Module:Citation Archive
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