FANDOM


-- 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