Module: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 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 .. '' .. ord .. '' 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  .. (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 table.insert(parts, string.format("%02d", args['month'])) end

if args['day'] then table.insert(parts, string.format("%02d", args['day'])) end 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(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.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) end

return p