Module:HF

local HF = {} local L = require('Module:List') local language = mw.language.new('en')

local data = mw.loadData( 'Module:HF/data' ) local ordinals = data.ordinals local StoryNames = data.StoryNames local Categories = data.Categories function HF.explode( sep, text ) local sep, fields = sep or "::", {} local pattern = string.format("([^%s]+)", sep) text:gsub(pattern, function(c) fields[#fields+1] = c end) return fields end function HF.trim(s) if type(s) == "string" then return (s:gsub("^%s*(.-)%s*$", "%1")) else return false end end function HF.isempty(s) local result = false if type(s) == "nil" then result = true elseif type(s) == "string" then if s == "" then result = true end elseif type(s) == "table" then if next(s) == nil then result = true end end return result end function HF.print_r( t, name, indent ) local cart    -- a container local autoref -- for self references -- counts the number of elements in a table local function tablecount(t)     local n = 0     for _, _ in pairs(t) do n = n+1 end     return n  end -- (RiciLake) returns true if the table is empty local function isemptytable(t) return next(t) == nil end local function basicSerialize (o) local so = tostring(o) if type(o) == "function" then local info = debug.getinfo(o, "S") -- info.name is nil because o is not a calling level if info.what == "C" then return string.format("%q", so .. ", C function") else -- the information is defined through lines return string.format("%q", so .. ", defined in (" .. info.linedefined .. "-" .. info.lastlinedefined .. ")" .. info.source) end elseif type(o) == "number" or type(o) == "boolean" then return so    else return string.format("%q", so) end end local function addtocart (value, name, indent, saved, field) indent = indent or "" saved = saved or {} field = field or name cart = cart .. indent .. field if type(value) ~= "table" then cart = cart .. " = " .. basicSerialize(value) .. ";\n" else if saved[value] then cart = cart .. " = {}; -- " .. saved[value] .. " (self reference)\n" autoref = autoref .. name .. " = " .. saved[value] .. ";\n" else saved[value] = name --if tablecount(value) == 0 then if isemptytable(value) then cart = cart .. " = {};\n" else cart = cart .. " = {\n" for k, v in pairs(value) do                k = basicSerialize(k) local fname = string.format("%s[%s]", name, k)                field = string.format("[%s]", k)                 -- three spaces between levels addtocart(v, fname, indent .. "  ", saved, field) end cart = cart .. indent .. "};\n" end end end end name = name or "__unnamed__" if type(t) ~= "table" then return name .. " = " .. basicSerialize(t) end cart, autoref = "", "" addtocart(t, name, indent) return cart .. autoref end function HF.firstToUpper( str ) return (str:gsub("^%l", string.upper)) end function HF.round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end

function HF.formatDate( field ) -- InfoboxBuilder return HF.__formatDate( field.Value ) end

function HF._formatDate( frame ) -- invoke return HF.__formatDate( frame.args[1] ) end

function HF.__formatDate( var ) -- internal return language:formatDate("F j, Y", var) end

function HF.episodeCount( var ) local episodecount = 0 local episodesbyname = HF.explode( ";", var ) for i, episode in ipairs( episodesbyname ) do episodecount = episodecount + 1 end return episodecount end

function HF.numtoordinal( var ) local number = var if ordinals[var] ~= nil then ordinal = ordinals[var] else ordinal = "" end return ordinal end

function HF.list( field, vars ) -- InfoboxBuilder return HF.__list( field.ListType, field.Value ) end

function HF._list( frame ) -- invoked local listtype = frame.args['type'] or frame.args[1] local divisible = frame.args return HF.__list( listtype, divisible ) end

function HF.__list( listtype, divisible ) -- internal local items = HF.explode( ';', divisible ) if (listtype == 'horizontal') then items.class = 'hwrap plainlinks' end return L.makeList( listtype, items ) end

function HF.horizontal( frame ) -- invoked return HF.__list('horizontal', frame.args[1]) end

function HF.bulleted( frame ) -- invoked return HF.__list('bulleted', frame.args[1]) end

function HF.unbulleted( frame ) -- invoked return HF.__list('unbulleted', frame.args[1]) end

function HF.parseStory( var ) local StoryToParse = var if StoryNames[var] ~= nil then StoryToParse = StoryNames[var] else StoryToParse = '' end return StoryToParse end

function HF._parseStory(frame) return HF.parseStory(frame.args[1]) end

function HF.parseCategory( var ) local CatToParse = var if Categories[var] ~= nil then CatToParse = Categories[var] else CatToParse = '' end return CatToParse end

function HF.parseIndexedFields( args ) local input = {} input.fields  = {}   -- Actual data input.vars    = {}   -- "Global" variables -- Distribute args to vars and fields. local indexes = {} -- Table used to sort indexes of fields local fields = {} -- Temporary fields table local f = 0       -- Fields consecutive indice for k, v in pairs(args) do   local keySplit = HF.explode( ":", tostring(k) ) local index = tonumber( HF.trim( keySplit[1] ) ) local key   = tostring( HF.trim( keySplit[2] ) ) local value = tostring( HF.trim( v )           ) if index > 0 then if fields[index] == nil then table.insert( indexes, index ) fields[index] = {} end fields[index][key] = value else if not HF.isempty( HF.trim( value ) ) then input.vars[key] = value end end end

table.sort( indexes ) for i, index in ipairs(indexes) do   f = f + 1 input.fields[f] = {} input.fields[f] = fields[index] end return input end

return HF