Modulo:Listutil
Aspekto
Dokumentado por ĉi tiu modulo povas esti kreata ĉe Modulo:Listutil/dokumentado
-- modul list - 2016-03-16
-- main functions:
-- list - accepts two required parameters and some optional parameters. it returns a list.
-- count - accepts two required parameters and returns the number of list items.
-- category - accepts four parameters and returns categories.
-- error handling:
-- factory
-- message
-- analyze
-- helping functions:
-- trim - removes spaces on the begin and the end of a string
-- delink - delinks a link, so it returns [[Ulo]] or [[Artikolo|Ulo]] like Ulo.
-- link - links a text, if it isn't a link already, else it returns the text without a change.
-- template - puts a template into the module or if you add the name of a template only, it parses the template
-- listitem - creats a list item depending of the given value of the parameter mode
-- spanitem - creats a span item
-- basic texts for error messages
local messagePrefix = "lua-module-Listutil-"
local l10nDef = {}
l10nDef[ "en" ] = {
noDelimiter = "Error in delimiter for the list - in the function",
emptyDelimiter = "Delimiter for the list is empty - in the function",
noText = "Error in the text for the list - in the function",
emptyText = "Text for the list is empty - in the function"
}
l10nDef[ "de" ] = {
noDelimiter = "Fehler beim Trennzeichen für die Liste - in der Funktion",
emptyDelimiter = "Trennzeichen für die Liste ist leer - in der Funktion",
noText = "Fehler im Text für die Liste - in der Funktion",
emptyText = "Text für die Liste ist leer - in der Funktion"
}
l10nDef[ "eo" ] = {
noDelimiter = "Eraro en la limsigno por la listo - en la funkcio",
emptyDelimiter = "Limsigno por la listo estas malplena - en la funkcio",
noText = "Eraro en la teksto por la listo - en la funkcio",
emptyText = "Teksto por la listo estas malplena - en la funkcio"
}
-- error handling
local function factory( say )
-- Retrieve localized message string in content language
-- Precondition:
-- say -- string; message ID
-- Postcondition:
-- Return some message string
-- Uses:
-- > messagePrefix
-- > l10nDef
-- mw.language.getContentLanguage()
-- mw.message.new()
local c = mw.language.getContentLanguage():getCode()
local m = mw.message.new( messagePrefix .. say )
local r = false
if m:isBlank() then
local l10n = l10nDef[ c ]
if not l10n then
l10n = l10nDef[ "en" ]
end
r = l10n[ say ]
else
m:inLanguage( c )
r = m:plain()
end
if not r then
r = "(((".. say .. ")))"
end
return r
end -- factory()
local function message (first, second, f)
-- first - the first required parameter in the main function is wrong
-- second - the second required parameter in the main function is wrong
-- f - in which function it occurs
local r = ""
if (first ~="") then
r = factory (first) .. ": " .. f .. "()"
end
if (second ~="") then
if (r ~="") then
r = r .. "<br />" .. factory (second) .. ": " .. f .. "()"
else r = factory (second) .. ": " .. f .. "()"
end
end
-- error (r, 0)
r = "<span class='error'>" .. r .. "</span>"
return r
end -- message ()
local function analyze (first, second, f)
-- first - the first required parameter has to be analyzed
-- second - the second required parameter has to be analyzed
-- f - in which function it occurs
-- r - message text
local r =""
if (first ==nil) or (first =="") or (second ==nil) or (second=="") then
local param1 =""
local param2 =""
local r =""
if (first == nil) then
param1= "noDelimiter"
end
if (first=="") then
param1= "emptyDelimiter"
end
if (second == nil) then
param2 ="noText"
end
if (second=="") then
param2 ="emptyText"
end
r=message (param1, param2, f)
return r
end
local lenfirst=mw.ustring.len(first)
local lensecond=mw.ustring.len(second)
-- if the first (delimiter) is longer than the second (text), then it returns a text, which
-- in the main function exchanges the values of the variables
if (lenfirst>lensecond) then
r="change"
return r
end
return r
end -- analyze ()
-- helping functions
-- trim returns text without spaces
-- if text is nil, then returns nil
-- if text is empty or consists of spaces only, then returns ''
local function trim (text)
return text and string.match (text, '^%s*(.-)%s*$')
end -- trim ()
-- delinks the text from v and returns [[Ulo]] or [[Artikolo|Ulo]] like Ulo.
-- this is needed, because a link in a link is not possible
-- s - is a helping variable
local function delink (v)
s = v:match( "%[%[[^|%]]*| *([^%]]+) *%]%]" )
if not s then
s = v:match( "%[%[%s*([^%]]+)%s*%]%]" )
end
if not s then
s = v
end
return mw.text.trim(s) -- removes spaces
end -- delink ()
-- links the text from v, if it isn't a link, else it returns the text whithout change
-- s - is a helping variable
local function link (v)
s = v:match( "%[%[[^|%]]*| *([^%]]+) *%]%]" )
if not s then
s = v:match( "%[%[%s*([^%]]+)%s*%]%]" )
end
if not s then
v=mw.text.trim(v) -- removes spaces
-- v=mw.ustring.gsub(v,"(%S+)","[[%1]]")
v=mw.ustring.gsub(v,"([^\n]+)","[[%1]]")
end
return mw.text.trim(v) -- removes spaces
end -- link ()
-- template puts a template into the module or parses it
-- v - is the name of the template or its parsed text (if the main function "list" receives it
-- with the template brackets {{}})
local function template (v)
local t = v:gsub( "<[^>]*>", "" )
--if (mw.ustring.sub(t,1,2) == "[[") then
if (t~=v) then
local r = mw.text.trim(v) -- removes spaces
return r
end
local frame = mw.getCurrentFrame()
local r = frame:expandTemplate{
title = t
}
return r
end -- template ()
-- listitem creates a list item
-- v is the text
-- x is a flag, that defines, if the item has to be linked
-- returns the list item
local function listitem (v, x)
local text =""
if (x =="jes") then
-- list item with a link
text = link(v)
elseif (x == "ŝablone") then
text = template(v)
else
-- list item without a link
text = mw.text.trim(v)
end
return text
end -- listitem ()
-- spanitem creates a span item
-- v - is the text
-- x - is a flag, , that defines, if the item has to be linked
-- returns the span item
local function spanitem (v, x, wrap)
local text=""
local w = ' class="nowrap"'
if (wrap == "jes") then
w = ""
end
if (x=="jes") then
-- span item with a link
text = '<span'.. w .. '>' .. link(v) .. '</span>'
elseif (x == "ŝablone") then
text = '<span'.. w .. '>' .. template(v) .. '</span>'
else
-- span item without a link
text = '<span' .. w .. '>' .. mw.text.trim(v) .. '</span>'
end
return text
end -- spanitem ()
-- Export
local p = {}
-- main functions
-- list - is the main function of the modul
-- it returns a list
-- it has two required parameters and some optional parameters
-- ligu - if it has the value jes, the text is linked
-- - it it has the value ŝablone, the text is tracted like a name of a template
-- modo - if its value is empty or ul, then it shows an unorded list
-- (like in the module Module:Listify) in the english Wikipedia
-- - if tis value is ol, then it shows an orded list
-- - if its value is span, then it shows an span formated text
-- (like the module Module:Liste éléments in the french Wikipedia)
-- limsigno - if modo has the value span, it is used to define the delimiter between the list items
-- tipo - if it has the value senmarko, then the mark of the list item is not showed
-- the following parameters work only, it modo has the value span
-- spacoj - defines the spaces between the delimiter and the text on both sides
-- (like "espaces" in the french module)
-- spacoj1 - defines the spaces before the delimiter
-- spacoj2 - defines the spaces after the delimiter
function p.list ( frame )
delimiter = frame.args[1]
text = frame.args[2]
-- it analyzes, if the required parameters are wrong or not
r=analyze (delimiter, text, "list")
if (r=="change") then delimiter, text = text, delimiter
elseif (r~="") then return r -- if r is some other than an empty string, it returns the message
-- and finishes the function
end
x = frame.args['ligu']
mode = frame.args['modo']
sep = frame.args['limsigno']
w = frame.args['linisalto']
kind = frame.args['tipo']
-- spaces for the mode = span
spaces = frame.args['spacoj']
spaces1 = frame.args['spacoj1']
spaces2 = frame.args['spacoj2']
return p._list(delimiter, text, x, mode, sep, w, kind, spaces, spaces1, spaces2)
end -- list ()
-- for use in this and other modules
function p._list (delimiter, text, x, mode, sep, w, kind, spaces, spaces1, spaces2)
-- tests, if certain parameters are empty
-- if x is not defined, then return an empty string
if (x == nil) then
x=""
end
-- if mode is not defined, then return an empty string
if (mode == nil) then
mode=""
end
-- if sep is not defined, then return a little point
-- this works in the following code parts only, if the mode has the value span
if (sep ==nil) then
sep = "·"
end
-- if kind is not defined, then return an empty string
if (kind ==nil) then
kind = ""
end
--strings = mw.text.split(text, delimiter, plain)
strings = mw.text.split(text, delimiter, true)
local output = {}
if (mode=="" or mode=="ul") then
local ul = mw.html.create("ul")
for k,v in pairs(strings) do
ul:node( mw.html.create("li"):wikitext( listitem(v,x) ):done() )
-- output[k] = listitem(v, x)
end
if kind == "senmarko" then
ul:css("list-style","none")
elseif kind == "senmarko2" then
ul:css("list-style","none")
ul:css("margin-left","0")
end
return tostring(ul:allDone())
elseif (mode=="ol") then
local ol = mw.html.create("ol")
for k,v in pairs(strings) do
ol:node( mw.html.create("li"):wikitext( listitem(v,x) ):done() )
-- output[k] = listitem(v, x)
end
if kind == "senmarko" then
ol:css("list-style","none")
elseif kind == "senmarko2" then
ol:css("list-style","none")
ol:css("margin-left","0")
end
return tostring(ol:allDone())
elseif (mode=="span") then
local i = 1
local res = ""
if (spaces == nil) then
nbsp1 = 1
nbsp2 = 1
end
spaces = tonumber(spaces)
if (spaces == nil) then
nbsp1 = 1
nbsp2 = 1
elseif (spaces ~= nil) then
nbsp1 = spaces
nbsp2 = spaces
elseif (spaces < 0) then
nbsp1 = 0
nbsp2 = 0
end
if (spaces1 ~= nil) then
spaces1 = tonumber(spaces1)
if (spaces1 ~= nil) then nbsp1 = spaces1
end
end
if (spaces2 ~= nil) then
spaces2 = tonumber(spaces2)
if (spaces2 ~=nil) then nbsp2 = spaces2
end
end
local space = mw.ustring.rep(" ", nbsp2)
if (w == "jes") then
space = " "
end
local sept = mw.ustring.rep(" ", nbsp1) .. sep .. space
while (strings[i]) do
if (i > 1) then -- séparateur avant, sauf le premier
res = res .. sept
end
res = res .. spanitem(strings[i], x, w)
i = i + 1
end
return res
elseif (mode=="pre") then
local pre = mw.html.create("pre")
local n = #strings -- number of items
for k,v in pairs(strings) do
local t = "" -- item text
if n > 1 and k < n then
t = v .. "\n" -- add an line wrap
else
t = v
end
-- pre:node( mw.html.create("span"):wikitext( listitem(t,x) ):done() )
pre:node( mw.html.create("span"):wikitext( t ):done() )
-- output[k] = listitem(v, x)
end
return tostring(pre:allDone())
elseif (mode=="kaj") or (mode=="aŭ") then
local i = 1
local s = #strings
local sept = ""
local sep = ""
local res = ""
local s1 = spaces1 or ""
local s2 = spaces2 or ""
while (strings[i]) do
if (i==s) and (i>1) then
sep = " " .. mode .. " "
res = res .. sep
elseif (i>1) then
sep = ", "
res = res .. sep
end
res = res .. s1 .. spanitem(strings[i], x, w) .. s2
i = i + 1
end
return res
elseif (mode=="faldebla") then -- nur uzebla, se estas mimimume 2 listeroj
local i = 1
local s = #strings
local div1 = '<div class="NavHead" style="text-align:left; background-color:#f9f9f9;">'
local div2 = '<div class="NavContent" style="text-align:left;">'
local div3 = '</div>'
local r = "" -- text to be returned
local l = "" -- list item
local br = "<br />"
for k,v in pairs(strings) do
-- unua listero
if (k == 1) then
l = div1 .. " " .. spanitem(v, x, w) .. div3
end
-- nur du listeroj kaj la dua
if s == 2 and k > 1 then
l = div2 .. " - " .. spanitem(v, x, w) .. div3
-- ĉe pli ol du la lasta
elseif k == s and k > 1 then
l = " - " .. spanitem(v, x, w) .. div3
-- ĉe pli ol du la dua
elseif k == 2 then
l = div2 .. " - " .. spanitem(v, x, w) .. br
-- ĉiuj ceteraj
elseif k > 1 then
l = " - " .. spanitem(v, x, w) .. br
end
r = r .. l
end
r = '<div class="NavFrame collapsed" style="border:none;">' .. r .. div3
return r
end
end -- _list ()
-- count - counts the number of list items
function p.count ( frame )
delimiter = frame.args[1]
text = frame.args[2]
-- it analyzes, if the required parameters are wrong or not
r=analyze (delimiter, text, "count")
if (r=="change") then delimiter, text = text, delimiter
elseif (r~="") then return r -- if r is some other than an empty string, it returns the message
-- and finishes the function
end
return p._count(delimiter, text)
end -- count ()
-- for use in this and other modules
function p._count (delimiter, text)
strings = mw.text.split(text, delimiter, plain)
local i = 0
for k,v in pairs(strings) do
i = i + 1
end
return i
end -- _count ()
-- category - is useful for automatic categorisation of list items
-- cat - is text, which has to be put before the text from the list item and after [[Kategorio:
-- key - is the sortkey for the category
function p.category ( frame )
delimiter = frame.args[1]
text = frame.args[2]
-- it analyzes, if the required parameters are wrong or not
r=analyze (delimiter, text, "category")
if (r=="change") then delimiter, text = text, delimiter
elseif (r~="") then return r -- if r is some other than an empty string, it returns the message
-- and finishes the function
end
cat = frame.args['kategorio'] -- it stands before the part from the list item
cat2 = frame.args['kategorio2'] -- it stands after the part from the list item
cat2space = frame.args['kategorio2spaco'] -- without a space
key = frame.args['ordigilo']
test = frame.args['testo'] or ""
return p._category(delimiter, text, cat, cat2, cat2space, key, test, frame)
end -- category ()
-- for use in this and other modules
function p._category (delimiter, text, cat, cat2, cat2space, key, test, frame)
-- if cat is not defined, then return an empty string
if (cat == nil) then
cat = ""
else cat = cat .. " "
end
-- if cat2 is not defined, then return an empty string
if (cat2 == nil) then
cat2 = ""
else
if (cat2space~="no") and (cat2space~="ne") then
cat2 = " " .. cat2
end
end
-- if key is not defined, then return an empty string
if (key == nil) then
key = ""
end
-- if test is defined, add a : to the wiki syntax of the category
if (test == "yes") or (test == "jes") then
test = ":"
end
strings = mw.text.split(text, delimiter, plain)
local output = {}
-- exceptions
local exceptions = 5
local ec = {} -- exception condition
local ev = {} -- exception value
for i=1, exceptions do
if frame.args['escepto' .. i] ~=nil and frame.args['escepto' .. i] ~= "" then
ec[i] = frame.args['escepto' .. i]
ev[i] = frame.args['escepto' .. i .. 'valoro']
end
end
for k,v in pairs(strings) do
local e_size = #ec
if e_size > 0 then
for i=1, exceptions do
if ec[i] == v then
if ev[i] ~= "##nenio" then
output[k] = '[[' .. test .. 'Kategorio:' .. ev[i]
else
output[k] = ""
end
else
output[k] = '[[' .. test .. 'Kategorio:' .. cat .. delink(v) .. cat2
end
end
else
output[k] = '[[' .. test .. 'Kategorio:' .. cat .. delink(v) .. cat2
end
-- if key has a value, then add it to the category, else don't add it
if output[k] ~= "" then
if key and key ~= "" then
output[k] = output[k] .. '|' .. key
end
output[k] = output[k] .. ']]'
end
end
return table.concat(output)
end -- _category ()
return p