FANDOM


-- Implements fields for [[Template:Infobox music]]
-- <nowiki>
 
local p = {}; -- Soundtrack Package
 
--------------------------------------------------------------
--[==[ Modules ]==]--
local ostList = mw.loadData "Module:Soundtrack/OST List"; -- read-only, psuedo-table, use pairs() and *not* next()
local userError = require "Dev:User error";
 
 
--[==[ Global Functions ]==]--
-- A wrapper function that will catch uny uncaught errors in func and will display the error to the editor
function nag_wrap(func)
    return function(...)
        local results = { pcall(func, ...) };
        local success = results[1];
 
        table.remove(results, 1); -- remove success arg from results
 
        if success then
            return unpack(results);
        else
            return userError(results[1], "Pages with script errors");
        end
    end
end
 
-- Returns whether the % (force article name) sentinel is appended to the name, and returns the real article name
-- For cases such as "Home (Music box)"
function isNameForced(name, onlyFrm)
    local frmName,forced = name:gsub("%%$",'');
    forced = forced > 0;
 
    if onlyFrm then
        -- Returns only the formatted name
        return frmName;
    else
        return forced, frmName;
    end
end
 
p.isNameForced = isNameForced;
 
-- Creates a MediaWiki link
function formatLink(name, link)
    local nameForced,name = isNameForced(name);
    local link = nameForced and name or link;
 
    return (link == name or (not link))
        and "[[" .. name .. "]]"
        or  "[[" .. link .. '|' .. name .. "]]";
end
 
-- "Shorthand" function to check all OSTs
-- May ultimately diminish readability by running loop in another func, but...
function chkOST(func)
    for ost,list in pairs(ostList) do
        func(ost, list);
    end
end
 
 
--[==[ Module Functions ]==]--
-- Gets track name from raw article name
-- e.g. "Alphys (track)" -> "Alphys"
function p.getFrmTrack(articleName)
    return articleName:gsub("%s+%b()$", "");
end
 
-- Gets track's index in track list from frame
function p.getListing()
    local trackPg = mw.title.getCurrentTitle();
    local normTrack = trackPg and trackPg.fullText:lower()
        or error("Something has gone horribly wrong."); -- error
 
    local trackNum = {}; -- to hold the track number(s)
    local multiOST = 0;  -- a counter of the number of OSTs the soundtrack is present in
 
    -- Example case for documentation
    if trackPg.namespace == 10 then -- I'm just gonna do it for the entire namespace.
        -- change "OST" below to some key in /OST List, should "OST" be changed there.
        return { OST = 14 }, false;
    end
 
    chkOST(function(ost, list)
        -- Perform a linear search
        for i,name in pairs(list) do
            -- NOTE: Leave compared strings in normalized form.
            if isNameForced(name, true):lower() == normTrack then
                -- Track found
                trackNum[ost] = i;
                multiOST = multiOST + 1;
                break; -- only breaks the inner-most loop
            end
        end
    end)
 
    assert(multiOST > 0, "This article is not a valid soundtrack page"); -- error
    return trackNum, multiOST > 1;
end
 
-- wrapper function
p.incr_track_wrapper = function(incr)
    return function(frame)
        local str = "";         -- hold the sequential track info
        local trackPresent = {} -- holds keys of tracks and string vals regarding which OST lists the track as present
        local trackCount = 0;   -- counter for number of tracks to be returned
 
        local indices,multiOST = p.getListing();
 
        -- Get sequential track information
        chkOST(function(ost, list)
            local rTrack = indices[ost] and list[indices[ost]+ incr]; -- raw track name
 
            if rTrack then
                trackCount = trackCount + (trackPresent[rTrack] and 0 or 1); -- increment
                trackPresent[rTrack] = (trackPresent[rTrack] or "") .. ost .. " + ";
            end
        end)
 
        -- Generate string
        for rTrack,info in pairs(trackPresent) do
            str = str
                .. formatLink(p.getFrmTrack(rTrack), rTrack)
                .. " (" .. info:sub(1, -4) .. ")\n";
        end
 
        return trackCount == 1
            and p.getFrmTrack(str:sub(1, -2))
            or str:sub(1, -2);
    end
end
 
p.next_track = nag_wrap(p.incr_track_wrapper( 1));
p.prev_track = nag_wrap(p.incr_track_wrapper(-1));
 
-- Returns the names of the albums that the current track (current article) belongs in
p.get_albums = function(frame)
    local albums = p.getListing();
    local str = "";
 
    for ost in pairs(albums) do
        str = str .. formatLink(ost) .. '\n';
    end
 
    return str;
end
 
-- Changes the title of articles (do not implement, goes against canonicalization)
-- e.g. "Alphys (track)" -> "Alphys"
p.frm_article_title = function(frame)
    --[[
    local title = frame.args[1]; -- article's title
    local whitelisted = false; -- flag to indicate article's "whitelist" status
 
    assert(type(title) == "string", "The first positional argument is a " .. type(title) .. ". (Expected string)"); -- error
 
    local trackName,frm = p.getFrmTrack(title);
    if frm == 0 then return''; end; -- title is already formatted
 
    -- Check if article is "whitelisted" (w/ sentinel)
    chkOST(function(_,list)
        for _,articleName in pairs(list) do
            local forced,frmName = isNameForced(articleName);
 
            if forced and frmName == title then
                whitelisted = true;
                return; -- terminate all loops
            end
        end
    end)
 
    if whitelisted then return''; end; -- whitelisted from title formatting
    return "{{DISPLAYTITLE:" .. trackName .. "}}"; -- this does not work in the parser, find a different solution
    --]]
end
 
----------------------------------------------------
return p;

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.