Modulo:Listutil

El Vikipedio, la libera enciklopedio
Salti al navigilo Salti al serĉilo
Dokumentado Dokumentado


Ŝablona programado Diskutoj Lua Testoj Subpaĝoj
Modulo Esperanto English Deutsch

Modulo: Dokumentado


Se vi havas demandon pri ĉi tiu Lua-modulo, tiam vi povas demandi en la diskutejo pri Lua-moduloj. La Intervikiaj ligiloj estu metataj al Vikidatumoj. (Vidu Helpopaĝon pri tio.)
-- 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("&nbsp;", nbsp2) 
         if (w == "jes") then
         	space = " "
         end         
         local sept = mw.ustring.rep("&nbsp;", 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