Die Dokumentation für dieses Modul kann unter Modul:Sort/cell/Doku erstellt werden
local Sort = { suite = "Sort", sub = "cell", serial = "2021-04-11", item = 90144855 } --[=[ Sort/cell -- support table cells sorting modules ]=] local Failsafe = Sort local face = function ( assign, attribute, args, apply, allow ) -- Store preceding attribute -- Precondition: -- assign -- table, to extend -- attribute -- string, attribute name -- args -- table|nil, parameters to retrieve -- apply -- string|number|nil, for value -- allow -- boolean, permit and request numbers >(=)0 -- Postcondition: -- attributes extended local d, s, v if apply then d = apply elseif args then d = args[ attribute ] end s = type( d ) if s == "string" then d = mw.text.trim( d ) if d == "" then d = false end end if d then if allow then local min = 1 if attribute == "rowspan" then min = 0 end if s == "string" then s = string.format( "[%d-9]%%d*", min ) if d:match( string.format( "^%s$", s ) ) then v = d else local p s = string.format( "^(['\"]) *(%s) *%%1$", s ) p, s = d:match( s ) if s then v = s end end elseif s == "number" and d >= min then local k = math.floor( d ) if d == k then v = tostring( k ) end end if not v then assign.scream = attribute .. "=????" end elseif s == "string" then local p p, s = d:match( "^(['\"])([^\"]*)%1$" ) if s then d = mw.text.trim( s ) end if d ~= "" then if attribute == "dir" then d = d:lower() if d == "ltr" or d == "rtl" then v = d end else v = d end end end end if v then assign.props = assign.props or { } assign.props[ attribute ] = v end end -- face() local facing = function ( args, append ) -- Prepend preceding attributes -- Precondition: -- args -- table, parameters -- append -- string|html|nil, thing to be extended -- Postcondition: -- Returns string, if append is a string or nil -- otherwise html is extended local p = args.props local r = append if p then if type( append ) == "table" then for k, v in pairs( p ) do if k == "class" then append:addClass( v ) elseif k == "css" then append:css( v ) else append:attr( k, v ) end end -- for k, v else if p.css then local s = "" for k, v in pairs( p.css ) do if type( k ) == "string" and type( v ) == "string" then v = mw.text.trim( v ) k = mw.text.trim( k ) if v ~= "" and k ~= "" then s = string.format( "%s;%s:%s", s, k, v ) end end end -- for k, v if s ~= "" then face( args, "style", false, s:sub( 2 ) ) end p.css = nil end if type( append ) == "string" then r = "| " .. append else r = "|" end for k, v in pairs( p ) do if k ~= "lang" or v ~= Sort.facility() then r = string.format( " %s=\"%s\"%s", k, v, r ) end end -- for k, v r = r:sub( 2 ) end end return r end -- facing() local features = function ( args, assign ) -- Parse CSS string -- Precondition: -- args -- table, parameters -- .style -- string|nil, CSS to be parsed -- assign -- table, to be extended -- Postcondition: -- args.props.css added if args.style then local s = mw.text.trim( args.style ) local pair, css = s:match( "^(['\"])([^\"]*)%1$" ) if css then s = mw.text.trim( css ) end css = mw.text.split( s, ";" ) -- Problem: URL; not expected for i = 1, #css do pair = mw.text.split( css[ i ], ":" ) -- Problem: URL; not expected if #pair == 2 then s = mw.text.trim( pair[ 1 ] ) if s ~= "" then assign.props = assign.props or { } assign.props.css = assign.props.css or { } assign.props.css[ s ] = mw.text.trim( pair[ 2 ] ) end end end -- i = 1, #css end end -- features() Sort.faced = function ( args, assign ) -- Assign a sortable value -- Precondition: -- args -- table, to be extended -- assign -- string, to be memorized -- Postcondition: -- args is extended, if meaningful if type( assign ) == "string" then local s = mw.text.trim( assign ) if s ~= "" then s = mw.text.decode( s ) s = mw.ustring.gsub( s, mw.ustring.char( 160 ), " " ) s = mw.ustring.gsub( s, "%s+", " " ) s = s:gsub( "\"", "" ) :gsub( "<", "" ) :gsub( ">", "" ) s = mw.ustring.sub( s, 1, 99 ) face( args, "data-sort-value", false, s ) end end end -- Sort.faced() Sort.facility = function () -- Retrieve page or project language -- Postcondition: -- Returns string, downcased if type( Sort.slang ) ~= "string" then Sort.contLang = Sort.contLang or mw.language.getContentLanguage() Sort.slang = Sort.contLang:getCode():lower() end return Sort.slang end -- Sort.facility() Sort.fair = function ( args, access, assign ) -- Assign a non-empty string -- Precondition: -- args -- table, to be queried -- access -- string, to identify a component -- assign -- table, to be extended -- Postcondition: -- assign is extended, if meaningful if type( args[ access ] ) == "string" then local s = mw.text.trim( args[ access ] ) if s ~= "" then assign[ access ] = s end end end -- Sort.fair() Sort.fault = function ( alert, args ) -- Error occurred -- Parameter: -- alert -- string, with message -- args -- table, parameters -- .elem -- table, if mw.html -- .cat -- string|table|nil, for error category -- may contain one or more mw.title -- Postcondition: -- Returns string, or expands .elem local r, suffix local e = mw.html.create( "span" ) :addClass( "error" ) :wikitext( alert ) if args.cat then local s = type( args.cat ) local c if s == "string" then s = mw.text.trim( args.cat ) if s ~= "" then c = { } table.insert( c, s ) end elseif s == "table" then if type( args.cat.baseText ) == "string" then c = { } table.insert( c, args.cat.text ) else local v for i = 1, #args.cat do v = args.cat[ i ] s = type( v ) if s == "string" then s = mw.text.trim( v ) if s ~= "" then c = c or { } table.insert( c, s ) end elseif s == "table" and type( v.baseText ) == "string" then c = c or { } table.insert( c, v.text ) end end -- i = 1, #args.cat end end if c then suffix = "" for i = 1, #c do suffix = string.format( "%s[[Category:%s]]", suffix, c[ i ] ) end -- i = 1, #c end end if args.elem then if suffix then e:wikitext( suffix ) end args.elem:node( e ) else r = tostring( e ) if suffix then r = r .. suffix end end return r end -- Sort.fault() Sort.feature = function ( args, access, assign ) -- Retrieve or set CSS property -- Precondition: -- args -- table, parameters -- access -- string, property name -- assign -- string|nil, value to be set -- Postcondition: -- Returns string, or not, if not assigned local r if assign then args.props = args.props or { } args.props.css = args.props.css or { } args.props.css[ access ] = assign elseif args.props and args.props.css and args.props.css[ access ] then r = args.props.css[ access ] end return r end -- Sort.feature() Sort.finalize = function ( args, append ) -- Complete table cell -- Parameter: -- args -- table, parameters -- .props -- table, if present -- .cell -- true, if mandatory table syntax -- .elem -- table, if mw.html -- .scream -- string|nil, with error message -- append -- string|nil, with content -- Postcondition: -- Returns string, or expands .elem, or nil local r if args.props then if args.elem then facing( args, args.elem ) if append then args.elem:wikitext( append ) end elseif append and not args.cell then local e = mw.html.create( "span" ) :wikitext( append ) facing( args, e ) r = tostring( e ) else r = facing( args, append ) end elseif args.elem and append then args.elem:wikitext( append ) else r = append end if args.scream then if args.elem then Sort.fault( args.scream, args ) else r = r or "" r = r .. Sort.fault( args.scream, args ) end end return r end -- Sort.finalize() Sort.first = function ( args, always ) -- Initialize table cell start -- Parameter: -- args -- table, parameters -- .cell -- string|boolean|table, enforce sort -- .rowspan -- number|string, for cell attribute -- .colspan -- number|string, for cell attribute -- .class -- string, for cell attribute -- .style -- string|table, for cell attribute -- .id -- string, for cell attribute -- .lang -- string, for cell attribute -- .dir -- string, for cell attribute -- .frame -- object, if present -- always -- true, if mandatory table syntax -- Postcondition: -- Returns table with consolidated parameters local r = { } local s = type( args.style ) if s == "string" then features( args, r ) elseif s == "table" then r.props = { } r.props.css = args.style end s = type( args.cell ) if s == "string" then r.cell = ( args.cell == "1" ) elseif s == "table" and type( args.cell.node ) == "function" then r.elem = args.cell r.cell = true elseif s == "boolean" then r.cell = args.cell else r.cell = always end if r.cell then face( r, "rowspan", args, false, true ) face( r, "colspan", args, false, true ) end face( r, "class", args ) face( r, "id", args ) face( r, "lang", args ) face( r, "dir", args ) if type( args.frame ) == "table" then r.frame = args.frame end return r end -- Sort.first() Sort.following = function () -- Retrieve text order -- Postcondition: -- Returns true, if left-to-right if type( Sort.ltr ) ~= "boolean" then Sort.contLang = Sort.contLang or mw.language.getContentLanguage() Sort.ltr = not Sort.contLang:isRTL() end return Sort.ltr end -- Sort.following() Sort.formatDate = function ( align, at ) -- Format local date and time -- align -- string, with format -- at -- string|nil, with timestamp -- Postcondition: -- Returns string Sort.contLang = Sort.contLang or mw.language.getContentLanguage() return Sort.contLang:formatDate( align, at, true ) end -- Sort.following() Failsafe.failsafe = function ( atleast ) -- Retrieve versioning and check for compliance -- Precondition: -- atleast -- string, with required version or "wikidata" or "~" -- or false -- Postcondition: -- Returns string -- with queried version, also if problem -- false -- if appropriate -- 2019-10-15 local last = ( atleast == "~" ) local since = atleast local r if last or since == "wikidata" then local item = Failsafe.item since = false if type( item ) == "number" and item > 0 then local entity = mw.wikibase.getEntity( string.format( "Q%d", item ) ) if type( entity ) == "table" then local seek = Failsafe.serialProperty or "P348" local vsn = entity:formatPropertyValues( seek ) if type( vsn ) == "table" and type( vsn.value ) == "string" and vsn.value ~= "" then if last and vsn.value == Failsafe.serial then r = false else r = vsn.value end end end end end if type( r ) == "nil" then if not since or since <= Failsafe.serial then r = Failsafe.serial else r = false end end return r end -- Failsafe.failsafe() -- Export local p = { } p.failsafe = function ( frame ) -- Versioning interface local s = type( frame ) local since if s == "table" then since = frame.args[ 1 ] elseif s == "string" then since = frame end if since then since = mw.text.trim( since ) if since == "" then since = false end end return Failsafe.failsafe( since ) or "" end -- p.failsafe p.Sort = function () -- Module interface return Sort end return p