Modul:Citation: Perbedaan antara revisi

Dari Wikipedia bahasa Indonesia, ensiklopedia bebas
Konten dihapus Konten ditambahkan
Farras (bicara | kontrib)
~
Farras (bicara | kontrib)
k ←Suntingan Farras (bicara) dibatalkan ke versi terakhir oleh Iwan Novirion
Baris 1: Baris 1:
---------------------------------------------------------------------
-- Module:Citation - Lua module for Citation auxiliary templates
---------------------------------------------------------------------
-- For the {{citation}} formatting functions, see: Module:Citation/CS1
-- (see NOTES at bottom)
--require "mw.text"
--require "mw.text"


local z = {
local z = {
wikitext = require("Module:Wikitext"),
wikitext = require("Module:Wikitext"),
mw = require("Module:Mw")
extensiontags = {
nowiki = true,
ref = true,
gallery = true,
pre = true,
source = true,
categorytree = true,
charinsert = true,
hiero = true,
imagemap = true,
inputbox = true,
math = true,
poem = true,
ref = true,
references = true,
syntaxhighlight = true,
timeline = true,
}
}
}

function trim( str )
if str == nil then
return nil;
end
return str:match( "^%s*(.-)%s*$" );
end


function hideinprint(content)
function hideinprint(content)
Baris 43: Baris 14:
end
end


function nowiki(frame, content)
-- This returns a string with HTML character entities for wikitext markup characters.
return z.mw.text.tag({name="nowiki",contents=content,params={}}, frame)
function wikiescape(text)
text = text:gsub( '[&\'%[%]{|}]', {
['&'] = '&',
["'"] = ''',
['['] = '[',
[']'] = ']',
['{'] = '{',
['|'] = '|',
['}'] = '}' } );
return text;
end
end


function createTag(t, frame)
function externallinkid(frame, args)
local name = t.name or "!-- --"
local sep = args.separator or " "
local content = t.contents or ""
args.suffix = args.suffix or ""
local attrs = {}
local t0 = onlyinprint(args.label .. sep .. args.id)
local t1 = hideinprint("[[" .. args.link .. "|" .. args.label .. "]]" .. sep .. "[" .. args.prefix .. z.mw.url.encode(args.id) .. args.suffix .. " " .. nowiki(frame, args.id) .. "]")
if ( z.extensiontags[name] ) then
return t0 .. t1
-- We have to preprocess these, so that they are properly turned into so-called "strip markers" in the generated wikitext.
if ( not frame ) then error ("Please supply an extra frame argument to the createTag() function.") end
local params = {}
for n,v in pairs(t.params) do
table.insert(params, "|" .. n .. "=" .. v)
end
return frame:preprocess("{{#tag:" .. name .. "|" .. content .. table.concat(params) .. "}}")
else
for n,v in pairs(t.params) do
if (v) then
table.insert(attrs, n .. "=\"" .. wikiescape(v) .. "\"")
else
table.insert(attrs, n)
end
end
if ("" == content) then
return "<" .. name .. " " .. table.concat(attrs, " ") .. "/>"
else
return "<" .. name .. " " .. table.concat(attrs, " ") .. ">" .. content .. "</" .. name .. ">"
end
end
end

--[[
This is a clone of mw.text.nowiki. When the mw.text library is installed,
this can be replaced by a call to that library. ]]
function nowiki( s )
-- string.gsub is safe here, because we're only caring about ASCII chars
s = string.gsub( s, '["&\'<=>%[%]{|}]', {
['"'] = '&#34;',
['&'] = '&#38;',
["'"] = '&#39;',
['<'] = '&#60;',
['='] = '&#61;',
['>'] = '&#62;',
['['] = '&#91;',
[']'] = '&#93;',
['{'] = '&#123;',
['|'] = '&#124;',
['}'] = '&#125;',
} )
s = string.sub( string.gsub( '\n' .. s, '\n[#*:;]', {
["\n#"] = "\n&#35;",
["\n*"] = "\n&#42;",
["\n:"] = "\n&#58;",
["\n;"] = "\n&#59;",
} ), 2 )
s = string.gsub( s, '://', '&#58;//' )
s = string.gsub( s, 'ISBN ', 'ISBN&#32;' )
s = string.gsub( s, 'RFC ', 'RFC&#32;' )

return s
end
end


function externallinkid(args)
function internallinkid(frame, args)
local sep = args.separator or "&nbsp;"
local sep = args.separator or "&nbsp;"
args.suffix = args.suffix or ""
args.suffix = args.suffix or ""
local url_string = args.id
if args.encode == true or args.encode == nil then
url_string = mw.uri.encode( url_string );
end
local t0 = onlyinprint(args.label .. sep .. args.id)
local t0 = onlyinprint(args.label .. sep .. args.id)
local t1 = hideinprint("[[" .. args.link .. "|" .. args.label .. "]]" .. sep .. "[" .. args.prefix .. url_string .. args.suffix .. " " .. nowiki(args.id) .. "]")
local t1 = hideinprint("[[" .. args.link .. "|" .. args.label .. "]]" .. sep .. "[[" .. args.prefix .. args.id .. args.suffix .. "|" .. nowiki(frame, args.id) .. "]]")
return t0 .. t1
return t0 .. t1
end
end


function doi(id, inactive, nocat)
function amazon(frame, id, domain)
if ( nil == domain ) then
domain = "com"
elseif ( "jp" == domain or "uk" == domain ) then
domain = "co." .. domain
end
return externallinkid(frame, {link="Amazon Standard Identification Number",label="ASIN",prefix="//www.amazon."..domain.."/dp/",id=id})
end

function doi(frame, id, broken, inactive, nocat)
local text = externallinkid(frame, {link="Digital object identifier",label="doi",prefix="http://dx.doi.org/",id=id,separator=":"})
local cat = ""
local cat = ""
local text;
if ( inactive ~= nil ) then
if ( inactive ~= nil ) then
text = "[[Digital object identifier|doi]]:" .. id;
cat = cat .. "[[Category:Pages with DOIs inactive since " .. selectyear(inactive) .. "]]"
inactive = " (inactive " .. inactive .. ")"
inactive = " (inactive " .. inactive .. ")"
cat = cat .. "[[Category:Pages with DOIs inactive since " .. z.wikitext.canonicalcleanuptime(inactive) .. "]]"
else
else
text = externallinkid({link="Digital object identifier",label="doi",prefix="http://dx.doi.org/",id=id,separator=":"})
inactive = ""
inactive = ""
end
end
if ( string.sub(id,1,3) ~= "10." ) then
if ( string.sub(id,1,3) ~= "10." ) then
cat = cat .. "[[Category:Pages with DOI errors]]" .. '<span class="error"> Bad DOI (expected "10." prefix) in code number</span>'
cat = cat .. "[[Category:Pages with DOI errors]]"
end
end
if ( nocat and nocat ~= "" ) then cat = "" end
if ( nocat and nocat ~= "" ) then cat = "" end
return text .. inactive .. cat
return text .. inactive .. cat
end

function url(frame, id)
local t0 = onlyinprint(id)
local t1 = hideinprint("[" .. id .. " " .. nowiki(frame, id) .. "]")
return t0 .. t1
end
end


function selectyear( str )
function openlibrary(frame, id)
local lang = mw.getContentLanguage();
local cat = ""
local good, result;
local prefix = ""
local code = id:sub(-1,-1)
good, result = pcall( lang.formatDate, lang, 'Y', str )
if good then
if ( code == "A" ) then
prefix = "http://openlibrary.org/authors/OL"
return result;
elseif ( code == "M" ) then
prefix = "http://openlibrary.org/books/OL"
elseif ( code == "W" ) then
prefix = "http://openlibrary.org/works/OL"
else
else
return '';
prefix = "http://openlibrary.org/OL"
cat = cat .. "[[Category:Pages with OL errors]]"
end
end
local text = externallinkid(frame, {link="Open Library",label="OL",prefix=prefix,id=id})
return text .. cat
end
end


function anchorid(label, args)
function reducetoinitials(first)
local P1 = trim(args[1]) or ""
local initials = {}
local P2 = trim(args[2]) or ""
for word in string.gmatch(first, "%S+") do
table.insert(initials, string.sub(word,1,1)) -- Vancouver format does not include full stops.
local P3 = trim(args[3]) or ""
local P4 = trim(args[4]) or ""
local P5 = trim(args[5]) or ""
local anchor = P1 .. P2 .. P3 .. P4 .. P5;
if anchor ~= '' then -- See bug description in Citation/CS1
anchor = mw.uri.anchorEncode( anchor );
end
end
return table.concat(initials) -- Vancouver format does not include spaces.
return label .. anchor
end
end


function refid(label, args)
function listpeople(control, people)
local sep = control.sep
local namesep = control.namesep
local format = control.format
local maximum = control.maximum
local text = {}
for i,person in ipairs(people) do
if (person.last ~= nil) then
local mask = person.mask
local one
if ( maximum ~= nil and i == maximum + 1 ) then
one = "et al."
elseif ( maximum ~= nil and i > maximum + 1 ) then
break
elseif (mask ~= nil) then
local n = tonumber(mask)
if (n ~= nil) then
one = string.rep("&mdash;",n)
else
one = mask
end
else
one = person.last
local first = person.first
if (first ~= nil) then
if ( "vanc" == format ) then first = reducetoinitials(first) end
one = one .. namesep .. first
end
if (person.link ~= nil) then one = "[[" .. person.link .. "|" .. one .. "]]" end
end
table.insert(text, one)
end
end
local result = table.concat(text, sep) -- construct list
if ( "scap" == format ) then result= z.mw.text.tag({name="span", contents=result, params={class="smallcaps", style="font-variant:small-caps;"}}) end -- if necessary wrap result in <span> tag to format in Small Caps
return result
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 p = args.p or ""
local pp = args.pp or ""
local pp = args.pp or ""
local loc = args.loc or ""
local loc = args.loc or ""
return anchorid(label, args) .. p .. pp .. loc
return anchorid(args) .. p .. pp .. loc
end
end


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


function crossref(frame, label, args)
function crossref(frame, args)
local config = frame.args -- the arguments passed BY the template, in the wikitext of the template itself
local config = frame.args -- the arguments passed BY the template, in the wikitext of the template itself
local LB = config.BracketLeft or ""
local LB = config.BracketLeft or ""
local RB = config.BracketRight or ""
local RB = config.BracketRight or ""
local anchor = args.ref or args.Ref or anchorid( label, args)
local anchor = args.ref or args.Ref or anchorid(args)
local text = name(args)
local text = name(args)
local loc = args.loc
local loc = args.loc
local page
local page = args.p or args.page
local pages = args.pp or args.pages
local pages = args.pp or args.pages
if pages == nil or pages == '' then
page = args.p or args.page;
end
if nil == loc then loc = "" else loc = " " .. loc end
if nil == loc then loc = "" else loc = " " .. loc end
if ( page ~= nil ) then
if ( page ~= nil ) then
local pagesep = config.PageSep or ", hlm.&nbsp;"
local pagesep = config.PageSep or ", p. "
loc = loc .. pagesep .. page
loc = loc .. pagesep .. page
end
end
if ( pages ~= nil ) then
if ( pages ~= nil ) then
local pagessep = config.PagesSep or ", hlm.&nbsp;"
local pagessep = config.PagesSep or ", pp. "
loc = loc .. pagessep .. pages
loc = loc .. pagessep .. pages
end
end
Baris 225: Baris 188:
local ps = args.Postscript or ""
local ps = args.Postscript or ""
return LB .. "[[" .. pagename .. "#" .. anchor .. "|" .. text .. "]]" .. loc .. RB .. ps
return LB .. "[[" .. pagename .. "#" .. anchor .. "|" .. text .. "]]" .. loc .. RB .. ps
end

function extractauthor(args, i)
local last = args["author" .. i .. "-last"] or args["author-last" .. i] or args["last" .. i] or args["surname" .. i] or args["Author" .. i] or args["author" .. i]
if ( last and "" < last ) then -- just in case someone passed in an empty parameter
return {
last = last,
first = args["author" .. i .. "-first"] or args["author-first" .. i] or args["first" .. i] or args["given" .. i],
link = args["author" .. i .. "-link"] or args["author-link" .. i] or args["author" .. i .. "link"] or args["authorlink" .. i],
mask = args["author" .. i .. "-mask"] or args["author-mask" .. i] or args["author" .. i .. "mask"] or args["authormask" .. i]
}
else
return nil
end
end

function extracteditor(args, i)
local last = args["editor" .. i .. "-last"] or args["editor-last" .. i] or args["EditorSurname" .. i] or args["Editor" .. i] or args["editor" .. i]
if ( last and "" < last ) then -- just in case someone passed in an empty parameter
return {
last = last,
first = args["editor" .. i .. "-first"] or args["editor-first" .. i] or args["EditorGiven" .. i],
link = args["editor" .. i .. "-link"] or args["editor-link" .. i] or args["editor" .. i .. "link"] or args["editorlink" .. i],
mask = args["editor" .. i .. "-mask"] or args["editor-mask" .. i] or args["editor" .. i .. "mask"] or args["editormask" .. i]
}
else
return nil
end
end

function citation0(frame, args)
local config = frame.args -- the arguments passed BY the template, in the wikitext of the template itself
local PPrefix = config.PPrefix or "p.&nbsp;"
local PPPrefix = config.PPPrefix or "pp.&nbsp;"
if ( nil ~= args.nopp ) then PPPrefix = "" PPrefix = "" end
-- Transfer unnumbered arguments to numbered arguments if necessary.
args["author1"] = args["author1"] or args["author"]
args["author1-last"] = args["author1-last"] or args["author-last"] or args["last"]
args["author1-first"] = args["author1-first"] or args["author-first"] or args ["first"]
args["author1-link"] = args["author1-link"] or args["author-link"]
args["author1-mask"] = args["author1-mask"] or args["author-mask"]
args["author1link"] = args["author1link"] or args["authorlink"]
args["editor1"] = args["editor1"] or args["editor"]
args["editor1-last"] = args["editor1-last"] or args["editor-last"]
args["editor1-first"] = args["editor1-first"] or args["editor-first"]
args["editor1-link"] = args["editor1-link"] or args["editor-link"]
args["editor1-mask"] = args["editor1-mask"] or args["editor-mask"]
args["editor1link"] = args["editor1link"] or args["editorlink"]

-- Pick out the relevant fields from the arguments. Different citation templates define different field names for the same underlying things.
local Authors = args.authors
local i
local a = {}
i = 1
while true do
a[i] = extractauthor(args, i)
if ( nil == a[i]) then break end
i = i + 1
end
local Coauthors = args.coauthors or args.coauthor
local Others = args.others
local EditorMask = args.editormask or args["editor-mask"]
local EditorFormat = args["editor-format"] or args.editorformat
local Editors = args.editors
local e = {}
i = 1
while true do
e[i] = extracteditor(args, i)
if ( nil == e[i]) then break end
i = i + 1
end
local Year = args.year
local PublicationDate = args.publicationdate
local OrigYear = args.origyear
local Date = args.date
local LayDate = args.laydate
local Title = args.title or args.encyclopaedia or args.encyclopedia or args.dictionary
local BookTitle = args.booktitle
local Conference = args.conference
local TransTitle = args.trans_title
local TitleNote = args.department
local TitleLink = args.titlelink or args.episodelink
local Chapter = args.chapter or args.article or args.entry
local ChapterLink = args.chapterlink
local TransChapter = args["trans-chapter"] or args.trans_chapter
local TitleType = args.type
local ArchiveURL = args["archive-url"] or args.archiveurl
local URL = args.url
local ChapterURL = args["chapter-url"] or args.chapterurl
local ConferenceURL = args["conference-url"] or args.conferenceurl
local Periodical = args.journal or args.newspaper or args.magazine or args.work or args.periodical or args.encyclopedia or args.encyclopaedia
local Series = args.series or args.version
local Volume = args.volume
local Issue = args.issue or args.number
local Position = nil
local Page = args.page
local Pages = args.pages
local PP = args.pp
local At = args.at
local Edition = args.edition
local PublicationPlace = args["publication-place"] or args.publicationplace or args.place or args.location
local Location = PublicationPlace
local PublisherName = args.publisher
local SubscriptionRequired = args.subscription
local Via = args.via
local AccessDate = args["access-date"] or args.accessdate
local ArchiveDate = args["archive-date"] or args.archivedate
local Agency = args.agency
local DeadURL = args.deadurl
local Language = args.language or args["dalam bahasa"]
local Format = args.format
local Ref = args.ref or args.Ref
local ARXIV = args.arxiv or args.ARXIV
local ASIN = args.asin or args.ASIN
local ASINTLD = args["ASIN-TLD"]
local BIBCODE = args.bibcode or args.BIBCODE
local DOI = args.doi or args.DOI
local DoiBroken = args.doi_inactivedate or args.doi_brokendate or args.DoiBroken
local ID = args.id or args.ID
local ISBN = args.isbn13 or args.isbn or args.ISBN
local ISSN = args.issn or args.ISSN
local JFM = args.jfm or args.JFM
local JSTOR = args.jstor or args.JSTOR
local LCCN = args.lccn or args.LCCN
local MR = args.mr or args.MR
local OCLC = args.oclc or args.OCLC
local OL = args.ol or args.OL
local OSTI = args.osti or args.OSTI
local PMC = args.pmc or args.PMC
local PMID = args.pmid or args.PMID
local RFC = args.rfc or args.RFC
local SSRN = args.ssrn or args.SSRN
local ZBL = args.zbl or args.ZBL
local Quote = args.quote or args.quotation
local PostScript = args.postscript
local LaySummary = args.laysummary
local LaySource = args.laysource
local Transcript = args.transcript
local TranscriptURL = args["transcript-url"] or args.transcripturl

-- At this point fields may be nil if they weren't specified in the template use. We can use that fact.
-- Account for the oddity that is {{cite conference}}, before generation of COinS data.
if ( BookTitle ) then
Chapter = Title
ChapterLink = TitleLink
TransChapter = TransTitle
Title = BookTitle
TitleLink = nil
TransTitle = nil
end
-- Account for the oddity that is {{cite episode}}, before generation of COinS data.
if config.CitationClass == "episode" then
local AirDate = args.airdate
local SeriesLink = args.serieslink
local Season = args.season
local SeriesNumber = args.seriesnumber or args.seriesno
local Network = args.network
local Station = args.station
local s = {}
if Issue ~= nil then table.insert(s, "episode " .. Issue) Issue = nil end
if Season ~= nil then table.insert(s, "season " .. Season) end
if SeriesNumber ~= nil then table.insert(s, "series " .. SeriesNumber) end
local n = {}
if Network ~= nil then table.insert(n, Network) end
if Station ~= nil then table.insert(n, Station) end
Date = Date or AirDate
Chapter = Title
ChapterLink = TitleLink
TransChapter = TransTitle
Title = Series
TitleLink = SeriesLink
TransTitle = nil
local Sep = args["series-separator"] or args["separator"] or ". "
Series = table.concat(s, Sep)
ID = table.concat(n, Sep)
end
-- These data form a COinS tag (see <http://ocoins.info/>) which allows automated tools to parse the citation information.
local OCinSdata = {} -- COinS metadata excluding id, bibcode, doi, etc.
local ctx_ver = "Z39.88-2004"
OCinSdata.rft_val_fmt = "info:ofi/fmt:kev:mtx:"
if ( nil ~= Periodical ) then
OCinSdata["rft.genre"] = "article"
OCinSdata["rft.jtitle"] = Periodical
if ( nil ~= Title ) then
OCinSdata["rft.atitle"] = Title
OCinSdata.rft_val_fmt "info:ofi/fmt:kev:mtx:journal"
end
end
if ( nil ~= Chapter ) then
OCinSdata["rft.genre"] = "bookitem"
OCinSdata["rft.btitle"] = Chapter
if ( nil ~= Title ) then OCinSdata["rft.atitle"] = Title end
else
OCinSdata["rft.genre"] = "book"
if ( nil ~= Title ) then
OCinSdata["rft.btitle"] = Title
OCinSdata.rft_val_fmt "info:ofi/fmt:kev:mtx:book"
end
end
OCinSdata["rft.place"] = PublicationPlace
OCinSdata["rft.date"] = Date or Year or PublicationDate
OCinSdata["rft.series"] = Series
OCinSdata["rft.volume"] = Volume
OCinSdata["rft.issue"] = Issue
OCinSdata["rft.pages"] = Page or Pages or At
OCinSdata["rft.edition"] = Edition
OCinSdata["rft.pub"] = PublisherName
OCinSdata["rft.isbn"] = ISBN
OCinSdata["rft.issn"] = ISSN
OCinSdata["rft.jfm"] = JFM
OCinSdata["rft.jstor"] = JSTOR
OCinSdata["rft.lccn"] = LCCN
OCinSdata["rft.mr"] = MR
OCinSdata.rft_id = URL or ChapterURL
if ( nil ~= a[1] and nil ~= a[1].last) then
local last = a[1].last
local first = a[1].first
OCinSdata["rft.aulast"] = last
if ( nil ~= first ) then
OCinSdata["rft.aufirst"] = first
OCinSdata["rft.au"] = last .. (args.NameSep or ", ") .. first
else
OCinSdata["rft.au"] = last
end
end
local OCinSids = {} -- COinS data only for id, bibcode, doi, pmid, etc.
OCinSids["info:arxiv"] = ARXIV
OCinSids["info:asin"] = ASIN
OCinSids["info:bibcode"] = BIBCODE
OCinSids["info:doi"] = DOI
OCinSids["info:oclcnum"] = OCLC
OCinSids["info:olnum"] = OL
OCinSids["info:osti"] = OSTI
OCinSids["info:pmc"] = PMC
OCinSids["info:pmid"] = PMID
OCinSids["info:rfc"] = RFC
OCinSids["info:ssrn"] = SSRN
OCinSids["info:zbl"] = ZBL
local OCinStitle = "ctx_ver=" .. ctx_ver -- such as "Z39.88-2004"
for name,value in pairs(OCinSids) do
OCinStitle = OCinStitle .. "&rft_id=" .. z.mw.url.encode(name .. "/" .. value)
end
for name,value in pairs(OCinSdata) do
OCinStitle = OCinStitle .. "&" .. name .. "=" .. z.mw.url.encode(value)
end
OCinStitle = OCinStitle .. "&rfr_id=info:sid/en.wikipedia.org:"
.. config.fullpagename -- end COinS data by page's non-encoded pagename

-- Now perform various field 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 ( Authors == nil ) then
local AuthorNameSep = args["author-name-separator"] or args["name-separator"] or "&#44; "
local AuthorSep = args["author-separator"] or args["separator"] or "&#59; "
local AuthorFormat = args["author-format"] or args.authorformat
local AuthorMaximum = tonumber(args["display-authors"] or args.displayauthors) or 8
local control = { sep = AuthorSep, namesep = AuthorNameSep, format = AuthorFormat, maximum = AuthorMaximum }
Authors = listpeople(control, a)
end
if ( Editors == nil ) then
local EditorNameSep = args["editor-name-separator"] or args["name-separator"] or "&#44; "
local EditorSep = args["editor-separator"] or args["separator"] or "&#59; "
local EditorFormat = args["editor-format"] or args.editorformat
local EditorMaximum = tonumber(args["display-editors"] or args.displayeditors) or 3
local control = { sep = EdithorSep, namesep = EditorNameSep, format = EditorFormat, maximum = EditorMaximum }
Editors = listpeople(control, e)
end
if ( Date == nil ) then
-- there's something hinky with how this adds dashes to perfectly-good free-standing years
--[[ Date = Year
if ( Date ~= nil ) then
local Month = args.month
if ( Month == nil ) then
local Began = args.began
local Ended = args.ended
if Began ~= nil and Ended ~= nil then
Month = Began .. "&ndash;" .. Ended
else
Month = "&ndash;"
end
end
Date = Month .. " " .. Date
local Day = args.day
if ( Day ~= nil ) then Date = Day .. " " .. Date end
end
]] -- so let's use the original version for now
Date = Year
if ( Date ~= nil ) then
local Month = args.month
if ( Month ~= nil ) then
Date = Month .. " " .. Date
local Day = args.day
if ( Day ~= nil ) then Date = Day .. " " .. Date end
end
end
end
if ( PublicationDate == Date or PublicationDate == Year ) then PublicationDate = nil end
if ( ArchiveURL and "" < ArchiveURL ) then
local temp = URL
URL = ArchiveURL
end
if ( TransTitle and "" < TransTitle ) then TransTitle = " [" .. TransTitle .. "]." else TransTitle = "" end
if ( TransChapter and "" < TransChapter ) then TransChapter = " [" .. TransChapter .. "]." else TransChapter = "" end
if ( Chapter and "" < Chapter ) then
if ( ChapterLink and "" < ChapterLink ) then Chapter = "[[" .. ChapterLink .. "|" .. Chapter .. "]]" end
if ( Periodical and "" < Periodical ) then
Chapter = "<i>" .. Chapter .. "</i>"
else
Chapter = "\"" .. Chapter .. "\""
end
Chapter = Chapter .. TransChapter
if ( ChapterLink == nil ) then
if ( ChapterURL and "" < ChapterURL ) then
Chapter = "[" .. ChapterURL .. " " .. Chapter .. "]"
elseif ( URL and "" < URL ) then
Chapter = "[" .. URL .. " " .. Chapter .. "]"
URL = nil
end
end
Chapter = Chapter .. ". " -- with end-space
else
Chapter = ""
end
if ( Title and "" < Title ) then
if ( TitleLink and "" < TitleLink ) then
Title = "[[" .. TitleLink .. "|" .. Title .. "]]" end
if ( Periodical and "" < Periodical ) then
Title = "\"" .. Title .. "\""
elseif ( config.CitationClass == "web"
or config.CitationClass == "news" ) then
Title = "\"" .. Title .. "\""
else
Title = "<i>" .. Title .. "</i>"
end
Title = Title .. TransTitle
if ( TitleLink == nil and URL and "" < URL ) then
Title = "[" .. URL .. " " .. Title .. "]"
URL = nil
end
Title = Title .. "." -- with end-dot
else
Title = ""
end
if ( Conference ~= nil ) then
if ( ConferenceURL ~= nil ) then
Conference = "[" .. ConferenceURL .. " " .. Conference .. "]"
end
Conference = " " .. Conference
else
Conference = ""
end
if ( nil ~= Position or nil ~= Page or nil ~= Pages ) then At = nil end
if ( nil == Position ) then
local Minutes = args.minutes
if ( nil ~= Minutes ) then
Position = " " .. Minutes .. " minutes in"
else
local Time = args.time
if ( nil ~= Time ) then
local TimeCaption = args.timecaption or "Event occurs at"
Position = " " .. TimeCaption .. " " .. Time
else
Position = ""
end
end
else
Position = " " .. Position
end
if ( nil == Page ) then
Page = ""
elseif ( Periodical ~= nil ) then
Page = ": " .. Page .. "."
else
Page = " " .. PPrefix .. Page .. "."
end
if ( nil == Pages ) then
Pages = ""
elseif ( Periodical ~= nil ) then
Pages = ": " .. Pages .. "."
else
if ( tonumber(Pages) ~= nil ) then
Pages = " " .. PPrefix .. Pages .. "."
else Pages = " " .. PPPrefix .. Pages .. "."
end
end
if ( At ~= nil ) then At = " " .. At .. "."
else At = "" end
if ( Coauthors ~= nil ) then
if ( Authors ~= nil ) then Coauthors = "; " .. Coauthors end
if ( Date == nil ) then Coauthors = Coauthors .. "." end
else Coauthors = "" end
if ( Others ~= nil ) then Others = " " .. Others .. "." else Others = "" end
if ( TitleType ~= nil ) then TitleType = " (" .. TitleType .. ")." else TitleType = "" end
if ( TitleNote ~= nil ) then TitleNote = " (" .. TitleNote .. ")." else TitleNote = "" end
if ( PublicationPlace ~= nil ) then PublicationPlace = PublicationPlace .. ": " else PublicationPlace = "" end
if ( Language ~= nil ) then Language = " (dalam bahasa " .. Language .. ")" else Language = "" end
if ( Edition ~= nil ) then Edition = " (" .. Edition .. " edition)" else Edition = "" end
if ( Volume ~= nil ) then Volume = " <b>" .. Volume .. "</b>" else Volume = "" end
if ( Issue ~= nil ) then Issue = " (" .. Issue .. ")" else Issue = "" end
if ( Series ~= nil ) then Series = " " .. Series .. "." else Series = "" end
if ( Format ~= nil ) then Format = " (" .. Format .. ")" else Format = "" end
if ( OrigYear ~= nil ) then OrigYear = " " .. OrigYear else OrigYear = "" end
if ( Agency ~= nil ) then Agency = " " .. Agency .. "." else Agency = "" end
if ( Date ~= nil ) then Date = Date else Date = "" end
if ( Via ~= nil ) then Via = " &mdash; via " .. Via else Via = "" end
if ( AccessDate ~= nil ) then AccessDate = " Retrieved " .. AccessDate .. "." else AccessDate = "" end
if ( SubscriptionRequired ~= nil ) then
SubscriptionRequired = " " .. z.mw.text.tag({name="span", contents="(subscription required)", params={style="font-size:0.95em; font-size: 90%; color: #555"}})
else
SubscriptionRequired = ""
end
if ( ARXIV ~= nil ) then ARXIV = " " .. externallinkid(frame, {label="arXiv",link="arXiv",prefix="http://arxiv.org/abs/",id=ARXIV,separator=":"}) else ARXIV = "" end
if ( ASIN ~= nil ) then ASIN = " " .. amazon(frame, ASIN, ASINTLD) else ASIN = "" end
if ( BIBCODE ~= nil ) then BIBCODE = " " .. externallinkid(frame, {label="Bibcode",link="Bibcode",prefix="http://adsabs.harvard.edu/abs/",id=BIBCODE,separator=":"}) else BIBCODE = "" end
if ( DOI ~= nil ) then DOI = " " .. doi(frame, DOI, DoiBroken) else DOI = "" end
if ( ID ~= nil ) then ID = " " .. ID else ID = "" end
if ( ISBN ~= nil ) then ISBN = " " .. internallinkid(frame, {label="ISBN",link="International Standard Book Number",prefix="Special:BookSources/",id=ISBN}) else ISBN = "" end
if ( ISSN ~= nil ) then ISSN = " " .. externallinkid(frame, {label="ISSN",link="International Standard Serial Number",prefix="//www.worldcat.org/issn/",id=ISSN}) else ISSN = "" end
if ( JFM ~= nil ) then JFM = " " .. externallinkid(frame, {label="JFM",link="Jahrbuch über die Fortschritte der Mathematik",prefix="http://www.zentralblatt-math.org/zmath/en/search/?format=complete&q=an:",id=JFM}) else JFM = "" end
if ( JSTOR ~= nil ) then JSTOR = " " .. externallinkid(frame, {label="JSTOR",link="JSTOR",prefix="http://www.jstor.org/stable/",id=JSTOR}) else JSTOR = "" end
if ( LCCN ~= nil ) then LCCN = " " .. externallinkid(frame, {label="LCCN",link="Library of Congress Control Number",prefix="http://lccn.loc.gov/",id=LCCN}) else LCCN = "" end
if ( MR ~= nil ) then MR = " " .. externallinkid(frame, {label="MR",link="Mathematical Reviews",prefix="http://www.ams.org/mathscinet-getitem?mr=",id=MR}) else MR = "" end
if ( OCLC ~= nil ) then OCLC = " " .. externallinkid(frame, {label="OCLC",link="Online Computer Library Center",prefix="//www.worldcat.org/oclc/",id=OCLC}) else OCLC = "" end
if ( OL ~= nil ) then OL = " " .. openlibrary(frame, OL) else OL = "" end
if ( OSTI ~= nil ) then OSTI = " " .. externallinkid(frame, {label="OSTI",link="Office of Scientific and Technical Information",prefix="http://www.osti.gov/energycitations/product.biblio.jsp?osti_id=",id=OSTI}) else OSTI = "" end
if ( PMC ~= nil ) then PMC = " " .. externallinkid(frame, {label="PMC",link="PubMed Central",prefix="//www.ncbi.nlm.nih.gov/pmc/articles/PMC",suffix="/?tool=pmcentrez",id=PMC}) else PMC = "" end
if ( PMID ~= nil ) then PMID = " " .. externallinkid(frame, {label="PMID",link="PubMed Identifier",prefix="//www.ncbi.nlm.nih.gov/pubmed/",id=PMID}) else PMID = "" end
if ( RFC ~= nil ) then RFC = " " .. externallinkid(frame, {label="RFC",link="Request for Comments",prefix="//tools.ietf.org/html/rfc",id=RFC}) else RFC = "" end
if ( SSRN ~= nil ) then SSRN = " " .. externallinkid(frame, {label="SSRN",link="Social Science Research Network",prefix="http://ssrn.com/abstract=",id=SSRN}) else SSRN = "" end
if ( URL ~= nil ) then URL = " " .. url(frame, URL) else URL = "" end
if ( ZBL ~= nil ) then ZBL = " " .. externallinkid(frame, {label="ZBL",link="Zentralblatt MATH",prefix="http://www.zentralblatt-math.org/zmath/en/search/?format=complete&q=an:",id=ZBL}) else ZBL = "" end
if ( Quote ~= nil ) then
Quote = " \"" .. Quote .. "\""
PostScript = ""
else
if ( PostScript ~= nil ) then PostScript = " " .. PostScript else PostScript = "" end
Quote = ""
end
local Archived
if ( nil ~= ArchiveURL ) then
if ( ArchiveDate ~= nil ) then ArchiveDate = " " .. ArchiveDate
else ArchiveDate = "" end
if ( "no" == DeadURL ) then
Archived = " [" .. ArchiveURL .. " Archived] from the original on" .. ArchiveDate .. "."
else
Archived = " Archived from [" .. args.url .. " the original] on" .. ArchiveDate .. "."
end
else
Archived = ""
end
local Lay
if ( nil ~= LaySummary ) then
if ( LayDate ~= nil ) then LayDate = " (" .. LayDate .. ")" else LayDate = "" end
if ( LaySource ~= nil ) then LaySource = " &ndash; <i>" .. LaySource .. "</i>" else LaySource = "" end
Lay = " [" .. LaySummary .. " lay summary]" .. LaySource .. LayDate
else
Lay = ""
end
if ( nil ~= Transcript ) then
if ( TranscriptURL ~= nil ) then Transcript = "[" .. TranscriptURL .. Transcript .. "]" end
else
Transcript = ""
end
local Publisher
if ( Periodical ~= nil ) then
if ( PublicationDate ~= nil ) then PublicationDate = " " .. PublicationDate else PublicationDate = "" end
if ( PublisherName ~= nil ) then
Publisher = " (" .. PublicationPlace .. PublisherName .. PublicationDate .. ")."
else
if (Location ~=nil) then Publisher= " (" .. Location .. ")."
else Publisher = "" end
end
Edition = ""
else
if ( PublicationDate ~= nil ) then PublicationDate = " (published " .. PublicationDate .. ")" else PublicationDate = "" end
if ( PublisherName ~= nil ) then Publisher = " " .. PublicationPlace .. PublisherName .. PublicationDate .. "." else Publisher = "" end
end
-- Several of the above rely upon detecting this as nil, so do it last.
if ( Periodical ~= nil ) then Periodical = " <i>" .. Periodical .. "</i>."
else Periodical = "" end
-- Piece all bits together at last. At this point, all should be 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 idcommon = ARXIV .. ASIN .. BIBCODE .. DOI .. ID .. ISBN .. JFM .. JSTOR .. LCCN .. MR .. OCLC .. OL .. OSTI .. PMC .. PMID .. RFC .. SSRN .. URL .. ZBL .. Archived .. AccessDate .. Via .. SubscriptionRequired .. Lay .. Quote .. PostScript
local tcommon = Title .. TitleType .. TitleNote .. Format .. Edition .. Language .. Conference .. Periodical .. Series .. Volume .. Issue .. Position .. Page .. Pages .. At
-- DEBUG: tcommon = "/Title="..Title .. "/TitleType="..TitleType .. "/TitleNote="..TitleNote .. "/Format="..Format .. "/Edition="..Edition .. "/Language="..Language .. "/Conference="..Conference .. "/Periodical="..Periodical .. "/Series="..Series .. "/Volume="..Volume .. "/Issue="..Issue .. "/Position="..Position .. Page .. Pages .. At

Date = Date .. OrigYear
local text
if ( "" ~= Authors ) then
if ( "" ~= Date ) then Date = " ("..Date.."). "
else Authors = Authors .. ". " end
if ( "" ~= Editors ) then Editors = " in " .. Editors .. "." end
text = Authors .. Coauthors .. " "..Date .. Chapter .. Others .. Editors .. tcommon .. Publisher .. Agency .. idcommon
elseif ( "" ~= Editors) then
Editors = Editors .. " (eds.)"
if ( "" ~= Date ) then Date = " (" .. Date .. "). "
else Editors = Editors .. ". " end
text = Editors .. Date .. Chapter .. tcommon .. Publisher .. Agency .. idcommon
else
if ( "" ~= Date ) then Date = " " .. Date .. "." end
text = Chapter .. tcommon .. Publisher .. Agency .. Date .. idcommon
end
-- Now enclose the whole thing in a <span/> element
if ( Year == nil ) then Year = "" end
local args = { class="citation " .. (config.CitationClass or "") }
if ( Ref ~= nil ) then
local id = Ref
if ( "harv" == Ref ) then
local names = {}
if ( "" ~= Authors ) then
for i,v in ipairs(a) do names[i] = v.last end
elseif ( "" ~= Editors ) then
for i,v in ipairs(e) do names[i] = v.last end
end
if ( names[1] == nil ) then
names[1] = Year
elseif ( names[2] == nil ) then
names[2] = Year
elseif ( names[3] == nil ) then
names[3] = Year
elseif ( names[4] == nil ) then
names[4] = Year
else
names[5] = Year
end
id = anchorid(names)
end
args.id = id;
end
text = z.mw.text.tag({name="span", contents=text, params=args})

local OCinS = z.mw.text.tag({name="span", contents="&nbsp;", params={class="Z3988",title=OCinStitle,style="display: none;"}})
return text .. OCinS
end
end


Baris 233: Baris 735:
if ( page ~= nil ) then
if ( page ~= nil ) then
local contents = ":" .. page
local contents = ":" .. page
p = createTag({name="sup",contents=contents,params={class="reference",style="white-space:nowrap;"}})
p = z.mw.text.tag({name="sup",contents=contents,params={class="reference",style="white-space:nowrap;"}})
end
end
return createTag({name="ref",contents="",params={name=name,group=group}}, frame) .. p
return z.mw.text.tag({name="ref",contents="",params={name=name,group=group}}, frame) .. p
end
end


Baris 266: Baris 768:
params.style = params.style .. " " .. z.wikitext.columnwidthstyle(width)
params.style = params.style .. " " .. z.wikitext.columnwidthstyle(width)
end
end
local references = createTag({name="references",contents=contents,params={group=group}}, frame)
local references = z.mw.text.tag({name="references",contents=contents,params={group=group}}, frame)
return createTag({name="div",contents=references,params=params})
return z.mw.text.tag({name="div",contents=references,params=params})
end
end


Baris 322: Baris 824:
local pframe = frame:getParent()
local pframe = frame:getParent()
local id = pframe.args.id or pframe.args[1] or ""
local id = pframe.args.id or pframe.args[1] or ""
return doi(id)
return doi(frame, id)
end
end


Baris 329: Baris 831:
local pframe = frame:getParent()
local pframe = frame:getParent()
local Name = pframe.args[1] or ""
local Name = pframe.args[1] or ""
return hideinprint("[[International Standard Serial Number|ISSN]]&nbsp;[http://www.worldcat.org/search?fq=x0:jrnl&q=n2:" .. Name .. " " .. Name .. "]")
return hideinprint(frame, "[[International Standard Serial Number|ISSN]]&nbsp;[http://www.worldcat.org/search?fq=x0:jrnl&q=n2:" .. Name .. " " .. Name .. "]")
end
end


Baris 335: Baris 837:
function z.SFNID(frame)
function z.SFNID(frame)
local pframe = frame:getParent()
local pframe = frame:getParent()
return anchorid('FOOTNOTE', pframe.args)
return anchorid(pframe.args)
end
end


Baris 342: Baris 844:
local pframe = frame:getParent()
local pframe = frame:getParent()
return crossref(frame, pframe.args)
return crossref(frame, pframe.args)
end

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


Baris 347: Baris 855:
function z.sfn(frame)
function z.sfn(frame)
local pframe = frame:getParent()
local pframe = frame:getParent()
pframe.args.Postscript = pframe.args.postscript or pframe.args.ps or ".";
local content = crossref(frame, pframe.args)
local args = { name = refid(pframe.args) }
return z.mw.text.tag({name = "ref", contents = content, params = args}, frame)
local content = crossref(frame, 'CITEREF', pframe.args)
local args = { name = refid( 'FOOTNOTE', pframe.args) }
return createTag({name = "ref", contents = content, params = args}, frame)
end
end


Baris 385: Baris 891:
params.class="reference"
params.class="reference"
if ( args.noid == nil or args.noid == "" ) then params.id = "ref_" .. P1 .. P3 end
if ( args.noid == nil or args.noid == "" ) then params.id = "ref_" .. P1 .. P3 end
return createTag({name="sup",contents=contents,params=params})
return z.mw.text.tag({name="sup",contents=contents,params=params})
end
end


Baris 398: Baris 904:
local contents
local contents
if arrow ~= "" then
if arrow ~= "" then
local sup_arrow = createTag({name="sup",contents=arrow,params={}})
local sup_arrow = z.mw.text.tag({name="sup",contents=arrow,params={}})
contents = "[[#ref_" .. id .. arrow .. "|<b>" .. sup_arrow .. "</b>]]" .. postscript
contents = "[[#ref_" .. id .. arrow .. "|<b>" .. sup_arrow .. "</b>]]" .. postscript
if "none" == arrow then arrow = "^" end -- Change this AFTER using it in the ID parameter and the contents.
if "none" == arrow then arrow = "^" end -- Change this AFTER using it in the ID parameter and the contents.
Baris 406: Baris 912:
local params = { class="citation wikicite" }
local params = { class="citation wikicite" }
if id ~= "" and ( args.noid == nil or args.noid == "" ) then
if id ~= "" and ( args.noid == nil or args.noid == "" ) then
params.id = mw.uri.anchorEncode("endnote_" .. id .. arrow)
params.id = z.mw.url.encodeAnchor("endnote_" .. id .. arrow)
end
end
return createTag({name="span",contents=contents,params=params})
return z.mw.text.tag({name="span",contents=contents,params=params})
end
end


Baris 440: Baris 946:
local config = frame.args -- the arguments passed BY the template, in the wikitext of the template itself
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 args = pframe.args -- the arguments passed TO the template, in the wikitext that instantiates the template
return createTag({name="ref",contents=(args[1] or ""),params={name=args.name,group=config.default_group}}, frame)
return z.mw.text.tag({name="ref",contents=(args[1] or ""),params={name=args.name,group=config.default_group}}, frame)
end
end


return z
return z
---------------------------------------------------------------------
--NOTES
--
-- NOTE A1: This Lua module was originally designed to handle a mix
-- of citation styles, crossing Vancouver style with Wikipedia's
-- local Citation Style 1 (CS1) from {Template:Citation/core}.
-- However, the conflicting positions of parameters, scattered
-- in twisted locations across this module, led to a separate
-- variation just to untangle the CS1 format of citations.
--
-- NOTE D2: The placement of dots and other separators between the
-- displayed parameters has been a continual headache, to keep
-- coordinated with the data in parentheses "(data)". There
-- has been a need to pre-check for the existence of related
-- options, to keep from putting double-dots ".." in some cases.
-- In particular, the omission of the "title=" parameter has led
-- to several cases of a spurious dot ". ." because the original
-- design had treated the title as a mandatory parameter.
--
------------------------------------------------------------------------
------------------------------------------------------------------------
--HISTORY:
--HISTORY:
Baris 471: Baris 958:
--19Oct2012 For pages, put &nbsp in "p.&nbsp;" etc.
--19Oct2012 For pages, put &nbsp in "p.&nbsp;" etc.
--19Oct2012 Enhanced "pages=" to detect lone page as "p." else "pp." prefix.
--19Oct2012 Enhanced "pages=" to detect lone page as "p." else "pp." prefix.
--19Oct2012 Fixed to show "." after Periodical name (work, newspaper...).
--19Oct2012 Fixed to show "." after Periodical name (work, newspaper, etc.).
--19Oct2012 Fixed web-link to have spaces "[... Archived] from the original".
--19Oct2012 Fixed web-link to have spaces "[... Archived] from the original".
--19Oct2012 Fixed to show ";" between authors & coauthors.
--19Oct2012 Fixed to show ";" between authors & coauthors.
--19Oct2012 Fixed to omit extra "." after coauthors.
--19Oct2012 Fixed to omit "." after coauthors.
--20Oct2012 Fixed COinS data to not urlencode all, as "ctx_ver=Z39.88-2004"
--20Oct2012 Fixed COinS data to not urlencode all, as "ctx_ver=Z39.88-2004"
--20Oct2012 Fixed COinS to not end as "&" but use lead "&rft...=" form.
--20Oct2012 Fixed COinS to not end as "&" but use lead "&rft...=" form.
Baris 481: Baris 968:
--05Nov2012 Add a span wrapper even when there is no Ref parameter
--05Nov2012 Add a span wrapper even when there is no Ref parameter
--15Feb2013 Added Agency for "agency=xx".
--15Feb2013 Added Agency for "agency=xx".
--19Feb2013 Put NOTES comments to explain module operation.
--19Feb2013 Copied as Module:Citation/CS1 to alter to match wp:CS1 form.
--19Feb2013 Changed OrigYear to use [__] for CS1 style.
--19Feb2013 Fixed to not show duplicate Publisher/Agency.
--19Feb2013 Moved page-number parameters to after final date.
--19Feb2013 Fixed to not put double-dots after title again.
--20Feb2013 Changed to omit dot "." if already ends with dot.
--20Feb2013 If class "journal" shows Publisher after Periodical/Series.
--20Feb2013 Shifted Format to after Language, and Others after Volume.
--20Feb2013 Set AccessDate + <span class="reference-accessdate">
--20Feb2013 Fixed url when deadurl=no.
--20Feb2013 Added sepc for separator character between parameters.
--20Feb2013 Put "OCLC" for "Online Computer Library Center".
--20Feb2013 Fix empty "authorlink=" as person.link ~= "".
--20Feb2013 Added space after AuthorSep & AuthorNameSep.
--21Feb2013 Added args.contributor (was missing parameter).
--21Feb2013 Fixed EditorSep (was misspelled "EdithorSep").
--21Feb2013 Set OCinSdata.rft_val_fmt = "info:ofi/fmt:kev:mtx:book"
--21Feb2013 Checked to omit blank codes (asin= | doi= etc.).
--21Feb2013 Set enddot to end line if not config.CitationClass "citation".
--21Feb2013 Fixed to show "issn=x" as the ISSN code.
--21Feb2013 Fixed to show "id=x" after Zbl code.
--21Feb2013 Changed to omit double-dot before date when already dot.
--21Feb2013 Order config.CitationClass "citation": Volume, Issue, Publisher.
--21Feb2013 Put warning "Bad DOI (expected "10."..)" in DOI result.
--21Feb2013 Automatically unbolded volume+comma when > 4 long.
--21Feb2013 Changed to allow lowercase "asin-tld".
--22Feb2013 Fixed ref=harv to extract Year from Date.
--22Feb2013 Set Harvard refer. span id if config.CitationClass "citation".
--22Feb2013 Fixed config.CitationClass "citation" as span class="citation".
--22Feb2013 Capitalized "Archived/Retrieved" only when sepc is dot ".".
--23Feb2013 Fixed author editor for "in" or "In" and put space after sepc.
--23Feb2013 Changed to omit dot in "et al." when sepc is "." separator.
--23Feb2013 Fixed "author1-first" to also get args.given or args.given1.
--23Feb2013 Fixed args.article to set Title, after Periodical is Title.
--23Feb2013 Fixed to allow blank Title (such as "contribution=mytitle").
--23Feb2013 Fixed double-dot ".." at end of Editors list
--26Feb2013 Moved "issue=" data to show before "page=".
--26Feb2013 Moved "type=" data to show after "format=".
--26Feb2013 For "pmc=" link, omitted suffix "/?tool=pmcentrez".
--27Feb2013 For coauthors, omitted extra separator after authors.
--27Feb2013 For date, allowed empty date to use month/day/year.
--27Feb2013 Fixed double-dot ".." at end of authors/coauthors list.
--27Feb2013 Reset editor suffix as ", ed." when date exists.
--27Feb2013 Removed duplicate display of "others=" data.
--27Feb2013 Removed parentheses "( )" around "department" TitleNote.
--05Mar2013 Moved Language to follow Periodical or Series.
--05Mar2013 Fixed Edition to follow Series or Volume.
--05Mar2013 Fixed class encyclopaedia to show article as quoted Chapter.
--05Mar2013 Fixed class encyclopaedia to show page as "pp." or "p.".
--07Mar2013 Changed class encyclopaedia to omit "( )" around publisher.
--07Mar2013 Fixed end double-dot by string.sub(idcommon,-1,-1) was "-1,1".
--13Mar2013 Removed enddot "." after "quote=" parameter.
--13Mar2013 Changed config.CitationClass "news" to use "p." page format.
--13Mar2013 Fixed missing "location=" when "web" or "encyclopaedia".
--14Mar2013 Fixed end double-dot after book/work title.
--14Mar2013 Fixed double-dot before "p." or "pp." page number.
--14Mar2013 Fixed config.CitationClass "book" to use p./pp. page.
--
--
--End
--End

Revisi per 7 Agustus 2014 21.07

--require "mw.text"

local z = {
    wikitext = require("Module:Wikitext"),
    mw = require("Module:Mw")
}

function hideinprint(content)
    return content
end

function onlyinprint(content)
    return ""
end

function nowiki(frame, content)
    return z.mw.text.tag({name="nowiki",contents=content,params={}}, frame)
end

function externallinkid(frame, args)
    local sep = args.separator or "&nbsp;"
    args.suffix = args.suffix or ""
    local t0 = onlyinprint(args.label .. sep .. args.id)
    local t1 = hideinprint("[[" .. args.link .. "|" .. args.label .. "]]" .. sep .. "[" .. args.prefix .. z.mw.url.encode(args.id) .. args.suffix .. " " .. nowiki(frame, args.id) .. "]")
    return t0 .. t1
end

function internallinkid(frame, args)
    local sep = args.separator or "&nbsp;"
    args.suffix = args.suffix or ""
    local t0 = onlyinprint(args.label .. sep .. args.id)
    local t1 = hideinprint("[[" .. args.link .. "|" .. args.label .. "]]" .. sep .. "[[" .. args.prefix .. args.id .. args.suffix .. "|" .. nowiki(frame, args.id) .. "]]")
    return t0 .. t1
end

function amazon(frame, id, domain)
    if ( nil == domain ) then 
        domain = "com"
    elseif ( "jp" == domain or "uk" == domain ) then
        domain = "co." .. domain
    end
    return externallinkid(frame, {link="Amazon Standard Identification Number",label="ASIN",prefix="//www.amazon."..domain.."/dp/",id=id})
end

function doi(frame, id, broken, inactive, nocat)
    local text = externallinkid(frame, {link="Digital object identifier",label="doi",prefix="http://dx.doi.org/",id=id,separator=":"})
    local cat = ""
    if ( inactive ~= nil ) then 
        inactive = " (inactive " .. inactive .. ")" 
        cat = cat .. "[[Category:Pages with DOIs inactive since " .. z.wikitext.canonicalcleanuptime(inactive) .. "]]"
    else 
        inactive = "" 
    end
    if ( string.sub(id,1,3) ~= "10." ) then
        cat = cat .. "[[Category:Pages with DOI errors]]"
    end
    if ( nocat and nocat ~= "" ) then cat = "" end
    return text .. inactive .. cat    
 end

function url(frame, id)
    local t0 = onlyinprint(id)
    local t1 = hideinprint("[" .. id .. " " .. nowiki(frame, id) .. "]")
    return t0 .. t1
end

function openlibrary(frame, id)
    local cat = ""
    local prefix = ""
    local code = id:sub(-1,-1)
    if ( code == "A" ) then
        prefix = "http://openlibrary.org/authors/OL"
    elseif ( code == "M" ) then
        prefix = "http://openlibrary.org/books/OL"
    elseif ( code == "W" ) then
        prefix = "http://openlibrary.org/works/OL"
    else
        prefix = "http://openlibrary.org/OL"
        cat = cat .. "[[Category:Pages with OL errors]]"
    end
    local text = externallinkid(frame, {link="Open Library",label="OL",prefix=prefix,id=id})
    return text .. cat
end

function reducetoinitials(first)
    local initials = {}
    for word in string.gmatch(first, "%S+") do
        table.insert(initials, string.sub(word,1,1)) -- Vancouver format does not include full stops.
    end
    return table.concat(initials) -- Vancouver format does not include spaces.
end

function listpeople(control, people)
    local sep = control.sep
    local namesep = control.namesep
    local format = control.format
    local maximum = control.maximum
    local text = {}
    for i,person in ipairs(people) do
        if (person.last ~= nil) then
            local mask = person.mask
            local one
            if ( maximum ~= nil and i == maximum + 1 ) then
                one = "et al."
            elseif ( maximum ~= nil and i > maximum + 1 ) then
                break
            elseif (mask ~= nil) then
                local n = tonumber(mask)
                if (n ~= nil) then
                    one = string.rep("&mdash;",n)
                else
                    one = mask
                end
            else
                one = person.last
                local first = person.first
                if (first ~= nil) then 
                    if ( "vanc" == format ) then first = reducetoinitials(first) end
                    one = one .. namesep .. first 
                end
                if (person.link ~= nil) then one = "[[" .. person.link .. "|" .. one .. "]]" end
            end
            table.insert(text, one)
        end
    end
    local result = table.concat(text, sep) -- construct list
    if ( "scap" == format ) then result= z.mw.text.tag({name="span", contents=result, params={class="smallcaps", style="font-variant:small-caps;"}}) end -- if necessary wrap result in <span> tag to format in Small Caps
    return result
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
    local page = args.p or args.page
    local pages = args.pp or args.pages
    if nil == loc then loc = "" else loc = " " .. loc end
    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 pagename = args.pagename or ""
    local ps = args.Postscript or ""
    return LB .. "[[" .. pagename .. "#" .. anchor .. "|" .. text .. "]]" .. loc .. RB .. ps
end

function extractauthor(args, i)
    local last = args["author" .. i .. "-last"] or args["author-last" .. i] or args["last" .. i] or args["surname" .. i] or args["Author" .. i] or args["author" .. i]
    if ( last and "" < last ) then -- just in case someone passed in an empty parameter
        return {
            last = last,
            first = args["author" .. i .. "-first"] or args["author-first" .. i] or args["first" .. i] or args["given" .. i],
            link = args["author" .. i .. "-link"] or args["author-link" .. i] or args["author" .. i .. "link"] or args["authorlink" .. i],
            mask = args["author" .. i .. "-mask"] or args["author-mask" .. i] or args["author" .. i .. "mask"] or args["authormask" .. i]
        }
    else
        return nil
    end
end

function extracteditor(args, i)
    local last = args["editor" .. i .. "-last"] or args["editor-last" .. i] or args["EditorSurname" .. i] or args["Editor" .. i] or args["editor" .. i]
    if ( last and "" < last ) then -- just in case someone passed in an empty parameter
        return {
            last = last,
            first = args["editor" .. i .. "-first"] or args["editor-first" .. i] or args["EditorGiven" .. i],
            link = args["editor" .. i .. "-link"] or args["editor-link" .. i] or args["editor" .. i .. "link"] or args["editorlink" .. i],
            mask = args["editor" .. i .. "-mask"] or args["editor-mask" .. i] or args["editor" .. i .. "mask"] or args["editormask" .. i]
        }
    else
        return nil
    end
end

function citation0(frame, args)
    local config = frame.args -- the arguments passed BY the template, in the wikitext of the template itself
    
    local PPrefix = config.PPrefix or "p.&nbsp;"
    local PPPrefix = config.PPPrefix or "pp.&nbsp;"
    if ( nil ~= args.nopp ) then PPPrefix = "" PPrefix = "" end
    
    -- Transfer unnumbered arguments to numbered arguments if necessary.
    args["author1"] = args["author1"] or args["author"]
    args["author1-last"] = args["author1-last"] or args["author-last"] or args["last"]
    args["author1-first"] = args["author1-first"] or args["author-first"] or args ["first"]
    args["author1-link"] = args["author1-link"] or args["author-link"]
    args["author1-mask"] = args["author1-mask"] or args["author-mask"]
    args["author1link"] = args["author1link"] or args["authorlink"]    
    args["editor1"] = args["editor1"] or args["editor"]
    args["editor1-last"] = args["editor1-last"] or args["editor-last"]
    args["editor1-first"] = args["editor1-first"] or args["editor-first"]
    args["editor1-link"] = args["editor1-link"] or args["editor-link"]
    args["editor1-mask"] = args["editor1-mask"] or args["editor-mask"]
    args["editor1link"] = args["editor1link"] or args["editorlink"]    

    -- Pick out the relevant fields from the arguments.  Different citation templates define different field names for the same underlying things.    
    local Authors = args.authors
    local i 
    local a = {}
    i = 1
    while true do
        a[i] = extractauthor(args, i)
        if ( nil == a[i]) then break end
        i = i + 1
    end
    local Coauthors = args.coauthors or args.coauthor 
    local Others = args.others 
    local EditorMask = args.editormask or args["editor-mask"]
    local EditorFormat = args["editor-format"] or args.editorformat
    local Editors = args.editors
    local e = {} 
    i = 1
    while true do
        e[i] = extracteditor(args, i)
        if ( nil == e[i]) then break end
        i = i + 1
    end
    local Year = args.year 
    local PublicationDate = args.publicationdate
    local OrigYear = args.origyear
    local Date = args.date
    local LayDate = args.laydate
    local Title = args.title or args.encyclopaedia or args.encyclopedia or args.dictionary
    local BookTitle = args.booktitle
    local Conference = args.conference
    local TransTitle = args.trans_title
    local TitleNote = args.department
    local TitleLink = args.titlelink or args.episodelink
    local Chapter = args.chapter or args.article or args.entry
    local ChapterLink = args.chapterlink
    local TransChapter = args["trans-chapter"] or args.trans_chapter
    local TitleType = args.type
    local ArchiveURL = args["archive-url"] or args.archiveurl
    local URL = args.url
    local ChapterURL = args["chapter-url"] or args.chapterurl
    local ConferenceURL = args["conference-url"] or args.conferenceurl
    local Periodical = args.journal or args.newspaper or args.magazine or args.work or args.periodical or args.encyclopedia or args.encyclopaedia
    local Series = args.series or args.version
    local Volume = args.volume
    local Issue = args.issue or args.number
    local Position = nil
    local Page = args.page
    local Pages = args.pages
    local PP = args.pp
    local At = args.at
    local Edition = args.edition
    local PublicationPlace = args["publication-place"] or args.publicationplace or args.place or args.location
    local Location = PublicationPlace
    local PublisherName = args.publisher
    local SubscriptionRequired = args.subscription
    local Via = args.via
    local AccessDate = args["access-date"] or args.accessdate
    local ArchiveDate = args["archive-date"] or args.archivedate
    local Agency = args.agency
    local DeadURL = args.deadurl
    local Language = args.language or args["dalam bahasa"]
    local Format = args.format
    local Ref = args.ref or args.Ref
    local ARXIV = args.arxiv or args.ARXIV
    local ASIN = args.asin or args.ASIN 
    local ASINTLD = args["ASIN-TLD"]
    local BIBCODE = args.bibcode or args.BIBCODE
    local DOI = args.doi or args.DOI
    local DoiBroken = args.doi_inactivedate or args.doi_brokendate or args.DoiBroken
    local ID = args.id or args.ID
    local ISBN = args.isbn13 or args.isbn or args.ISBN
    local ISSN = args.issn or args.ISSN
    local JFM = args.jfm or args.JFM
    local JSTOR = args.jstor or args.JSTOR
    local LCCN = args.lccn or args.LCCN
    local MR = args.mr or args.MR
    local OCLC = args.oclc or args.OCLC
    local OL = args.ol or args.OL
    local OSTI = args.osti or args.OSTI
    local PMC = args.pmc or args.PMC
    local PMID = args.pmid or args.PMID
    local RFC = args.rfc or args.RFC
    local SSRN = args.ssrn or args.SSRN
    local ZBL = args.zbl or args.ZBL
    local Quote = args.quote or args.quotation
    local PostScript = args.postscript
    local LaySummary = args.laysummary
    local LaySource = args.laysource
    local Transcript = args.transcript
    local TranscriptURL = args["transcript-url"] or args.transcripturl

    -- At this point fields may be nil if they weren't specified in the template use.  We can use that fact.
    
    -- Account for the oddity that is {{cite conference}}, before generation of COinS data.
    if ( BookTitle ) then
        Chapter = Title
        ChapterLink = TitleLink
        TransChapter = TransTitle
        Title = BookTitle
        TitleLink = nil
        TransTitle = nil
    end
    -- Account for the oddity that is {{cite episode}}, before generation of COinS data.
    if config.CitationClass == "episode" then
        local AirDate = args.airdate
        local SeriesLink = args.serieslink
        local Season = args.season
        local SeriesNumber = args.seriesnumber or args.seriesno
        local Network = args.network
        local Station = args.station
        local s = {}
        if Issue ~= nil then table.insert(s, "episode " .. Issue) Issue = nil end
        if Season ~= nil then table.insert(s, "season " .. Season) end
        if SeriesNumber ~= nil then table.insert(s, "series " .. SeriesNumber) end
        local n = {}
        if Network ~= nil then table.insert(n, Network) end
        if Station ~= nil then table.insert(n, Station) end
        Date = Date or AirDate
        Chapter = Title
        ChapterLink = TitleLink
        TransChapter = TransTitle
        Title = Series
        TitleLink = SeriesLink
        TransTitle = nil
        local Sep = args["series-separator"] or args["separator"] or ". "
        Series = table.concat(s, Sep)
        ID = table.concat(n, Sep)
    end
    
    -- These data form a COinS tag (see <http://ocoins.info/>) which allows automated tools to parse the citation information.
    local OCinSdata = {} -- COinS metadata excluding id, bibcode, doi, etc.
    local ctx_ver = "Z39.88-2004" 
    OCinSdata.rft_val_fmt = "info:ofi/fmt:kev:mtx:"
    if ( nil ~= Periodical ) then
        OCinSdata["rft.genre"] = "article"
        OCinSdata["rft.jtitle"] = Periodical
	    if ( nil ~= Title ) then 
               OCinSdata["rft.atitle"] = Title 
               OCinSdata.rft_val_fmt "info:ofi/fmt:kev:mtx:journal"
            end
    end
    if ( nil ~= Chapter ) then
        OCinSdata["rft.genre"] = "bookitem"
	    OCinSdata["rft.btitle"] = Chapter
	    if ( nil ~= Title ) then OCinSdata["rft.atitle"] = Title end
    else
        OCinSdata["rft.genre"] = "book"
	    if ( nil ~= Title ) then 
               OCinSdata["rft.btitle"] = Title 
               OCinSdata.rft_val_fmt "info:ofi/fmt:kev:mtx:book"
            end
    end
    OCinSdata["rft.place"] = PublicationPlace
    OCinSdata["rft.date"] = Date or Year or PublicationDate
    OCinSdata["rft.series"] = Series
    OCinSdata["rft.volume"] = Volume
    OCinSdata["rft.issue"] = Issue
    OCinSdata["rft.pages"] = Page or Pages or At
    OCinSdata["rft.edition"] = Edition
    OCinSdata["rft.pub"] = PublisherName
    OCinSdata["rft.isbn"] = ISBN
    OCinSdata["rft.issn"] = ISSN
    OCinSdata["rft.jfm"] = JFM
    OCinSdata["rft.jstor"] = JSTOR
    OCinSdata["rft.lccn"] = LCCN
    OCinSdata["rft.mr"] = MR
    OCinSdata.rft_id = URL or ChapterURL
    if ( nil ~= a[1] and nil ~= a[1].last) then
    local last = a[1].last
	local first = a[1].first
	OCinSdata["rft.aulast"] = last
        if ( nil ~= first ) then 
	    OCinSdata["rft.aufirst"] = first
	    OCinSdata["rft.au"] = last .. (args.NameSep or ", ") .. first
	else
	    OCinSdata["rft.au"] = last
        end
    end
    local OCinSids = {} -- COinS data only for id, bibcode, doi, pmid, etc.
    OCinSids["info:arxiv"] = ARXIV
    OCinSids["info:asin"] = ASIN
    OCinSids["info:bibcode"] = BIBCODE
    OCinSids["info:doi"] = DOI
    OCinSids["info:oclcnum"] = OCLC
    OCinSids["info:olnum"] = OL
    OCinSids["info:osti"] = OSTI
    OCinSids["info:pmc"] = PMC
    OCinSids["info:pmid"] = PMID
    OCinSids["info:rfc"] = RFC
    OCinSids["info:ssrn"] = SSRN
    OCinSids["info:zbl"] = ZBL
    local OCinStitle = "ctx_ver=" .. ctx_ver  -- such as "Z39.88-2004"
    for name,value in pairs(OCinSids) do
        OCinStitle = OCinStitle .. "&rft_id=" .. z.mw.url.encode(name .. "/" .. value)
    end
    for name,value in pairs(OCinSdata) do
        OCinStitle = OCinStitle .. "&" .. name .. "=" .. z.mw.url.encode(value)
    end
    OCinStitle = OCinStitle .. "&rfr_id=info:sid/en.wikipedia.org:"
       .. config.fullpagename  -- end COinS data by page's non-encoded pagename

    -- Now perform various field 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 ( Authors == nil ) then 
        local AuthorNameSep = args["author-name-separator"] or args["name-separator"] or "&#44; "
        local AuthorSep = args["author-separator"] or args["separator"] or "&#59; "
        local AuthorFormat = args["author-format"] or args.authorformat
        local AuthorMaximum = tonumber(args["display-authors"] or args.displayauthors) or 8
        local control = { sep = AuthorSep, namesep = AuthorNameSep, format = AuthorFormat, maximum = AuthorMaximum }
        Authors = listpeople(control, a) 
    end
    if ( Editors == nil ) then 
        local EditorNameSep = args["editor-name-separator"] or args["name-separator"] or "&#44; "
        local EditorSep = args["editor-separator"] or args["separator"] or "&#59; "
        local EditorFormat = args["editor-format"] or args.editorformat
        local EditorMaximum = tonumber(args["display-editors"] or args.displayeditors) or 3
        local control = { sep = EdithorSep, namesep = EditorNameSep, format = EditorFormat, maximum = EditorMaximum }
        Editors = listpeople(control, e) 
    end
    if ( Date == nil ) then
--   there's something hinky with how this adds dashes to perfectly-good free-standing years
--[[        Date = Year
        if ( Date ~= nil ) then
            local Month = args.month
            if ( Month == nil ) then 
                local Began = args.began
                local Ended = args.ended
                if Began ~= nil and Ended ~= nil then
                    Month = Began .. "&ndash;" .. Ended
                else
                    Month = "&ndash;"
                end
            end
            Date = Month .. " " .. Date
            local Day = args.day
            if ( Day ~= nil ) then Date = Day .. " " .. Date end
        end
]] -- so let's use the original version for now
        Date = Year
        if ( Date ~= nil ) then
            local Month = args.month
            if ( Month ~= nil ) then 
                Date = Month .. " " .. Date 
                local Day = args.day
                if ( Day ~= nil ) then Date = Day .. " " .. Date end
            end
        end
    end
    if ( PublicationDate == Date or PublicationDate == Year ) then PublicationDate = nil end
    if ( ArchiveURL and "" < ArchiveURL ) then
        local temp = URL
        URL = ArchiveURL
    end
    if ( TransTitle and "" < TransTitle ) then TransTitle = " [" .. TransTitle .. "]." else TransTitle = "" end
    if ( TransChapter and "" < TransChapter ) then TransChapter = " [" .. TransChapter .. "]." else TransChapter = "" end
    if ( Chapter and "" < Chapter ) then
        if ( ChapterLink and "" < ChapterLink ) then Chapter = "[[" .. ChapterLink .. "|" .. Chapter .. "]]" end
        if ( Periodical and "" < Periodical ) then
            Chapter = "<i>" .. Chapter .. "</i>"
        else
            Chapter = "\"" .. Chapter .. "\""
        end
        Chapter = Chapter .. TransChapter
        if ( ChapterLink == nil ) then
            if ( ChapterURL and "" < ChapterURL ) then
                Chapter = "[" .. ChapterURL .. " " .. Chapter .. "]"
            elseif ( URL and "" < URL ) then 
                Chapter = "[" .. URL .. " " .. Chapter .. "]"
                URL = nil
            end
        end
        Chapter = Chapter .. ". " -- with end-space
    else 
        Chapter = "" 
    end
    if ( Title and "" < Title ) then
        if ( TitleLink and "" < TitleLink ) then
            Title = "[[" .. TitleLink .. "|" .. Title .. "]]" end
        if ( Periodical and "" < Periodical ) then
            Title = "\"" .. Title .. "\""
        elseif ( config.CitationClass == "web"
              or config.CitationClass == "news" ) then
            Title = "\"" .. Title .. "\""
        else
            Title = "<i>" .. Title .. "</i>"
        end
        Title = Title .. TransTitle
        if ( TitleLink == nil and URL and "" < URL ) then 
            Title = "[" .. URL .. " " .. Title .. "]"
            URL = nil
        end
        Title = Title .. "." -- with end-dot
    else 
        Title = "" 
    end
    if ( Conference ~= nil ) then
        if ( ConferenceURL ~= nil ) then
            Conference = "[" .. ConferenceURL .. " " .. Conference .. "]"
        end
        Conference = " " .. Conference
    else 
        Conference = "" 
    end
    if ( nil ~= Position or nil ~= Page or nil ~= Pages ) then At = nil end
    if ( nil == Position ) then
        local Minutes = args.minutes
        if ( nil ~= Minutes ) then
            Position = " " .. Minutes .. " minutes in"
        else
            local Time = args.time
            if ( nil ~= Time ) then
                local TimeCaption = args.timecaption or "Event occurs at"
                Position = " " .. TimeCaption .. " " .. Time
            else
                Position = ""
            end
        end
    else
        Position = " " .. Position
    end
    if ( nil == Page ) then 
        Page = "" 
    elseif ( Periodical ~= nil ) then
        Page = ": " .. Page .. "."
    else
        Page = " " .. PPrefix .. Page .. "."
    end
    if ( nil == Pages ) then 
        Pages = "" 
    elseif ( Periodical ~= nil ) then
        Pages = ": " .. Pages .. "."
    else
        if ( tonumber(Pages) ~= nil ) then
          Pages = " " .. PPrefix .. Pages .. "."
        else Pages = " " .. PPPrefix .. Pages .. "."
        end
    end
    if ( At ~= nil ) then At = " " .. At .. "."
    else At = "" end
    if ( Coauthors ~= nil ) then
      if ( Authors ~= nil ) then Coauthors = "; " .. Coauthors end
      if ( Date == nil ) then Coauthors = Coauthors .. "." end
    else Coauthors = "" end
    if ( Others ~= nil ) then Others = " " .. Others .. "." else Others = "" end
    if ( TitleType ~= nil ) then TitleType = " (" .. TitleType .. ")." else TitleType = "" end
    if ( TitleNote ~= nil ) then TitleNote = " (" .. TitleNote .. ")." else TitleNote = "" end
    if ( PublicationPlace ~= nil ) then PublicationPlace = PublicationPlace .. ": " else PublicationPlace = "" end
    if ( Language ~= nil ) then Language = " (dalam bahasa " .. Language .. ")" else Language = "" end
    if ( Edition ~= nil ) then Edition = " (" .. Edition .. " edition)" else Edition = "" end
    if ( Volume ~= nil ) then Volume = " <b>" .. Volume .. "</b>" else Volume = "" end
    if ( Issue ~= nil ) then Issue = " (" .. Issue .. ")" else Issue = "" end
    if ( Series ~= nil ) then Series = " " .. Series .. "." else Series = "" end
    if ( Format ~= nil ) then Format = " (" .. Format .. ")" else Format = "" end
    if ( OrigYear ~= nil ) then OrigYear = " " .. OrigYear else OrigYear = "" end
    if ( Agency ~= nil ) then Agency = " " .. Agency .. "." else Agency = "" end
    if ( Date ~= nil ) then Date = Date else Date = "" end
    if ( Via ~= nil ) then Via = " &mdash; via " .. Via else Via = "" end
    if ( AccessDate ~= nil ) then AccessDate = " Retrieved " .. AccessDate .. "." else AccessDate = "" end
    if ( SubscriptionRequired ~= nil ) then
        SubscriptionRequired = " " .. z.mw.text.tag({name="span", contents="(subscription required)", params={style="font-size:0.95em; font-size: 90%; color: #555"}})
    else
        SubscriptionRequired = ""
    end
    if ( ARXIV ~= nil ) then ARXIV = " " .. externallinkid(frame, {label="arXiv",link="arXiv",prefix="http://arxiv.org/abs/",id=ARXIV,separator=":"}) else ARXIV = "" end
    if ( ASIN ~= nil ) then ASIN = " " .. amazon(frame, ASIN, ASINTLD) else ASIN = "" end
    if ( BIBCODE ~= nil ) then BIBCODE = " " .. externallinkid(frame, {label="Bibcode",link="Bibcode",prefix="http://adsabs.harvard.edu/abs/",id=BIBCODE,separator=":"}) else BIBCODE = "" end
    if ( DOI ~= nil ) then DOI = " " .. doi(frame, DOI, DoiBroken) else DOI = "" end
    if ( ID ~= nil ) then ID = " " .. ID else ID = "" end
    if ( ISBN ~= nil ) then ISBN = " " .. internallinkid(frame, {label="ISBN",link="International Standard Book Number",prefix="Special:BookSources/",id=ISBN}) else ISBN = "" end
    if ( ISSN ~= nil ) then ISSN = " " .. externallinkid(frame, {label="ISSN",link="International Standard Serial Number",prefix="//www.worldcat.org/issn/",id=ISSN}) else ISSN = "" end
    if ( JFM ~= nil ) then JFM = " " .. externallinkid(frame, {label="JFM",link="Jahrbuch über die Fortschritte der Mathematik",prefix="http://www.zentralblatt-math.org/zmath/en/search/?format=complete&q=an:",id=JFM}) else JFM = "" end
    if ( JSTOR ~= nil ) then JSTOR = " " .. externallinkid(frame, {label="JSTOR",link="JSTOR",prefix="http://www.jstor.org/stable/",id=JSTOR}) else JSTOR = "" end
    if ( LCCN ~= nil ) then LCCN = " " .. externallinkid(frame, {label="LCCN",link="Library of Congress Control Number",prefix="http://lccn.loc.gov/",id=LCCN}) else LCCN = "" end
    if ( MR ~= nil ) then MR = " " .. externallinkid(frame, {label="MR",link="Mathematical Reviews",prefix="http://www.ams.org/mathscinet-getitem?mr=",id=MR}) else MR = "" end
    if ( OCLC ~= nil ) then OCLC = " " .. externallinkid(frame, {label="OCLC",link="Online Computer Library Center",prefix="//www.worldcat.org/oclc/",id=OCLC}) else OCLC = "" end
    if ( OL ~= nil ) then OL = " " .. openlibrary(frame, OL) else OL = "" end
    if ( OSTI ~= nil ) then OSTI = " " .. externallinkid(frame, {label="OSTI",link="Office of Scientific and Technical Information",prefix="http://www.osti.gov/energycitations/product.biblio.jsp?osti_id=",id=OSTI}) else OSTI = "" end
    if ( PMC ~= nil ) then PMC = " " .. externallinkid(frame, {label="PMC",link="PubMed Central",prefix="//www.ncbi.nlm.nih.gov/pmc/articles/PMC",suffix="/?tool=pmcentrez",id=PMC}) else PMC = "" end
    if ( PMID ~= nil ) then PMID = " " .. externallinkid(frame, {label="PMID",link="PubMed Identifier",prefix="//www.ncbi.nlm.nih.gov/pubmed/",id=PMID}) else PMID = "" end
    if ( RFC ~= nil ) then RFC = " " .. externallinkid(frame, {label="RFC",link="Request for Comments",prefix="//tools.ietf.org/html/rfc",id=RFC}) else RFC = "" end
    if ( SSRN ~= nil ) then SSRN = " " .. externallinkid(frame, {label="SSRN",link="Social Science Research Network",prefix="http://ssrn.com/abstract=",id=SSRN}) else SSRN = "" end
    if ( URL ~= nil ) then URL = " " .. url(frame, URL) else URL = "" end
    if ( ZBL ~= nil ) then ZBL = " " .. externallinkid(frame, {label="ZBL",link="Zentralblatt MATH",prefix="http://www.zentralblatt-math.org/zmath/en/search/?format=complete&q=an:",id=ZBL}) else ZBL = "" end
    if ( Quote ~= nil ) then 
        Quote = " \"" .. Quote .. "\"" 
        PostScript = ""
    else 
        if ( PostScript ~= nil ) then PostScript = " " .. PostScript else PostScript = "" end
        Quote = "" 
    end
    local Archived
    if ( nil ~= ArchiveURL ) then
        if ( ArchiveDate ~= nil ) then ArchiveDate = " " .. ArchiveDate
        else ArchiveDate = "" end
        if ( "no" == DeadURL ) then
            Archived = " [" .. ArchiveURL .. "  Archived] from the original on" .. ArchiveDate .. "."
        else
            Archived = " Archived from [" .. args.url .. " the original] on" .. ArchiveDate .. "."
        end
    else
        Archived = ""
    end
    local Lay
    if ( nil ~= LaySummary ) then
        if ( LayDate ~= nil ) then LayDate = " (" .. LayDate .. ")" else LayDate = "" end
        if ( LaySource ~= nil ) then LaySource = " &ndash; <i>" .. LaySource .. "</i>" else LaySource = "" end
        Lay = " [" .. LaySummary .. " lay summary]" .. LaySource .. LayDate
    else
        Lay = ""
    end
    if ( nil ~= Transcript ) then
        if ( TranscriptURL ~= nil ) then Transcript = "[" .. TranscriptURL .. Transcript .. "]" end
    else
        Transcript = ""
    end
    local Publisher
    if ( Periodical ~= nil ) then
        if ( PublicationDate ~= nil ) then PublicationDate = " " .. PublicationDate else PublicationDate = "" end
        if ( PublisherName ~= nil ) then
            Publisher = " (" .. PublicationPlace .. PublisherName .. PublicationDate .. ")."
        else
            if (Location ~=nil) then Publisher= " (" .. Location .. ")."
            else Publisher = "" end
        end
        Edition = ""
    else
        if ( PublicationDate ~= nil ) then PublicationDate = " (published " .. PublicationDate .. ")" else PublicationDate = "" end
        if ( PublisherName ~= nil ) then Publisher = " " .. PublicationPlace .. PublisherName .. PublicationDate .. "." else Publisher = "" end
    end
    -- Several of the above rely upon detecting this as nil, so do it last.
    if ( Periodical ~= nil ) then Periodical = " <i>" .. Periodical .. "</i>."
    else Periodical = "" end
    
    -- Piece all bits together at last.  At this point, all should be 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 idcommon = ARXIV .. ASIN .. BIBCODE .. DOI .. ID .. ISBN .. JFM .. JSTOR .. LCCN .. MR .. OCLC .. OL .. OSTI .. PMC .. PMID .. RFC .. SSRN .. URL .. ZBL .. Archived .. AccessDate .. Via .. SubscriptionRequired .. Lay .. Quote .. PostScript
    local tcommon = Title .. TitleType .. TitleNote .. Format .. Edition .. Language .. Conference .. Periodical .. Series .. Volume .. Issue .. Position .. Page .. Pages .. At
    -- DEBUG: tcommon = "/Title="..Title .. "/TitleType="..TitleType .. "/TitleNote="..TitleNote .. "/Format="..Format .. "/Edition="..Edition .. "/Language="..Language .. "/Conference="..Conference .. "/Periodical="..Periodical .. "/Series="..Series .. "/Volume="..Volume .. "/Issue="..Issue .. "/Position="..Position .. Page .. Pages .. At

    Date = Date .. OrigYear
    local text
    if ( "" ~= Authors ) then
        if ( "" ~= Date ) then Date = " ("..Date.."). "
        else Authors = Authors .. ". " end
        if ( "" ~= Editors ) then Editors = " in " .. Editors .. "." end
        text = Authors .. Coauthors .. " "..Date .. Chapter .. Others .. Editors .. tcommon .. Publisher .. Agency .. idcommon
    elseif ( "" ~= Editors) then
        Editors = Editors .. " (eds.)"
        if ( "" ~= Date ) then Date = " (" .. Date .. "). "
        else Editors = Editors .. ". " end
        text = Editors .. Date .. Chapter .. tcommon .. Publisher .. Agency .. idcommon
    else
        if ( "" ~= Date ) then Date = " " .. Date .. "." end
        text = Chapter .. tcommon .. Publisher .. Agency .. Date .. idcommon
    end
    
    -- Now enclose the whole thing in a <span/> element
    if ( Year == nil ) then Year = "" end
    local args = { class="citation " .. (config.CitationClass or "") }
    if ( Ref ~= nil ) then 
        local id = Ref
        if ( "harv" == Ref ) then
            local names = {}
            if ( "" ~= Authors ) then
                for i,v in ipairs(a) do names[i] = v.last end
            elseif ( "" ~= Editors ) then
                for i,v in ipairs(e) do names[i] = v.last end
            end
            if ( names[1] == nil ) then 
                names[1] = Year 
            elseif ( names[2] == nil ) then 
                names[2] = Year 
            elseif ( names[3] == nil ) then
                names[3] = Year
            elseif ( names[4] == nil ) then
                names[4] = Year
            else
                names[5] = Year
            end
            id = anchorid(names)
        end
        args.id = id;
    end
    text = z.mw.text.tag({name="span", contents=text, params=args})

    local OCinS = z.mw.text.tag({name="span", contents="&nbsp;", params={class="Z3988",title=OCinStitle,style="display: none;"}}) 
        
    return text .. OCinS
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 = z.mw.text.tag({name="sup",contents=contents,params={class="reference",style="white-space:nowrap;"}}) 
    end
    return z.mw.text.tag({name="ref",contents="",params={name=name,group=group}}, frame) .. p
end

function reflist0(frame, config, args)
    local contents = args.refs or ""
    local liststyle = args.liststyle
    local count = args[1]
    local width = args.colwidth
    local group = args.group or config.default_group
    if ( nil == tonumber(count) and nil == width ) then 
        width = count
        count = nil
    end
    if ( nil == liststyle ) then
        if ( "upper-alpha" == group or "lower-alpha" == group or "upper-roman" == group or "lower-roman" == group or "upper-greek" == group or "lower-greek" == group ) then
            liststyle = group
        else
            liststyle = config.default_liststyle
        end
    end
    local params = {}
    params.class = "reflist"    
    params.style = z.wikitext.liststyle(liststyle)
    if ( nil ~= count ) then        
        params.class = params.class .. " references-column-count references-column-count-" .. count
        params.style = params.style .. " " .. z.wikitext.columncountstyle(count)
    end    
    if ( nil ~= width ) then
        params.class = params.class .. " references-column-width"
        params.style = params.style .. " " .. z.wikitext.columnwidthstyle(width)
    end
    local references = z.mw.text.tag({name="references",contents=contents,params={group=group}}, frame)
    return z.mw.text.tag({name="div",contents=references,params=params})
end

function refbegin0(frame, config, args)
    local liststyle = args.liststyle
    local indent = args.indent
    local indentsize = args.indentsize
    local count = args[1]
    local width = args.colwidth
    if ( nil == tonumber(count) and nil == width ) then 
        width = count
        count = nil
    end
    if ( nil == liststyle ) then
        if ( "upper-alpha" == group or "lower-alpha" == group or "upper-roman" == group or "lower-roman" == group or "upper-greek" == group or "lower-greek" == group ) then
            liststyle = group
        else
            liststyle = config.default_liststyle
        end
    end
    local params = {}
    params.class = "refbegin"
    params.style = z.wikitext.liststyle(liststyle)
    if ( nil ~= count ) then        
        params.class = params.class .. " references-column-count references-column-count-" .. count
        params.style = params.style .. " " .. z.wikitext.columncountstyle(count)
    end    
    if ( nil ~= width ) then
        params.class = params.class .. " references-column-width"
        params.style = params.style .. " " .. z.wikitext.columnwidthstyle(width)
    end
    local dlopen
    if ( nil ~= indent ) then
        dlopen = z.wikitext.OpenHTMLTag({name="dl",params={style="text-indent: -" .. (indentsize or "3.2") .. "em;"}})
    else
        dlopen = ""
    end
    return z.wikitext.OpenHTMLTag({name="div",params=params}) .. dlopen
end

function refend0(frame, config, args)
    local indent = args.indent
    local dlclose
    if ( nil ~= indent ) then
        dlclose = "</dl>"
    else
        dlclose = ""
    end
    return dlclose .. "</div>"
end

-- This is used by {{doi}} to create DOI links in the style used in citations.
function z.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 {{ISSN}} to create ISSN links in the style used in citations.
function z.ISSN(frame)
    local pframe = frame:getParent()
    local Name = pframe.args[1] or ""
    return hideinprint(frame, "[[International Standard Serial Number|ISSN]]&nbsp;[http://www.worldcat.org/search?fq=x0:jrnl&q=n2:" .. Name .. " " .. Name .. "]")
end

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

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

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

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

-- This is used by template {{r}}.
function z.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 {{ref label}}.
function z.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 = "[[#endnote_" .. P1 .. P3 .. "|&#91;" .. P2 .. "&#93;]]"
    local params = {}
    params.class="reference"
    if ( args.noid == nil or args.noid == "" ) then params.id = "ref_" .. P1 .. P3 end
    return z.mw.text.tag({name="sup",contents=contents,params=params})
end

-- This is used by template {{note label}}.
function z.notelabel(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 id = args[1] or ""
    local arrow = args[3] or ""
    local postscript = args[4] or ""
    local contents 
    if arrow ~= "" then
        local sup_arrow = z.mw.text.tag({name="sup",contents=arrow,params={}})
        contents = "[[#ref_" .. id .. arrow .. "|<b>" .. sup_arrow .. "</b>]]" .. postscript
        if "none" == arrow then arrow = "^" end -- Change this AFTER using it in the ID parameter and the contents.
    else
        contents = (args[2] or "") .. postscript
    end
    local params = { class="citation wikicite" }
    if id ~= "" and ( args.noid == nil or args.noid == "" ) then 
        params.id = z.mw.url.encodeAnchor("endnote_" .. id .. arrow)
    end
    return z.mw.text.tag({name="span",contents=contents,params=params})
end

-- This is used by templates {{reflist}} and {{notelist}}.
function z.reflist(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
    return reflist0(frame, config, args)
end

-- This is used by template {{refbegin}}.
function z.refbegin(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
    return refbegin0(frame, config, args)
end

-- This is used by template {{refend}}.
function z.refend(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
    return refend0(frame, config, args)
end

-- This is used by template {{efn}}.
function z.efn(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
    return z.mw.text.tag({name="ref",contents=(args[1] or ""),params={name=args.name,group=config.default_group}}, frame)
end

return z
------------------------------------------------------------------------
--HISTORY:
--18Oct2012 Fixed lead-space in Chapter by omitting " ".
--18Oct2012 Fixed lead-space in Chapter/Title as end " " of Authors/Date/...
--19Oct2012 Put HISTORY comments to log major changes (not typos).
--19Oct2012 Fixed extra dot ".." in Title by omitting at end of "tcommon=...".
--19Oct2012 For pages, put &nbsp in "p.&nbsp;" etc.
--19Oct2012 Enhanced "pages=" to detect lone page as "p." else "pp." prefix.
--19Oct2012 Fixed to show "." after Periodical name (work, newspaper, etc.).
--19Oct2012 Fixed web-link to have spaces "[...  Archived] from the original".
--19Oct2012 Fixed to show ";" between authors & coauthors.
--19Oct2012 Fixed to omit "." after coauthors.
--20Oct2012 Fixed COinS data to not urlencode all, as "ctx_ver=Z39.88-2004"
--20Oct2012 Fixed COinS to not end as "&" but use lead "&rft...=" form.
--20Oct2012 Fixed COinS to not url.encode page's "rfr_id=..." pagename.
--20Oct2012 Fixed COinS data when "web" to default to rft.genre "book".
--05Nov2012 Add a span wrapper even when there is no Ref parameter
--15Feb2013 Added Agency for "agency=xx".
--
--End