Module:Citation Archive

From Remilia Wiki
Jump to navigation Jump to search

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

--[[
Module:Citation/Archive
Extensible archive service registry for citation templates

To add a new archive service, add an entry to SERVICES below.
]]

local p = {}

--------------------------------------------------------------------------------
-- ARCHIVE SERVICE REGISTRY
--------------------------------------------------------------------------------

p.SERVICES = {
    wayback = {
        name = 'Wayback Machine',
        param = 'wayback',
        priority = 1,
    },
    today = {
        name = 'archive.today',
        param = 'today',
        priority = 2,
    },
    megalodon = {
        name = 'Megalodon',
        param = 'megalodon',
        priority = 3,
    },
    perma = {
        name = 'Perma.cc',
        param = 'perma',
        priority = 4,
    },
    ghost = {
        name = 'GhostArchive',
        param = 'ghost',
        priority = 5,
    },
}

-- Legacy parameter mappings (old name -> service key)
p.LEGACY = {
    ['archive-url'] = 'wayback',
    ['archive-date'] = 'wayback',
    ['archive-is'] = 'today',
    ['archive-is-date'] = 'today',
}

--------------------------------------------------------------------------------
-- UTILITY
--------------------------------------------------------------------------------

local function trim(s)
    if not s then return nil end
    return tostring(s):match('^%s*(.-)%s*$')
end

local function hasValue(s)
    return s ~= nil and trim(s) ~= ''
end

--------------------------------------------------------------------------------
-- EXTRACTION
--------------------------------------------------------------------------------

-- Extract all archive data from template arguments
-- Returns sorted list of { name, url, date }
function p.extract(args)
    local archives = {}
    
    -- New-style parameters: archive-{service}, archive-{service}-date
    for key, service in pairs(p.SERVICES) do
        local urlParam = 'archive-' .. service.param
        local dateParam = 'archive-' .. service.param .. '-date'
        
        local url = trim(args[urlParam])
        local date = trim(args[dateParam])
        
        if hasValue(url) then
            table.insert(archives, {
                name = service.name,
                url = url,
                date = date,
                priority = service.priority,
            })
        end
    end
    
    -- Legacy: archive-url -> wayback (if not already set)
    if hasValue(args['archive-url']) and not hasValue(args['archive-wayback']) then
        table.insert(archives, {
            name = p.SERVICES.wayback.name,
            url = trim(args['archive-url']),
            date = trim(args['archive-date']),
            priority = p.SERVICES.wayback.priority,
        })
    end
    
    -- Legacy: archive-is -> today (if not already set)
    if hasValue(args['archive-is']) and not hasValue(args['archive-today']) then
        table.insert(archives, {
            name = p.SERVICES.today.name,
            url = trim(args['archive-is']),
            date = trim(args['archive-is-date']),
            priority = p.SERVICES.today.priority,
        })
    end
    
    -- Sort by priority
    table.sort(archives, function(a, b)
        return (a.priority or 99) < (b.priority or 99)
    end)
    
    return archives
end

--------------------------------------------------------------------------------
-- RENDERING
--------------------------------------------------------------------------------

-- Render archives as "Archived at X on date. Archived at Y."
function p.render(archives)
    if not archives or #archives == 0 then
        return nil
    end
    
    local parts = {}
    for _, archive in ipairs(archives) do
        local text = 'Archived at [' .. archive.url .. ' ' .. archive.name .. ']'
        if hasValue(archive.date) then
            text = text .. ' on ' .. archive.date
        end
        table.insert(parts, text)
    end
    
    return table.concat(parts, '. ')
end

return p