Module:ComicTitle

From BIONICLEsector01

Documentation for this module may be created at Module:ComicTitle/doc

local data = mw.loadData("Module:ComicTitle/data")
local p = {}

-- The value of the type arg indicating that the desired output is a short
-- version of the title.
local TYPE_SHORT = "short"

-- The value of the type arg indicating that the desired output is a
-- DISPLAYTITLE-ready version of the title.
local TYPE_DISPLAYTITLE = "displaytitle"

-- The value of the type arg indicating that the desired output is a lead-ready
-- version of the title.
local TYPE_LEAD = "lead"

-- The value of the type arg indicating that the desired output is a link.
local TYPE_LINK = "link"

-- Given the invokation args, return the desired type of the title if a valid
-- one was specified, or nil otherwise.
-- Valid values of type are specified in TYPE_SHORT, TYPE_DISPLAYTITLE,
-- and TYPE_LEAD.
local function getDesiredComicTitleType(args)
    if args["type"] == nil then
        return nil
    end

    for _, validType in ipairs({TYPE_SHORT, TYPE_DISPLAYTITLE, TYPE_LEAD}) do
        if args["type"] == validType then
            return validType
        end
    end

    return nil
end

-- Given a shortcut for an issue within a series, split that shortcut up into
-- ones for the series and the issue. The function assumes the first number is
-- the beginning of the issue shortcut.
-- Return both seriesShortcut and issueShortcut if both can be found,
-- or just shortcut if an issueShortcut is not found.
local function getSeriesAndIssueShortcuts(shortcut)
    local issueShortcutStartIndex, _ = string.find(shortcut, "%d")
    if issueShortcutStartIndex == nil then
        return shortcut
    end

	local seriesShortcut = string.sub(shortcut, 1, issueShortcutStartIndex - 1)
	local issueShortcut = string.sub(shortcut, issueShortcutStartIndex)
    return seriesShortcut, issueShortcut
end

-- Return a link to the given article with the given link text and color.
local function getLink(article, text, color)
    if color == nil or color == "" then
        if article == text then
            return "[[" .. article .. "]]"
        else 
            return "[[" .. article .. "|" .. text .. "]]"
        end
    else
    	return mw.getCurrentFrame():expandTemplate{ title = 'ColorLink', args = { color, article, text } }
    end
end

-- Return a bolded copy of the given string.
local function getBoldedText(text)
	return "<b>" .. text .. "</b>"
end

-- Return an italicized copy of the given string.
local function getItalicizedText(text)
	return "<cite>" .. text .. "</cite>"
end

-- Return a quote-wrapped copy of the given string.
local function getQuotedText(text)
	return "\"" .. text .. "\""
end

-- Return a copy of the given text that has been transformed in the following order:
-- * italicized if shouldItalicize is true,
-- * bolded if shouldBold is true, and
-- * wrapped in quotation marks if shouldQuote is true.
-- If text is nil, return an empty string.
local function getFormattedText(text, shouldItalicize, shouldBold, shouldQuote)
    if text == nil then
        return ""
    end

    local formattedText = text

    if shouldItalicize then
        formattedText = getItalicizedText(formattedText)
    end

    if shouldBold then
        formattedText = getBoldedText(formattedText)
    end

    if shouldQuote then
        formattedText = getQuotedText(formattedText)
    end

    return formattedText
end

-- Given a shortcut for a valid standalone comic,
-- return that comic's title formatted as desired.
local function getFormattedStandaloneTitle(shortcut, type, linkColor)
    local shouldLink = type == TYPE_LINK
    local shouldItalicize = data.standalone[shortcut].italicizeTitle
    local shouldBold = type == TYPE_LEAD
    local shouldQuote = not ((type == TYPE_DISPLAYTITLE) or shouldItalicize)

    local titleText = data.standalone[shortcut].title
    if shouldLink then
        titleText = getLink(data.standalone[shortcut].article, titleText, linkColor)
    end

    return getFormattedText(titleText, shouldItalicize, shouldBold, shouldQuote)
end

-- Given a shortcut representing a valid comic series,
-- return that series's title formatted as desired.
local function getFormattedSeriesTitle(seriesShortcut, type, linkColor)
    local shouldLink = type == TYPE_LINK
    local shouldItalicize = data.series[seriesShortcut].italicizeSeriesTitle
    local shouldBold = type == TYPE_LEAD

    local titleText = data.series[seriesShortcut].seriesTitle
    if shouldLink then
        titleText = getLink(data.series[seriesShortcut].seriesArticle, titleText, linkColor)
    end

    return getFormattedText(titleText, shouldItalicize, shouldBold, false)
end

-- Given shortcuts representing a valid comic issue (that doesn't have a name)
-- within a valid comic series,
-- return that issue's title formatted as desired.
local function getFormattedSeriesAndUnnamedIssueTitle(seriesShortcut, issueShortcut, type, linkColor)
    local shouldLink = type == TYPE_LINK
    local shouldItalicizeSeriesTitle = data.series[seriesShortcut].italicizeSeriesTitle
    local shouldBold = type == TYPE_LEAD

    local titleText = getFormattedText(data.series[seriesShortcut].seriesTitle, shouldItalicizeSeriesTitle, false, false) .. " " .. issueShortcut
    if shouldLink then
        titleText = getLink(data.series[seriesShortcut].seriesTitle .. " " .. issueShortcut, titleText, linkColor)
    end
    
    return getFormattedText(titleText, false, shouldBold, false)
end

-- Given shortcuts representing a valid comic issue (that has a name)
-- within a valid comic series
-- return that issue's title formatted as desired.
local function getFormattedSeriesAndNamedIssueTitle(seriesShortcut, issueShortcut, type, linkColor)
    local shouldLink = type == TYPE_LINK
    local shouldDisplaySeriesTitle = not (type == TYPE_SHORT or type == TYPE_LEAD or type == TYPE_LINK)
    local shouldItalicizeSeriesTitle = data.series[seriesShortcut].italicizeSeriesTitle
    local shouldBoldIssueTitle = type == TYPE_LEAD
    local shouldQuoteIssueTitle = type ~= TYPE_DISPLAYTITLE

    local issueTitleText = data.series[seriesShortcut].issueTitles[issueShortcut]
    if shouldLink then
        issueTitleText = getLink(data.series[seriesShortcut].seriesTitle .. " " .. issueShortcut .. ": " .. data.series[seriesShortcut].issueTitles[issueShortcut], issueTitleText, linkColor)
    end
    
    local formattedSeriesTitleAndIssueNumber = getFormattedText(data.series[seriesShortcut].seriesTitle, shouldItalicizeSeriesTitle, false, false) .. " " .. issueShortcut
    local formattedIssueTitle = getFormattedText(issueTitleText, false, shouldBoldIssueTitle, shouldQuoteIssueTitle)

    if shouldDisplaySeriesTitle then
        return formattedSeriesTitleAndIssueNumber .. ": " .. formattedIssueTitle
    else
        return formattedIssueTitle
    end
end

-- Return the title, formatted as desired, for the comic represented by the
-- given shortcut.
-- If the requested shortcut is not recognized, return it unmodified unless
-- a link was requested, in which case return a link to the given shortcut.
-- shortcut: the code (abbreviation) representing the comic name
-- type: the valid type of the title, or nil if none specified
-- linkColor: the color to use for producing a link, or nil for the default color
local function _comicTitle(shortcut, type, linkColor)
    if data.standalone[shortcut] ~= nil then
        return getFormattedStandaloneTitle(shortcut, type, linkColor)
    end

    -- if the program reaches this point,
    -- the shortcut doesn't reference a standalone comic, but it might reference
    -- a series (either the shortcut is for a series itself, or an issue within
    -- a series)

    local seriesShortcut, issueShortcut = getSeriesAndIssueShortcuts(shortcut)

	if seriesShortcut ~= nil and data.series[seriesShortcut] ~= nil then
		if seriesShortcut == shortcut then
			return getFormattedSeriesTitle(seriesShortcut, type, linkColor)
        elseif data.series[seriesShortcut].issueTitles[issueShortcut] ~= nil then
            return getFormattedSeriesAndNamedIssueTitle(seriesShortcut, issueShortcut, type, linkColor)
        else
            return getFormattedSeriesAndUnnamedIssueTitle(seriesShortcut, issueShortcut, type, linkColor)
        end
	end

    -- comic is not recognized
    
    if type == TYPE_LINK then
    	return getLink(shortcut, shortcut, linkColor)
    else
    	return shortcut
    end
end

-- Pull out the relevant args for use.
function p.comicTitle(frame)
    local shortcut = frame.args[1] or ""
    local type = getDesiredComicTitleType(frame.args)

    return _comicTitle(shortcut, type, nil)
end

-- Pull out the relevant args for use.
function p.comicLink(frame)
    local shortcut = frame.args[1] or ""
    local type = TYPE_LINK
    local linkColor = frame.args["color"] or nil

    return _comicTitle(shortcut, type, linkColor)
end

return p