Modul:Sort
Erscheinungsbild
Dokumentation für das Modul Sort[Ansicht] [Bearbeiten] [Versionsgeschichte] [ ]
Dieses Modul wurde am 27. Juli 2018 von Modul:Sort der deutschen Wikipedia importiert. Statt Änderungen hier auf Wikivoyage vorzunehmen, sollte eine neuer Import vorgezogen werden, falls im originalen Wiki neue Funktionen hinzugekommen sind. Stimme dich dazu bitte mit der Community in der Vorlagenwerkstatt ab. |
Das Modul sollte aktualisiert werden! |
Dieses Modul ist getestet und für den projektweiten Gebrauch geeignet. Es kann in Vorlagen benutzt und auf Hilfeseiten erläutert werden. Entwicklungen an dem Modul sollten auf Sort/Test und die Anwendung auf der Spielwiese getestet werden, da wiederholte Trial-and-Error-Edits die Resourcen stark belasten können. |
Hinweise
- Die obige Dokumentation wurde aus der Seite Modul:Sort/Doku eingefügt. (bearbeiten | Versionsgeschichte) Die Kategorien für dieses Modul sollten in der Dokumentation eingetragen werden. Die Interwiki-Links sollten auf Wikidata eingepflegt werden.
- Liste der Unterseiten
local Sort = { suite = "Sort",
serial = "2019-10-29",
item = 24205172 }
--[=[
Sort
]=]
local Failsafe = Sort
local GlobalMod = Sort
local foreignModule = function ( access, advanced, append, alt, alert )
-- Fetch global module
-- Precondition:
-- access -- string, with name of base module
-- advanced -- true, for require(); else mw.loadData()
-- append -- string, with subpage part, if any; or false
-- alt -- number, of wikidata item of root; or false
-- alert -- true, for throwing error on data problem
-- Postcondition:
-- Returns whatever, probably table
-- 2019-10-29
local storage = access
local finer = function ()
if append then
storage = string.format( "%s/%s",
storage,
append )
end
end
local fun, lucky, r, suited
if advanced then
fun = require
else
fun = mw.loadData
end
GlobalMod.globalModules = GlobalMod.globalModules or { }
suited = GlobalMod.globalModules[ access ]
if not suited then
finer()
lucky, r = pcall( fun, "Module:" .. storage )
end
if not lucky then
if not suited and
type( alt ) == "number" and
alt > 0 then
suited = string.format( "Q%d", alt )
suited = mw.wikibase.getSitelink( suited )
GlobalMod.globalModules[ access ] = suited or true
end
if type( suited ) == "string" then
storage = suited
finer()
lucky, r = pcall( fun, storage )
end
if not lucky and alert then
error( "Missing or invalid page: " .. storage, 0 )
end
end
return r
end -- foreignModule()
Sort.lex = function ( adjust, apply, adapt )
-- Build ASCII sortkey for text value
-- Precondition:
-- adjust -- string to be aligned
-- apply -- string or table, with base
-- "latin"
-- adapt -- string or table, with variation, or false
-- "DIN5007m2" -- DIN 5007 mode "2"
local r = adjust
if adapt or not r:match( "^[ -~]*$" ) then
local collate, post, pre
if apply then
collate = apply
else
collate = "uni"
end
if type( collate ) == "string" then
collate = foreignModule( Sort.suite,
false,
collate,
Sort.item )
end
if adapt and type( collate ) == "table" then
local variants = type( adapt )
local n
if variants == "string" then
variants = mw.text.split( adapt, "%s+" )
elseif variants == "table" then
variants = adapt
else
variants = { }
end
n = #variants
if n == 1 and variants[ 1 ] == "" then
n = 0
end
if n > 0 then
local tmp = { }
local var
for k, v in pairs( collate ) do
tmp[ k ] = v
end -- for k, v
collate = tmp
for i = 1, n do
tmp = foreignModule( Sort.suite,
false,
variants[ i ],
Sort.item )
if type( tmp ) == "table" then
var = tmp.single
if type( var ) ~= "table" then
-- legacy
var = tmp
end
if type( var ) == "table" then
for k, v in pairs( var ) do
collate[ k ] = v
end -- for k, v
end
var = tmp.pre
if type( var ) == "table" then
if type( pre ) ~= "table" then
pre = { }
end
for k, v in pairs( var ) do
pre[ k ] = v
end -- for k, v
end
var = tmp.post
if type( var ) == "table" then
if type( post ) ~= "table" then
post = { }
end
for k, v in pairs( var ) do
post[ k ] = v
end -- for k, v
end
elseif type( tmp ) == "string" then
collate = tmp
break -- for i
else
collate = "Invalid table " .. variants[ i ]
break -- for i
end
end -- for i
end
end
if type( collate ) == "table" then
local k, n, s, start
if type( pre ) == "table" then
for k, v in pairs( pre ) do
r = mw.ustring.gsub( r, k, v )
end -- for k, v
end
n = mw.ustring.len( r )
for i = n, 1, -1 do
k = mw.ustring.codepoint( r, i, i )
if k < 127 then -- ASCII
s = ( k < 32 ) -- htab newline whitespace
if s then
s = " "
end
elseif ( k >= 0x0300 and k <= 0x0362 ) or
( k >= 0x1AB0 and k <= 0x1AFF ) or
( k >= 0x1DC0 and k <= 0x1DFF ) or
( k >= 0xFE20 and k <= 0xFE2F ) then
-- COMBINING ...
s = ""
else
s = collate[ k ]
end
if s then
if i > 1 then
s = mw.ustring.sub( r, 1, i - 1 ) .. s
end
r = s .. mw.ustring.sub( r, i + 1 )
end
end -- for i--
if type( post ) == "table" then
for k, v in pairs( post ) do
r = mw.ustring.gsub( r, k, v )
end -- for k, v
end
else
r = "**ERROR** Sort.lex ** Submodule unavailable " .. collate
end
end
r = r:gsub( " +", " " )
return r
end -- Sort.lex()
Sort.num = function ( adjust, ad, at, align, absolute )
-- Build sortkey for heading numerical value
-- Precondition:
-- adjust -- string to be aligned; leading digits / minus
-- ad -- decimal separator; "." or ","; defaults to "."
-- at -- thousands group separator; defaults to none
-- "," "." "'"
-- align -- number of leading zeros / maximum length
-- defaults to 15
-- absolute -- negative figures by digits; default: by value
-- Postcondition:
-- Returns string with sortkey
local max = 15
local mid = 46 -- "."
local min1 = -1 -- none
local min2 = -2 -- none
local low = false
local last = false
local lead = true
local source = tostring( adjust )
local sub = "."
local suffix = false
local n = mw.ustring.len( source )
local r = ""
local c
if ad then
mid = mw.ustring.codepoint( ad, 1, 1 )
end
if at then
min1, min2 = mw.ustring.codepoint( at, 1, 2 )
end
if align then
max = align
end
for i = 1, n do
c = mw.ustring.codepoint( source, i, i )
if c > 32 then -- not whitespace
if c >= 48 and c <= 57 then -- digits
r = string.format( "%s%c", r, c )
max = max - 1
elseif c == min1 or c == min2 then -- group separator
elseif c == mid then -- decimal separator
for j = i + 1, n do
c = mw.ustring.codepoint( source, j, j )
if c >= 48 and c <= 57 then -- digits
sub = string.format( "%s%c", sub, c )
elseif c == min1 or c == min2 then -- grouping
else
i = j
break -- for j
end
i = n
end -- for j
last = true
elseif lead then
if c == 45 or c == 8722 then -- minus
low = true
elseif c ~= 43 then -- plus
last = true
end
else
last = true
end
lead = false
elseif not lead then -- whitespace not leading
last = true
end
if last then
if i < n then
suffix = mw.ustring.sub( source, i )
if c == 69 or c == 101 then -- E e
local s = suffix:match( "^[Ee](-?%d+)" )
if s then
j = tonumber( s )
sub = sub:sub( 2 )
suffix = suffix:sub( #s + 2 )
if j > 0 then
if j > #sub then
sub = sub .. string.rep( "0", j - #sub )
end
r = r .. sub:sub( 1, j )
sub = sub:sub( j + 1 )
max = max - j
elseif j < 0 then
j = - j
if j > #r then
r = string.rep( "0", j - #r ) .. r
end
sub = r:sub( - j ) .. sub
r = r:sub( 1, #r - j )
max = max + j
end
sub = "." .. sub
end
end
end
break -- for i
end
end -- for i
if low then
if not absolute then -- complementary value
local s = "."
local cmpl = function ( str, k )
return 57 - str:byte( k )
end
for i = 2, #sub do
s = string.format( "%s%d", s, cmpl( sub, i ) )
end -- for i
for i = #r, 1, -1 do
s = string.format( "%d%s", cmpl( r, i ), s )
end -- for i--
r = s
if max > 0 then
r = string.rep( "9", max ) .. r
end
sub = false
max = 0
end
end
if sub then
r = r .. sub
end
if max > 0 then
r = string.rep( "0", max ) .. r
end
if low then
r = "-" .. r
end
if suffix then
r = string.format( "%s %s", r, suffix )
end
return r
end -- Sort.num()
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.Tlatin = function ( frame )
-- Template::latin
-- {{{1}}}
-- #invoke
-- v -- variant, omitted or "DIN5007m2"
local lucky, r = pcall( Sort.lex,
frame.args[ 1 ] or
frame:getParent().args[ 1 ] or
"",
"latin",
frame.args.v )
return r;
end -- p.Tlatin
p.Tn = function ( frame )
-- Template::numerical
-- {{{1}}}
-- #invoke
-- d -- decimal separator; defaults to "."
-- t -- thousands group separator; defaults to none
-- z -- number of leading zeros / maximum length; defaults to 15
-- m -- negative figures by digits; default: by value
local lucky, r = pcall( Sort.num,
frame.args[ 1 ] or
frame:getParent().args[ 1 ] or
"",
frame.args.d,
frame.args.t,
tonumber( frame.args.z ),
frame.args.m == "1" )
return r;
end -- p.Tn
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 ()
return Sort
end -- p.Sort
return p