Documentation for this module may be created at Module:ComicsHF/doc
-- HF stands for High Frequency.
-- This Module augments the built-in HF
local HF = mw.InfoboxBuilderHF
----------------------------
-- Libraries of functions --
----------------------------
-- Parses invocation parameters, trims whitespace, and removes blanks
HF.getArgs = require('Dev:Arguments').getArgs
-- Since this should only be evaluated once per pageview, it's now global
_G.vars = { Pagename = mw.title.getCurrentTitle().text }
-----------------------
-- Libraries of data --
-----------------------
-- Data tables for common Staff contributors
local StaffNames = require( 'Module:StaffCorrection' )
-- Data tables for common Publisher names
local CompanyNames = require( 'Module:CompanyCorrection' )
------------------------------------------------
-- Local functions (used only in this Module) --
------------------------------------------------
function invokeInt(funcName)
-- This wrapper allows invocation of an internal function from a frame.
-- In other words, it translates from a Template: to an internal function.
return function (frame)
local args = HF.getArgs(frame, { trim = true, removeBlanks = true })
return HF[funcName](args, vars)
end
end
----------------------------------------------------------
-- Public functions (called from a Template or article) --
----------------------------------------------------------
-- Adds a Help button to the title / corner of an Infobox.
-- (Does not implement a specific Template. Called from invoke.)
HF.TitleHelpButton = invokeInt('_TitleHelpButton')
-- Adds a Help button to the label of an Infobox field.
-- (Does not implement a specific Template. Called from invoke.)
HF.HelpButton = invokeInt('_HelpButton')
-- Takes a list (or array) of items in a field that are on a single line
-- and separated by a delimiter, and does something with them.
-- (Does not implement a specific Template. Called from invoke.)
HF.Iterator = invokeInt('_Iterator')
---------------------------------------------------------
-- Internal functions (used in this and other Modules) --
---------------------------------------------------------
-- eliminates whitespace from the front and back of a string
function HF.trim(s)
if type(s) == 'string' then
return (s:gsub("^%s*(.-)%s*$", '%1'))
else
return false
end
end
-- I think this is for padding with zeros
function HF.AddZeros( s, len )
local output = ""
local sLength = string.len( tostring( s ) )
local diff = tonumber( len ) - tonumber( sLength )
if diff > 0 then
for i = 1, diff do
output = output .. "0"
end
end
output = output .. s
return output
end
-- This creates an external link.
function HF.ExternalLink( target, label, plain )
local output = string.format('[%s %s]', target, label)
if plain == true then
output = string.format('<span class="plainlinks">%s</span>', output)
end
return output
end
-- This creates a link to a category, as well as placing it in that category.
-- `sortkey` and `label` are optional
-- If there's no `label` given, it will only place it in the category,
-- which is what HF.Category is for.
function HF.CategoryLink( category, sortkey, label )
if not HF.isempty( label ) then
return HF.LinkToCategory( category, label ) ..
HF.Category( category, sortkey )
else
return HF.Category( category, sortkey )
end
end
-- Adds a Category
-- `sortkey` is optional
function HF.Category( category, sortkey )
if sortkey == nil then sortkey = '' else sortkey = '|' .. sortkey end
return string.format('[['..'Category:%s%s]]', category, sortkey)
end
-- Adds a link to a Category
function HF.LinkToCategory( category, label )
return string.format('[[:'..'Category:%s|%s]]', category,
label or 'Category:' .. category )
end
-- Adds an internal link
-- `label` is optional
function HF.Link( link, text )
if not HF.isempty( text ) then
return string.format('[['..'%s|%s]]', link, text)
else
return string.format('[['..'%s]]', link)
end
end
-- Checks to see if there's an existing article at the target.
-- If there is, creates a link.
-- If there's not, only write the target's name as text.
-- If it is passed a link, it will not perform this check and will only write the link.
function HF.KillNewLinks( object )
if object:match("^%[%[(.*)%]%]$") then
return object
elseif mw.title.new( object ).exists == true then
return HF.Link( object )
else
return object
end
end
-- Checks to see if there's an existing category at the target.
-- If there is, creates a link.
-- If there's not, only write the target's name as text.
function HF.KillNewCatLinks( object )
if mw.title.new( object, 'Category' ).exists == true then
return HF.Link( ':Category:'..object, object )
else
return object
end
end
-- Checks to see if there's an existing category at the target.
-- If there is, creates a link.
-- If there's not, only write the target's name as text.
function HF.KillNewCategories( object )
if mw.title.new( object, 'Category' ).exists == true then
return HF.Category( object, object, object)
else
return object
end
end
function HF._HelpButton( args )
if HF.isempty( args.buttonsize ) then args.buttonsize = "10px" end
local link = string.format(
'[['..'File:Information-silk.png|%s|link=Click here for help with this field#%s]] %s',
args.buttonsize,
args.Section or args.Label or '',
args.Label or ''
)
return link
end
function HF._TitleHelpButton( args )
if HF.isempty( args.buttonsize ) then args.buttonsize = "16px" end
local link = string.format(
'[['..'File:Help.png|%s|link=%s#%s|%s]]',
args.buttonsize,
args.Link or 'Help:Template Fields',
args.Section or args.Label or '',
args.Label or ''
)
return '<span class="title-help-button">'..link..'</span>'
end
function HF.ContributorNameCorrection( name )
if type( StaffNames[ string.lower( name ) ] ) == "string" then
return StaffNames[ string.lower( name ) ]
else
return name
end
end
function HF.CompanyNameCorrection( name )
if type( CompanyNames[ string.lower( name ) ] ) == "string" then
return CompanyNames[ string.lower( name ) ]
else
return name
end
end
function HF._Iterator( args )
local text = args['text'] or args[1] or nil
local delimiter = args['delimiter'] or args[2] or ';'
local contributorrole = args['role'] or nil
local check = args['check'] or nil
local storage = mw.text.split( text, delimiter )
local output = {}
for i, item in ipairs( storage ) do
item = HF.trim(item)
check = HF.trim(check)
if not string.match(item, '%S') then break end
if check == 'company' then
if type(item) == 'string' and
CompanyNames:in_database( item ) then
table.insert( output,
HF.KillNewLinks( CompanyNames:normalize(item) ) ..
CompanyNames:cat_staff( item )
)
else
table.insert( output, item )
end
elseif check == 'staff' then
table.insert(
output,
StaffNames:link( item ) ..
StaffNames:cat_role( item, contributorrole )
)
elseif check == 'featured' then
table.insert(
output,
HF.Category( item .. ' Titles') ..
HF.Link( item )
)
elseif check == 'featured_publisher' then
table.insert(
output,
HF.Category( CompanyNames:normalize(item) .. ' Titles') ..
HF.KillNewLinks( CompanyNames:normalize(item) )
)
elseif check == 'category' then
table.insert(output, HF.KillNewCategories( item ))
elseif check == 'categorylinkonly' then
table.insert(output, HF.KillNewCatLinks( item ))
elseif check == 'noredlink' then
table.insert(output, HF.KillNewLinks( item ))
elseif check == 'jobtitles' then
if mw.title.new( item..'s', 'Category' ).exists == true then
table.insert(output, HF.CategoryLink( item..'s', item, item) )
else
table.insert(output, item)
end
else
table.insert(output, item)
end
end
return table.concat(output, ' · ')
end
HF.TrimOverflow = invokeInt('_TrimOverflow')
function HF._TrimOverflow( args )
local input = args[1]
local breakat = args['TrimBreak'] or ' '
local limit = args['TrimLimit'] or 1000
local morelabel = args['TrimMoreLabel'] or 'more...'
local lesslabel = args['TrimLessLabel'] or 'less...'
if not input then return nil end
if mw.ustring.len( input ) > limit then
local primary = mw.ustring.sub( input, 1, limit )
local secondary = mw.ustring.sub( input, limit )
local shiftatbreak = ''
if not args['TrimBreak'] and string.find(primary, '·') then breakat = '·'
elseif not args['TrimBreak'] and string.find(primary, ';') then breakat = ';'
elseif not args['TrimBreak'] and string.find(primary, ' ') then breakat = ' '
end
primary, shiftatbreak = mw.ustring.match( primary, '(.*)'..breakat..'(.*)$')
secondary = shiftatbreak .. secondary
local morebox = mw.html.create('div')
:addClass('expansion-tag')
:addClass('mw-collapsible')
:addClass('mw-collapsed')
:attr('data-expandtext',morelabel)
:attr('data-collapsetext',lesslabel)
:wikitext(secondary):allDone()
return primary .. tostring(morebox)
else
return input
end
end
-------------------------------------------------
-- Output (send it back to whatever called it) --
-------------------------------------------------
return HF