Module:Article link/sandbox
Appearance
This is the module sandbox page for Module:Article link (diff). |
Module that handles the logic for {{Article link}}
--[=[
Implementation logic for [[Template:Article Link]]
]=]
require('strict')
local p = {} --p stands for package
local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')
local Error = require('Module:Error')
local Cats = require('Module:Categories')
local function ordinal(n)
local unit = n % 10
local hundredth = n % 100
local ord
if unit == 1 and (hundredth ~= 11) then
ord = 'st'
elseif unit == 2 and (hundredth ~= 12) then
ord = 'nd'
elseif unit == 3 and (hundredth ~= 13) then
ord = 'rd'
else
ord = 'th'
end
return n .. '<sup>' .. ord .. '</sup>'
end
local function make_link(target, disp, suppressIfTargetMissing)
mw.logObject(target)
if suppressIfTargetMissing then
local targetTitle = mw.title.new( target )
if targetTitle == nil or not targetTitle.exists then
-- page is missing: just return the text
return (disp or target)
end
end
return '[[' .. target .. '|' .. (disp or target) .. ']]'
end
local function make_article_components(args)
local parts = { args['periodical'] }
if args['series'] or args['volume'] or args['issue'] then
-- Series/Volume/Issue layout
if args['series'] then
table.insert(parts, 'Series ' .. args['series'])
end
if args['volume'] then
table.insert(parts, 'Volume ' .. args['volume'])
end
if args['issue'] then
local rank = ''
if args['issue_rank'] ~= 'blank' then
rank = (args['issue_rank'] or 'Issue') .. ' '
end
table.insert(parts, rank .. args['issue'])
end
else
table.insert(parts, args['year'])
if args['month'] then
local fmtstr = "%d"
if mw.ustring.match(args['month'], "^0%d$") ~= nil then
fmtstr = "%02d"
end
table.insert(parts, string.format(fmtstr, args['month']))
end
if args['day'] then
local fmtstr = "%d"
if mw.ustring.match(args['day'], "^0%d$") ~= nil then
fmtstr = "%02d"
end
table.insert(parts, string.format(fmtstr, args['day']))
end
Cats:addCat("Pages using article link with date-based subpage structure")
end
return parts
end
local function make_date_str(args)
local dstamp = os.time({
year = args['year'],
month = args['month'] or 1,
day = args['day'] or 1
})
local out = ''
if args['day'] then
out = out .. ordinal(string.format("%d", args['day'])) .. ' '
end
if args['month'] then
out = out .. os.date('%B', dstamp) .. ', '
end
if args['year'] then
out = out .. args['year']
end
return out
end
local function make_span(class, content)
local span = mw.html.create('span')
:addClass(class)
:wikitext(content)
return tostring(span)
end
local function make_article_link_output(args, frame)
local parts = make_article_components(args)
local out = ''
local in_copyright = false
-- checking copyright status
if args['copyright_until'] then
local copyright_until = tonumber(args['copyright_until'])
if copyright_until == nil then
return Error.error({"The 'copyright_until' argument must be integer."})
end
local current_year = tonumber(os.date("%Y"))
if current_year < copyright_until then
in_copyright = true
end
end
-- link to the article
if args['direct_link'] then
-- assume nothing and just output the link
out = out .. args['direct_link']
elseif args['no_link'] or in_copyright then
-- if the article link is suppressed (e.g. a non-PD article but still
-- in a portal or author listing because it has a valid (legal) off-wiki link
out = out .. '"' .. args['article'] .. '"'
else
local art_page = args['link'] or args['article']
-- drop the issue if it doesn't feature in an article link
-- (note: it could still exist as a sibling to the articles)
if not yesno(args['issue_in_title']) then
mw.log("dropping issue from article")
table.remove(parts)
end
local target = table.concat(parts, '/') .. '/' .. art_page
out = out .. '"' .. make_link(target, args['article']) .. '"'
end
local authors = {}
if args['author'] then
table.insert(authors, args['author'])
out = out .. ' by ' .. make_span('wst-artlink-author', args['author'])
elseif args['author1'] then
-- At least one author is given, so loop to find all of them.
local i = 0
while true do
i = i + 1
local authorX = args['author' .. i]
if not authorX then break end
local displayX = args['author' .. i .. '-display']
if not displayX then
displayX = authorX
end
table.insert(authors, {link = authorX, display = displayX})
end
if #authors >= 1 then
out = out .. ' by '
for i, author in ipairs(authors) do
local linkedAuthor = '[[Author:' .. author.link .. '|' .. author.display .. ']]'
out = out .. make_span('wst-artlink-author', linkedAuthor)
if i == #authors then
out = out .. '.'
elseif i == #authors - 1 then
if #authors == 2 then
out = out .. ' and '
else
out = out .. ', and '
end
else
out = out .. ', '
end
end
end
end
if args['coauthor'] and not args['author1'] then
if args['author'] then
out = out .. ','
end
out = out .. ' with ' .. make_span('wst-artlink-coauthor', args['coauthor'])
end
local date_str
if args['override_date'] then
date_str = args['override_date']
-- override dates can still have the year, optionally
if args['year'] then
date_str = date_str .. ', ' .. args['year']
end
else
-- assume YYYY, YYYY-MM or YYYY-MM-DD
if args['year'] then
date_str = make_date_str(args)
end
end
out = out .. ' in ' .. make_span('wst-artlink-periodical',
make_link(args['periodical'], args['display_periodical'])
)
local parts = make_article_components(args)
if args['series'] or args['volume'] or args['issue'] then
local num_comps = 1
if args['series'] then
num_comps = num_comps + 1
local ser_target = table.concat(parts, '/', 1, num_comps )
local ser_link = make_link(ser_target, 'Series ' .. args['series'], true)
out = out .. ', ' .. make_span('wst-artlink-midlevel wst-artlink-series', ser_link)
end
if args['volume'] then
num_comps = num_comps + 1
local vol_target = table.concat(parts, '/', 1, num_comps )
local vol_link = make_link(vol_target, args['volume'], true)
out = out .. ', ' .. make_span('wst-artlink-midlevel wst-artlink-volnum', vol_link)
end
if args['issue'] then
if args['issue_in_title'] then
num_comps = num_comps + 1
end
local text = ''
if yesno(args['issue_link']) then
local iss_target = table.concat(parts, '/', 1, num_comps )
text = make_link(iss_target, args['issue'], true)
else
text = args['issue']
end
out = out .. ' ' .. '(' .. make_span('wst-artlink-midlevel wst-artlink-issnum', text) .. ')'
end
if date_str then
out = out .. ' (' .. make_span('wst-artlink-date', date_str) .. ')'
end
else
-- date style
if date_str then
local target = table.concat(parts, '/', 1, #parts)
local date_link = make_link(target, date_str, true)
out = out .. ', ' .. make_span('wst-artlink-midlevel wst-artlink-date', date_link)
end
end
if args['section'] then
out = out .. ', in section "' .. make_span('wst-artlink-section', args['section']) .. '"'
end
-- pages
if args['p'] then
if args['pp'] then
out = out .. ', pp. ' .. args['p'] .. '–' .. args['pp']
else
out = out .. ', p. ' .. args['p']
end
end
if args['editor'] then
if args['author'] or args['coauthor'] then
out = out .. ', ed. '
else
out = out .. ' Ed. '
end
out = out .. make_span('wst-artlink-editor', args['editor'])
end
-- append copyright expiration notice
if in_copyright then
out = out .. ' — Copyrighted in the United States until ' .. args['copyright_until']
if args['renewal'] then
local renewal = args['renewal']
if string.len(renewal) == 12 then
renewal = frame:expandTemplate{ title = 'CO Copyright renewal', args = { renewal } }
else
renewal = frame:expandTemplate{ title = 'Copyright renewal', args = { renewal } }
end
out = out .. ' due to ' .. renewal
end
end
return make_span('wst-artlink', out)
end
--[=[
Construct the link from arguments
]=]
function p.article_link(frame)
local args = getArgs(frame)
-- check parameters
if args.periodical == nil then
return Error.error({"The 'periodical' argument must be given."})
end
if args.article == nil and args.direct_link == nil then
return Error.error({"One of the arguments 'article' or 'direct_link' must be given."})
end
-- set defaults
if args.issue_in_title == nil then
args.issue_in_title = true
end
if args.issue_link == nil then
args.issue_link = true
end
-- number sets issue and issue_rank
if args.number ~= nil then
args.issue_rank = "Number"
args.issue = args.number
end
return make_article_link_output(args, frame) .. Cats:getCats()
end
return p