Documentation for this module may be created at Module:ComicsInfobox/doc
-- <nowiki>
-- Start Module skeleton. Everything builds off this.
local Infobox = {}
----------------------------
-- Libraries of functions --
----------------------------
-- stands for High Frequency
local HF = require("Module:ComicsHF")
-- Parses invocation parameters, trims whitespace, and removes blanks
local getArgs = require('Dev:Arguments').getArgs
-- Functions for making Wikitext lists
local L = require("Dev:List")
-- Since this should only be evaluated once per pageview, it's now global
_G.vars = { Pagename = mw.title.getCurrentTitle().text }
---------------------
-- Local functions --
---------------------
local function invokeInt(funcName)
-- This wrapper allows invocation from articles and templates
-- of internal Lua functions.
return function (frame)
local args = getArgs(frame, { trim = true, removeBlanks = true })
return Infobox[funcName](args, vars)
end
end
----------------------
-- Public functions --
----------------------
function Infobox.CategoriesFromKeywords( fieldValue, valid, exceptions, vars )
local output = ""
-- Field isn't blank
if fieldValue ~= nil then
-- Grab a valid pair and use it
for validKey, validValue in pairs(valid) do
-- If you find the validKey in the field, look more closely
if string.find( string.lower(fieldValue), validKey ) ~= nil then
-- Check if there are exceptions for the validKey
if type(exceptions[validKey]) ~= "table" then
-- There are no exceptions
-- Just categorize using this validKey
-- and move to the next validKey
for valueKey, valueCategoryName in ipairs( validValue ) do
output = output .. HF.CategoryLink(
valueCategoryName,
vars.Pagename,
""
)
end
end
end
end
end
return output
end
-- Calls _sanitizeInput from a Template
function Infobox.sanitize(frame)
local args = getArgs(frame, { trim = true, removeBlanks = true })
return Infobox._sanitizeInput(args[1])
end
-- Cleans up sloppy inputs into something more useful
-- This reduces the need to run a bot and get users to change habits
function Infobox._sanitizeInput( input )
-- set "output" from "input", and manipulate "output"
local output = input
-- No more line breaks
output = string.gsub( output, '([,;])<br>%s*.', '%1 ' )
-- Where there's just a line break and no delimiter, there should be a delimiter.
output = string.gsub( output, '<br>%s*.', '; ' )
-- Put references where they belong (before a delimiter)
output = string.gsub( output, '([,;])(["]?){{([rR])|([^}]*)}} ', '%2{{%3|%4}}%1 ' )
return output
end
function Infobox._cloakCommas( input )
local output = input
-- temporarily change those interior commas to obscure symbol '§'
output = string.gsub( output,
'%(([^,)]*),([^,)]*)%)',
'(%1§%2)'
)
-- Do the same thing for Templates
output = string.gsub( output,
'{{([%w%s]*)|([^}]*),([^}]*)}}',
'{{%1|%2§%3}}' )
-- Do the same for Links and Categories
-- itemstring = string.gsub( itemstring,
-- '%[%[([^,)]*),([^,)]*)|[([^,)]*),([^,)]*)%]%]',
-- '[[%1§%2|%3§%4]]'
-- )
return output
end
-- Calls _hlist from a Template
Infobox.hlist = invokeInt('_hlist')
-- Internal function for creating horizontal lists
function Infobox._hlist( args )
-- ** Determine values for the function ** --
-- Delimiter is the separator between items. Defaults to {{{1|;}}}
local delimiter = args['delimiter'] or args[1] or ';'
-- The actual plaintext string to be changed into a list.
-- If there's no {{{2}}}, then it's the only unnamed argument.
local itemstring = args['value'] or args[2] or args[1] or nil
if not args[2] then delimiter = args['delimiter'] or args[1] or ';' end
itemstring = Infobox._sanitizeInput( itemstring )
-- Optional length based trimming.
local trim = args['trim'] or args[3] or false
if delimiter == ',' and
( string.match( itemstring, '%(([^,)]*),([^,)]*)%)') or
string.match( itemstring, '{{([%w%s]*)|([^}]*),([^}]*)}}')
)
-- If items are separated by commas and
-- there are commas inside parenthesis
-- Like "Stark Tower (New York City, New York), "
then
itemstring = Infobox._cloakCommas( itemstring )
end
if mw.ustring.match(itemstring, ';' ) and
not mw.ustring.match(itemstring, '(.*);(.*);' ) and
delimiter == ','
-- if there's just ONE semicolon and delimiter is ','
-- then no matter what, whatever is before the semicolon is in "front"
then
local primary = mw.ustring.match(itemstring, '(.*);' )
local secondary = mw.ustring.match(itemstring, ';(.*)' )
-- Separate the individual items by delimiter
-- and put them in a table (or array)
local items1 = HF.explode( delimiter, primary )
local items2 = HF.explode( delimiter, secondary )
-- Take the items in the back tables
-- and reproduce them as horizontal, bulleted lists
local list1 = L.makeList( 'horizontal', items1 )
local list2 = L.makeList( 'horizontal', items2 )
-- Create the content wrapper for the back
local morebox = mw.html.create('div')
:addClass('expansion-tag')
:addClass('mw-collapsible')
:addClass('mw-collapsed')
:attr('data-expandtext', morelabel)
:attr('data-collapsetext', lesslabel)
:wikitext(list2):allDone()
-- Output everything
-- If we changed the symbols before, we'll change them back now
return mw.ustring.gsub( list1 .. tostring(morebox), '§', ',' )
elseif type(trim) == 'number' and
mw.ustring.len( itemstring ) > trim
-- If there's a value for trim
-- and the input is longer than the threshold given
then
-- break the initial string into the pre-threshold (front)
-- and post-threshold (back) strings
local primary = string.sub( input, 1, trim )
local secondary = string.sub( input, trim )
local shiftatbreak = ''
-- Make a natural break at the delimiter before the threshold
-- and move the remainder to the back string
primary, shiftatbreak = mw.ustring.match(
primary,
'(.*)'..delimiter..'(.*)$'
)
secondary = shiftatbreak .. secondary
-- Separate the individual items by delimiter
-- and put them in a table (or array)
local items1 = HF.explode( delimiter, primary )
local items2 = HF.explode( delimiter, secondary )
-- If we changed the symbols before, we'll change them back now
for i, v in ipairs( items1 ) do
v = mw.ustring.gsub( v, '§', ',' )
end
for i, v in ipairs( items2 ) do
v = mw.string.gsub( v, '§', ',' )
end
-- Take the items in the front and back tables
-- and reproduce them as horizontal, bulleted lists
local list1 = L.makeList( 'horizontal', items1 )
local list2 = L.makeList( 'horizontal', items2 )
-- Create the HTML content wrapper for the back
local morebox = mw.html.create('div')
:addClass('expansion-tag')
:addClass('mw-collapsible')
:addClass('mw-collapsed')
:attr('data-expandtext', morelabel)
:attr('data-collapsetext', lesslabel)
:wikitext(list2):allDone()
-- Output everything
-- If we changed the symbols before, we'll change them back now
return string.gsub( list1 .. tostring(morebox), '§', ',' )
else
-- If there's no trim, or it's all under the threshold
-- Separate the individual items by delimiter
-- and put them in a table (or array)
local items = HF.explode( delimiter, itemstring )
-- Take the items in the table
-- and reproduce them as a horizontal, bulleted list
local list = L.makeList( 'horizontal', items )
-- Output the list
-- If we changed the symbols before, we'll change them back now
return string.gsub( list, '§', ',' )
end
end
-- Return the Module skeleton.
return Infobox
-- </nowiki>