Module:Citation

--require "mw.text"

local p = { wikitext = require "Module:Wikitext" }

function hideinprint(frame, content) return content end

function onlyinprint(frame, content) return "" end

function doi(frame, id) local text = hideinprint(frame, "doi:" .. p.wikitext.tag(frame, {name="nowiki",contents=id,params={}}) .. "") if ( string.sub(id,1,3) ~= "10." ) then text = text .. ""   end return text end

function listpeople(config, people) local text = "" local sep = config.AuthorSep or "&#59;" for i,person in ipairs(people) do       if (person.last ~= nil) then local one = person.last if (person.first ~= nil) then one = one .. ", " .. person.first end if (person.link ~= nil) then one = "" .. one .. "" end text = text .. one if ( people[i + 1] ~= nil ) then text = text .. sep .. " " end end end return text end

function anchorid(args) local P1 = args[1] or "" local P2 = args[2] or "" local P3 = args[3] or "" local P4 = args[4] or "" local P5 = args[5] or "" return "CITEREF" .. P1 .. P2 .. P3 .. P4 .. P5 end

function refid(args) local p = args.p or "" local pp = args.pp or "" local loc = args.loc or "" return anchorid(args) .. p .. pp .. loc end

function name(args) local P1 = args[1] or "" if ( args[5] ~= nil) then return P1 .. " et al." else local P2 = args[2] or "" local P3 = args[3] or "" local P4 = args[4] or "" if ( args[4] ~= nil ) then P4 = " " .. P4           P3 = " & " .. P3           P2 = " & " .. P2       elseif ( args[3] ~= nil ) then P3 = " " .. P3           P2 = " & " .. P2       elseif ( args[2] ~= nil ) then P2 = " " .. P2                   end return P1 .. P2 .. P3 .. P4   end end

function crossref(frame, args) local config = frame.args -- the arguments passed BY the template, in the wikitext of the template itself local LB = config.BracketLeft or "" local RB = config.BracketRight or "" local anchor = args.ref or args.Ref or anchorid(args) local text = name(args) local loc = args.loc or "" local page = args.p or args.page local pages = args.pp or args.pages if ( page ~= nil ) then local pagesep = config.PageSep or ", p. " loc = loc .. pagesep .. page end if ( pages ~= nil ) then local pagessep = config.PagesSep or ", pp. " loc = loc .. pagessep .. pages end local ps = args.Postscript or "" return LB .. "" .. text .. "" .. loc .. RB .. ps end

function citation0(frame, args) local config = frame.args -- the arguments passed BY the template, in the wikitext of the template itself -- Pick out the relevant fields from the arguments. Different citation templates define different field names for the same underlying things. local AuthorMask = args.authormask or args.authormask local Authors = args.authors local a = {} for i=1,9,1 do       local last = args["last" .. i] or args["surname" .. i] or args["author" .. i]       if ( last ~= nil ) then a[i] = {} a[i].last = last a[i].first = args["first" .. i] or args["given" .. i]           a[i].link = args["author" .. i .. "link"] or args["authorlink" .. i]       end end if ( a[1] == nil ) then local i = "" local last = args["last" .. i] or args["surname" .. i] or args["author" .. i]       if ( last ~= nil ) then a[1] = {} a[1].last = last a[1].first = args["first" .. i] or args["given" .. i]           a[1].link = args["author" .. i .. "link"] or args["authorlink" .. i]       end end local Coauthors = args.coauthor or args.coauthors local Editors = args.editors local e = {} for i=1,9,1 do       local last = args["editor" .. i .. "-last"] or args["editor-last" .. i] or args["EditorSurname" .. i] or args["Editor" .. i]       if ( last ~= nil ) then e[i] = {} e[i].last = last e[i].first = args["editor" .. i .. "-first"] or args["editor-first" .. i] or args["EditorGiven" .. i]           e[i].link = args["editor" .. i .. "link"] or args["editorlink" .. i]       end end if ( e[1] == nil ) then local i = "" local last = args["editor" .. i .. "-last"] or args["editor-last" .. i] or args["EditorSurname" .. i] or args["Editor" .. i]       if ( last ~= nil ) then e[1] = {} e[1].last = last e[1].first = args["editor" .. i .. "-first"] or args["editor-first" .. i] or args["EditorGiven" .. i]           e[1].link = args["editor" .. i .. "link"] or args["editorlink" .. i]       end end local Year = args.year or args.publicationdate local Date = args.date local Title = args.title or args.encyclopaedia or args.encyclopedia local Chapter = args.chapter or args.article local URL = args.archiveurl or args.url local ChapterURL = args.chapterurl local Journal = args.journal or args.newspaper or args.magazine or args.work local Series = args.series local Volume = args.volume local Issue = args.issue or args.number local Pages = args.pages or args.page local Edition = args.edition local Place = args.place or args.location local PublicationPlace = args.publicationplace or args.place or args.location local Publisher = args.publisher local Language = args.language local Format = args.format local ISBN = args.isbn or args.ISBN local DOI = args.doi or args.DOI local ID = args.id or args.ID or args.pmid or args.PMID local Ref = args.ref or args.Ref -- At this point fields may be nil if they weren't specified in the template use. We can use that to perform various substitutions. -- We also add leading spaces and surrounding markup and punctuation to the various parts of the citation, but only when they are non-nil. if ( Date == nil ) then Date = Year if ( Date ~= nil ) then if ( args.month ~= nil ) then Date = args.month .. " " .. Date if ( args.day ~= nil ) then Date = args.day .. " " .. Date end end end end if ( Journal ~= nil ) then Chapter = Title Title = Journal end if ( Chapter ~= nil ) then Chapter = "\"" .. Chapter .. "\"" if ( ChapterURL ~= nil ) then Chapter = "[" .. ChapterURL .. " " .. Chapter .. "]"       elseif ( URL ~= nil ) then Chapter = "[" .. URL .. " " .. Chapter .. "]"           URL = nil end Chapter = " " .. Chapter .. "."   else Chapter = "" end if ( Title ~= nil ) then if ( URL ~= nil ) then Title = "[" .. URL .. " " .. Title .. "]"           URL = nil end Title = " ''" .. Title .. "''."   else Title = "" end if ( Publisher ~= nil ) then Publisher = " " .. Publisher .. "." else Publisher = "" end if ( PublicationPlace ~= nil ) then PublicationPlace = " " .. PublicationPlace .. ":" else PublicationPlace = "" end if ( Language ~= nil ) then Language = " (in " .. Language .. ")" else Language = "" end if ( ISBN ~= nil ) then ISBN = " ISBN " .. ISBN else ISBN = "" end if ( DOI ~= nil ) then DOI = " " .. doi(frame, DOI) else DOI = "" end if ( URL ~= nil ) then URL = " " .. URL else URL = "" end if ( Edition ~= nil ) then Edition = " " .. Edition .. " edition" else Edition = "" end if ( Volume ~= nil ) then Volume = " '''" .. Volume .. "'''" else Volume = "" end if ( Issue ~= nil ) then Issue = " (" .. Issue .. ")" else Issue = "" end if ( Pages ~= nil ) then Pages = " :" .. Pages else Pages = "" end if ( Series ~= nil ) then Series = " " .. Series .. "." else Series = "" end if ( Format ~= nil ) then Format = " (" .. Format .. ")" else Format = "" end if ( ID ~= nil ) then ID = " " .. ID else ID = "" end if ( Date ~= nil ) then Date = " (" .. Date .. ")" else Date = "" end if ( Authors == nil ) then Authors = listpeople(config, a) end if ( Editors == nil ) then Editors = listpeople(config, e) end -- Piece all of the bits together at last. At this point, all of these should be guaranteed non-nil. -- We build things this way because it is more efficient in LUA not to keep reassigning to the same string variable over and over. local text if ( "" ~= Authors ) then if ( "" ~= Date ) then Date = Date .. "." else Authors = Authors .. "." end if ( "" ~= Editors ) then Editors = " in " .. Editors .. "." end text = Authors .. Date .. Chapter .. Editors .. Title .. Format .. Edition .. Language .. Volume .. Issue .. Pages .. Series .. PublicationPlace .. Publisher .. ISBN .. DOI .. ID .. URL elseif ( "" ~= Editors) then Editors = Editors .. " (eds.)" if ( "" ~= Date ) then Date = Date .. "." else Editors = Editors .. "." end text = Editors .. Date .. Chapter .. Title .. Format .. Edition .. Language .. Volume .. Issue .. Pages .. Series .. PublicationPlace .. Publisher .. ISBN .. DOI .. ID .. URL else text = Chapter .. Title .. Format .. Edition .. Language .. Volume .. Issue .. Pages .. Series .. PublicationPlace .. Publisher .. Date .. ISBN .. DOI .. ID .. URL end -- Now enclose the whole thing in a element if it is cross-linked from elsewhere. if ( Year == nil ) then Year = "" end if ( Ref ~= nil ) then local id = Ref if ( "harv" == Ref ) then local P1 = Surname1 local P2 = Surname2 local P3 = Surname3 local P4 = Surname4 local P5           if ( Surname2 == nil ) then P2 = Year elseif ( Surname3 == nil ) then P3 = Year elseif ( Surname4 == nil ) then P4 = Year else P5 = Year end id = anchorid({P1,P2,P3,P4,P5}) end local args = { class="citation " .. config.CitationClass, id=id } text = p.wikitext.tag(frame, {name="span", contents=text, params=args}) end return text end

function r0(frame, name, group, page) if ( name == nil ) then return "" end if ( group == nil ) then group = "" end local p = "" if ( page ~= nil ) then local contents = ":" .. page p = p.wikitext.tag(frame, {name="sup",contents=contents,params={class="reference",style="white-space:nowrap;"}}) end return p.wikitext.tag(frame, {name="ref",contents="",params={name=name,group=group}}) .. p end

-- This is used by to create DOI links in the style used in citations. function p.doi(frame) local pframe = frame:getParent local id = pframe.args.id or pframe.args[1] or "" return doi(frame, id) end

-- This is used by to create ISSN links in the style used in citations. function p.ISSN(frame) local pframe = frame:getParent local Name = pframe.args[1] or "" return hideinprint(frame, "ISSN .. Name .. " " .. Name .. "") end

-- This is used by templates such as to create the (encoded) anchor name for a Harvard cross-reference hyperlink. function p.SFNID(frame) local pframe = frame:getParent return anchorid(pframe.args) end

-- This is used by templates such as to create the Harvard cross-reference text. function p.Harvard(frame) local pframe = frame:getParent return crossref(frame, pframe.args) end

-- This is used by templates such as to create the actual citation text. function p.citation(frame) local pframe = frame:getParent return citation0(frame, pframe.args) end

-- This is used by templates such as to create the entire cross-reference. function p.sfn(frame) local pframe = frame:getParent local content = crossref(frame, pframe.args) local args = { name = refid(pframe.args) } -- return mw.text.tag{name = "ref", contents = content, params = args} return p.wikitext.tag(frame, {name = "ref", contents = content, params = args}) end

-- This is used by template. function p.r(frame) local pframe = frame:getParent local config = frame.args -- the arguments passed BY the template, in the wikitext of the template itself local args = pframe.args -- the arguments passed TO the template, in the wikitext that instantiates the template args.page1 = args.page1 or args.page local text = "" -- This would be shorter using ipairs, but that doesn't work on an arguments table supplied to a template. local index = 1 while args[index] ~= nil do       local arg = args[index] local t = r0(frame, arg, args.group, args["page" .. index]) text = text .. t       index = index + 1 end return text end

-- This is used by template. function p.reflabel(frame) local pframe = frame:getParent local config = frame.args -- the arguments passed BY the template, in the wikitext of the template itself local args = pframe.args -- the arguments passed TO the template, in the wikitext that instantiates the template local P1 = args[1] or "" local P2 = args[2] or "" local P3 = args[3] or "" local id = nil local contents = "&#91;" .. P2 .. "&#93;" local params = {} params.class="reference" if ( args.noid ~= nil and args.noid ~= "" ) then params.id = "ref_" .. P1 .. P3 end return p.wikitext.tag(frame, {name="sup",contents=contents,params=params}) end

return p