Ad placeholder

Module:ParseList: Difference between revisions

Jump to navigation Jump to search
Added no margin version of htmlListNoBullets
(Created page with "local getArgs = require('Module:Arguments').getArgs local p = {} -- Config options, these may be overwritten in the main function local delimiter = "," local makeLinks = false local pluralize = false local joinWord = "and" local function splitString(str) local values = {} for value in str:gmatch("[^" .. delimiter .. "]+") do table.insert(values, value:gsub("%s+", "")) end return values end local specialPlurals = { Thief = "Thieves", thief = "...")
 
(Added no margin version of htmlListNoBullets)
 
(36 intermediate revisions by 3 users not shown)
Line 2: Line 2:
local p = {}
local p = {}


-- Config options, these may be overwritten in the main function
-- Config options, set in main function
local delimiter = ","
local listDelimiters
local makeLinks = false
local makeElementsLinks
local pluralize = false
local makeElementsPlural
local joinWord = "and"
local makeElementsSingular
local makeElementsLowercase
local useTemplateOnElements
local useTwoArgTemplateOnElements
local textDelim
local textLastDelim


local function splitString(str)
local function splitListString(listString)
    local values = {}
local strings = {}
    for value in str:gmatch("[^" .. delimiter .. "]+") do
for str in listString:gmatch("[^" .. listDelimiters .. "]+") do
        table.insert(values, value:gsub("%s+", ""))
table.insert(strings, str:match("^%s*(.-)%s*$"))
    end
end
    return values
return strings
end
end


-- This is a TWO-WAY conversion table of singular words and their corresponding
-- plural form, for those that wouldn't be handled correctly by the automatic
-- rules implemented further down below.  Note that we don't need to cover most
-- regular English words, as they're unlikely to ever be used with this module.
-- The kind of stuff you want to add here is gameplay elements like classes,
-- weapons, races, and so on.
local specialPlurals = {
local specialPlurals = {
Thief = "Thieves",
-- Weapons
thief = "thieves",
Glaive = "Glaives",
Quarterstaff = "Quarterstaves",
glaive = "glaives",
quarterstaff = "quarterstaves",
Staff = "Staves",
staff = "staves",
-- Races
Gith = "Gith",
gith = "gith",
Githyanki = "Githyanki",
githyanki = "githyanki",
Duergar = "Duergar",
duergar = "duergar",
Drow = "Drow",
drow = "drow",
Dragonborn = "Dragonborn",
dragonborn = "dragonborn",
-- Creature types
Fey = "Fey",
fey = "fey",
Undead = "Undead",
undead = "undead",
}
}


local function processValue(str)
-- Checks if str is equal to or ends in one of the keys in specialPlurals.
if pluralize then
-- Returns the pluralized version if so, otherwise nil.
local plural = specialPlurals[str] or str .. "s"
local function findSpecialPlural(str)
if makeLinks then
for singular, plural in pairs(specialPlurals) do
return "[[" .. str .. "|" .. plural .. "]]"
if str == singular then
else
return plural
return plural
end
end
else
local len = #singular
if makeLinks then
local suffix = str:sub(-len, -1)
return "[[" .. str .. "]]"
if (suffix == singular) then
else
return str:sub(1, -len - 1) .. plural
return str
end
end
end
end
end
end


local function processList(listString)
-- Checks if str is equal to or ends in one of the values in specialPlurals.
local values = splitString(listString)
-- Returns the singular version if so, otherwise nil.
    local count = #values
local function findSpecialSingular(str)
    if count == 0 then
for singular, plural in pairs(specialPlurals) do
    return ""
if str == plural then
    elseif count == 1 then
return singular
    return processValue(values[1])
    elseif count == 2 then
    local v1 = processValue(values[1])
    local v2 = processValue(values[2])
return v1 .. " " .. joinWord .. " " .. v2
    end
    local result = ""
for i, value in ipairs(values) do
local v = processValue(value, linked)
if i < count then
result = result .. v .. ", "
else
result = result .. joinWord .. " " .. v
end
end
    end
local len = #plural
    return result
local suffix = str:sub(-len, -1)
if suffix == plural then
return str:sub(1, -len - 1) .. singular
end
end
end
 
-- Checks for a special pluralization first, then implements these rules:
-- ...f -> ...ves
-- ...y -> ...ies
-- ...s -> ...ses
-- ...ch -> ...ches
-- ...sh -> ...shes
-- ... -> ...s
local function makePlural(str)
local sp = findSpecialPlural(str)
if sp then
return sp
end
local last1 = str:sub(-1)
if last1 == "f" then
return str:sub(1, -2) .. "ves"
elseif last1 == "y" then
return str:sub(1, -2) .. "ies"
elseif last1 == "s" then
return str .. "es"
end
local last2 = str:sub(-2)
if last2 == "ch" or last2 == "sh" then
return str .. "es"
end
return str .. "s"
end
 
-- Checks for a special singularization first, then implements these rules:
-- ...ves -> ...f
-- ...ies -> ...y
-- ...ses -> ...s
-- ...ches -> ...ch
-- ...shes -> ...sh
-- ...s -> ...
-- ... -> ...
local function makeSingular(str)
local special = findSpecialSingular(str)
if special then
return special
end
local last3 = str:sub(-3)
if last3 == "ves" then
return str:sub(1, -4) .. "f"
elseif last3 == "ies" then
return str:sub(1, -4) .. "y"
elseif last3 == "ses" then
return str:sub(1, -3)
end
local last4 = str:sub(-4)
if last4 == "ches" or last4 == "shes" then
return str:sub(1, -3)
end
if str:sub(-1) == "s" then
return str:sub(1, -2)
end
return str
end
 
-- Applies the various per-element transforms.  Frame is needed for template
-- expansion; it may be nil if template transforms won't be applied.
local function processElement(str, frame)
local original = str
if makeElementsPlural then
str = makePlural(str)
elseif makeElementsSingular then
str = makeSingular(str)
end
if makeElementsLowercase then
str = str:lower()
end
if makeElementsLinks then
return "[[" .. original .. "|" .. str .. "]]"
elseif useTemplateOnElements then
return frame:expandTemplate{
title = useTemplateOnElements,
args = { str }
}
elseif useTwoArgTemplateOnElements then
return frame:expandTemplate{
title = useTwoArgTemplateOnElements,
args = { original, str }
}
end
return str
end
end


function p.toSentence(frame)
-- These functions implement different output styles.  The elements will have
-- already gone through processElement() at this point, so they only need to be
-- glued together to produce the desired style of listing format.
local converters = {
text = function (elements)
local result = ""
local count = #elements
for i, str in ipairs(elements) do
if i == 1 then
result = str
elseif i < count then
result = result .. textDelim .. str
else
result = result .. textLastDelim .. str
end
end
return result
end,
simpleList = function (elements)
local result = ""
local first = true
for i, str in ipairs(elements) do
if first then
result = str
first = false
else
result = result .. ", " .. str
end
end
return result
end,
htmlList = function (elements)
local result = "<ul>\n"
for i, str in ipairs(elements) do
result = result .. "<li>" .. str .. "</li>\n"
end
return result .. "</ul>"
end,
htmlListNoBullets = function (elements)
local result = "<ul style='list-style: none;'>\n"
for i, str in ipairs(elements) do
result = result .. "<li>" .. str .. "</li>\n"
end
return result .. "</ul>"
end,
htmlListNoBulletsOrMargin = function (elements)
local result = "<ul style='list-style: none; margin: 0'>\n"
for i, str in ipairs(elements) do
result = result .. "<li>" .. str .. "</li>\n"
end
return result .. "</ul>"
end,
tableList = function (elements)
local result = "<div class=\"bg3wiki-tablelist\">"
for i, str in ipairs(elements) do
result = result .. str .. "\n"
end
return result .. "</div>"
end,
none = function (elements)
local result = ""
for i, str in ipairs(elements) do
result = result .. str
end
return result
end,
}
 
function p.main(frame)
local args = getArgs(frame, { frameOnly = true })
local args = getArgs(frame, { frameOnly = true })
delimiter = args['delimiter'] or delimiter
return p._main(args, frame)
makeLinks = args['makeLinks'] or makeLinks
end
pluralize = args['pluralize'] or pluralize
 
joinWord = args['joinWord'] or joinWord
-- Frame is needed for template expansion; may be nil if the useTemplate and
return processList(frame.args[1])
-- useTemplate2 args are nil.
function p._main(args, frame)
listDelimiters = args['delimiter'] or ","
makeElementsLinks = args['makeLinks']
makeElementsPlural = args['makePlural']
makeElementsSingular = args['makeSingular']
makeElementsLowercase = args['makeLowercase']
useTemplateOnElements = args['useTemplate']
useTwoArgTemplateOnElements = args['useTemplate2']
textDelim = args['textDelim']
if textDelim then
textLastDelim = args['textLastDelim'] or textDelim
else
textDelim = ', '
textLastDelim = args['textLastDelim'] or ', and '
end
local style = args['style'] or args['type'] or 'text'
local converter = converters[style]
local elements = {}
local listString = args[1]
local strings = splitListString(listString)
for i, str in ipairs(strings) do
table.insert(elements, processElement(str, frame))
end
return converter(elements)
end
end


return p
return p

Navigation menu