10,916
editsMore actions
Improve output of htmlList style.
(Add dragonborn) |
(Improve output of htmlList style.) |
||
(16 intermediate revisions by 3 users not shown) | |||
Line 7: | Line 7: | ||
local makeElementsPlural | local makeElementsPlural | ||
local makeElementsSingular | local makeElementsSingular | ||
local | local makeElementsLowercase | ||
local useTemplateOnElements | |||
local useTwoArgTemplateOnElements | |||
local textDelim | |||
local textLastDelim | |||
local function splitListString(listString) | local function splitListString(listString) | ||
local strings = {} | |||
for str in listString:gmatch("[^" .. listDelimiters .. "]+") do | |||
table.insert(strings, str:match("^%s*(.-)%s*$")) | |||
end | |||
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 = { | ||
-- Weapons | -- Weapons | ||
Glaive = "Glaives", | |||
glaive = "glaives", | |||
Staff = "Staves", | |||
staff = "staves", | |||
-- Races | -- Races | ||
Gith = "Gith", | Gith = "Gith", | ||
gith = "gith", | gith = "gith", | ||
Line 52: | Line 51: | ||
} | } | ||
-- Checks if str is equal to or ends in one of the keys in specialPlurals. | |||
-- Returns the pluralized version if so, otherwise nil. | |||
local function findSpecialPlural(str) | |||
for singular, plural in pairs(specialPlurals) do | |||
if str == singular then | |||
return plural | |||
end | |||
local len = #singular | |||
local suffix = str:sub(-len, -1) | |||
if (suffix == singular) then | |||
return str:sub(1, -len - 1) .. plural | |||
end | |||
end | |||
end | |||
-- Checks if str is equal to or ends in one of the values in specialPlurals. | |||
-- Returns the singular version if so, otherwise nil. | |||
local function findSpecialSingular(str) | |||
for singular, plural in pairs(specialPlurals) do | |||
if str == plural then | |||
return singular | |||
end | |||
local len = #plural | |||
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 function makePlural(str) | ||
local sp = | local sp = findSpecialPlural(str) | ||
if sp then | if sp then | ||
return sp | return sp | ||
end | end | ||
if str:sub(- | 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" | 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 | end | ||
return str .. "s" | return str .. "s" | ||
end | 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 function makeSingular(str) | ||
local special | local special = findSpecialSingular(str) | ||
if special then | if special then | ||
return special | return special | ||
end | end | ||
if str:sub(- | 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" | 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 | end | ||
return str | return str | ||
end | end | ||
local function processElement(str) | -- Applies the various per-element transforms. Frame is needed for template | ||
local | -- expansion; it may be nil if template transforms won't be applied. | ||
local function processElement(str, frame) | |||
local original = str | |||
if makeElementsPlural then | if makeElementsPlural then | ||
str = makePlural(str) | |||
elseif makeElementsSingular then | elseif makeElementsSingular then | ||
str = makeSingular(str) | |||
end | |||
if makeElementsLowercase then | |||
str = str:lower() | |||
end | end | ||
if makeElementsLinks then | if makeElementsLinks then | ||
return "[[" .. | return "[[" .. original .. "|" .. str .. "]]" | ||
elseif useTemplateOnElements then | |||
return | return frame:expandTemplate{ | ||
title = useTemplateOnElements, | |||
args = { str } | |||
} | |||
elseif useTwoArgTemplateOnElements then | |||
return frame:expandTemplate{ | |||
title = useTwoArgTemplateOnElements, | |||
args = { original, str } | |||
} | |||
end | end | ||
return str | |||
end | end | ||
-- 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 = { | local converters = { | ||
text = function (elements) | |||
local result = "" | |||
local count = #elements | |||
for i, str in ipairs(elements) do | for i, str in ipairs(elements) do | ||
if i < count then | if i == 1 then | ||
result = result .. | result = str | ||
elseif i < count then | |||
result = result .. textDelim .. str | |||
else | else | ||
result = result .. | result = result .. textLastDelim .. str | ||
end | end | ||
end | |||
return result | |||
end, | end, | ||
htmlList = function (elements) | htmlList = function (elements) | ||
local result = "" | local result = "<ul>\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, | |||
htmlListNoBullets = function (elements) | |||
local result = "<ul style='list-style: none; margin: 0;'>\n" | |||
for i, str in ipairs(elements) do | for i, str in ipairs(elements) do | ||
result = result .. " | result = result .. "<li>" .. str .. "</li>\n" | ||
end | end | ||
return result | return result .. "</ul>" | ||
end, | end, | ||
simpleList = function (elements) | simpleList = function (elements) | ||
Line 138: | Line 223: | ||
function p.main(frame) | function p.main(frame) | ||
local args = getArgs(frame, { frameOnly = true }) | local args = getArgs(frame, { frameOnly = true }) | ||
return p._main(args) | return p._main(args, frame) | ||
end | end | ||
function p._main(args) | -- Frame is needed for template expansion; may be nil if the useTemplate and | ||
-- useTemplate2 args are nil. | |||
function p._main(args, frame) | |||
listDelimiters = args['delimiter'] or "," | listDelimiters = args['delimiter'] or "," | ||
makeElementsLinks = args['makeLinks'] | makeElementsLinks = args['makeLinks'] | ||
makeElementsPlural = args['makePlural'] | makeElementsPlural = args['makePlural'] | ||
makeElementsSingular = args['makeSingular'] | 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 | local style = args['style'] or args['type'] or 'text' | ||
local converter = converters[ | local converter = converters[style] | ||
local elements = {} | local elements = {} | ||
local listString = args[1] | local listString = args[1] | ||
local strings = splitListString(listString) | local strings = splitListString(listString) | ||
for i, str in ipairs(strings) do | for i, str in ipairs(strings) do | ||
table.insert(elements, processElement(str)) | table.insert(elements, processElement(str, frame)) | ||
end | end | ||
return converter(elements) | return converter(elements) |