-- modul list - 2015-05-28
-- main functions:
-- list - accepts two obligatory parameters and an optional parameter. it returns a list.
-- count - accepts two parameters and returns the number of list items.
-- category - accepts four parameters and returns categories.
-- 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.
-- listitem - creats a list item depending of the given value of the parameter mode
-- spanitem - creatas a span item  

local p = {}

-- 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 ''
function p.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

function p.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
function p.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 ()   

-- 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
function p.listitem (v, x)
        local text =""
        if (x =="jo") then
        -- list item with a link    
          text = '<li>' .. p.link(v) .. '</li>'       
        else    
        -- list item without a link    
          text = '<li>' .. mw.text.trim(v) .. '</li>' 
        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 
function p.spanitem (v, x, wrap)
         local text=""
         local w = ' class="nowrap"'
         if (wrap == "jo") then
         	w = ""
         end         
         if (x=="jo") then
         -- span item with a link     
            text = '<span'.. w .. '>' .. p.link(v) .. '</span>'           
         else     
         -- span item without a link     
            text = '<span'.. w .. '>' .. p.trim(v) .. '</span>'
         end
         return text
end -- spanitem ()  
 
-- main functions 
-- list - is the main function of the modul
-- it returns a list
-- it has two obligatory parameters and an optional parameter 'ligu'
-- ligu - if it has the value jes, the text is linked
-- modo - if its value is empty or ul, then it shows an unorded list
--      - if tis value is ol, then it shows an orded list
--      - if its value is span, then it shows an span formated text

function p.list ( frame )
    delimiter = frame.args[1]
    text = frame.args[2]
    x = frame.args['zwězuj']
    mode = frame.args['modus']
    sep = frame.args['źěleńske-znamuško']
    w = frame.args['łamanje cerow']    
    -- tests, if certain parameters are empty 
    -- if x is empty, then return an empty string
    if (x == nil) then
      x=""
    end        
    -- if mode is empty, then return an empty string
    if (mode == nil) then
      mode=""
    end       
    -- if sep is empty, 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    
    strings = mw.text.split(text, delimiter, plain)
    local output = {}
 
    if (mode=="" or mode=="ul" or mode=="ol") then 
       for k,v in pairs(strings) do
          output[k] = p.listitem(v, x)
       end
       if (mode=="ol") then
       -- the complete list     
            return '<ol>' .. table.concat(output) .. '</ol>' 
       else return '<ul>' .. table.concat(output) .. '</ul>'             
       end    
    elseif (mode=="span") then
         local i = 1
         local res = "" 
         local nbsp = 1 -- number of spaces
         local space = mw.ustring.rep("&nbsp;", nbsp) 
         if (w == "jo") then
         	space = " "
         end         
         local sept = mw.ustring.rep("&nbsp;", nbsp) .. sep .. space
         while (strings[i]) do
           if (i > 1) then -- séparateur avant, sauf le premier
            res = res .. sept
           end
           res = res .. p.spanitem(strings[i], x, w)            
           i = i + 1
         end
         return res
    end   
end  -- list ()

-- count - counts the number of list items

function p.count ( frame )
    delimiter = frame.args[1]
    text = frame.args[2]
    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]
    cat = frame.args['kategorija'] -- it stands before the part from the list item
    cat2 = frame.args['kategorija2'] -- it stands after the part from the list item  
    key = frame.args['sortěrowanje']
    -- if it is empty, then return an empty string
    if (cat == nil) then 
        cat = ""
    else cat = cat .. " "    
    end
    -- if it is empty, then return an empty string    
    if (cat2 == nil) then 
        cat2 = ""
    else cat2 = " " .. cat2     
    end    
    -- if it is empty, then return an empty string    
    if (key == nil) then 
        key = ""
    end
    strings = mw.text.split(text, delimiter, plain)
    local output = {}
    for k,v in pairs(strings) do
      output[k] = '[[Kategorija:' .. cat .. p.delink(v) .. cat2
      -- if key has a value, then add it to the category, else don't add it      
      if key and key ~= "" then
      output[k] = output[k] .. '|' .. key
      end
      output[k] = output[k] .. ']]'
    end       
 
    return table.concat(output) 
end  -- category ()
 
return p