Module:Citation/CS1: Difference between revisions

    From Nonbinary Wiki
    m>Dragons flight
    (hmmm, I see how spaces are currently handled)
    m>Dragons flight
    (fix)
    Line 95: Line 95:
    end
    end


    function safejoin( tbl, duplicate_char )
    function safejoin( tbl, duplicate_char, space_char )
        --[[
        Note: we use string function here, rather than ustring functions.
       
        This has considerably faster performance and should work correctly as
        long as the duplicate_char is strict ASCII.  The strings
        in tbl may be ASCII or UTF8.
        ]]
       
         local str = '';
         local str = '';
         for _, value in ipairs( tbl ) do
         for _, value in ipairs( tbl ) do
             if value == nil then value = ''; end
             if value == nil then value = ''; end
           
            -- Trim spaces
            value = value:match( '^%s*(.-)%s*$' );
              
              
             if str == '' then
             if str == '' then
    Line 113: Line 108:
                 if value:sub(1,1) == duplicate_char then
                 if value:sub(1,1) == duplicate_char then
                     if str:sub(-1,-1) == duplicate_char then
                     if str:sub(-1,-1) == duplicate_char then
                         str = str .. value:sub(2);
                         str = str .. space_char .. value:sub(2);
                     elseif str:sub(-3,-1) == duplicate_char .. "''" then                   
                     elseif str:sub(-3,-1) == duplicate_char .. "''" then                   
                         str = str .. value:sub(2);
                         str = str .. space_char .. value:sub(2);
                     else
                     else
                         str = str .. value;
                         str = str .. space_char .. value;
                     end
                     end
                 else
                 else
                     str = str .. value;
                     str = str .. space_char .. value;
                 end
                 end
             end
             end
    Line 942: Line 937:
             end
             end
             text = Authors .. Date .. Chapter .. Editors .. tcommon
             text = Authors .. Date .. Chapter .. Editors .. tcommon
             safejoin( {text, pgtext, idcommon}, sepc, ' ' );
             text = safejoin( {text, pgtext, idcommon}, sepc, ' ' );
         elseif ( "" ~= Editors) then
         elseif ( "" ~= Editors) then
             if ( "" ~= Date ) then
             if ( "" ~= Date ) then
    Line 959: Line 954:
             end
             end
             text = Editors .. Date .. Chapter .. tcommon
             text = Editors .. Date .. Chapter .. tcommon
             text = safejoin( {text, pgtext, idcommon}, sepc, ' ' );
             text = safejoin( {text, pgtext, idcommon}, sepc );
         else
         else
             if ( "" ~= Date ) then
             if ( "" ~= Date ) then
    Line 968: Line 963:
             end -- endif ""~=Date
             end -- endif ""~=Date
             text = Chapter .. tcommon .. Date
             text = Chapter .. tcommon .. Date
             text = safejoin( {text, pgtext, idcommon}, sepc, ' ' );
             text = safejoin( {text, pgtext, idcommon}, sepc );
         end
         end
          
          

    Revision as of 20:53, 16 March 2013

    Documentation for this module may be created at Module:Citation/CS1/doc

    ---------------------------------------------------------------------
    -- Module:Citation/CS1 - Lua module for Citation Style 1 templates
    ---------------------------------------------------------------------
    --                               (see NOTES at bottom)
    --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 " "
        args.suffix = args.suffix or ""
        local url_string = args.id
        if args.encode == true or args.encode == nil then
            url_string = z.mw.url.encode( url_string );
        end
        
        local t0 = onlyinprint(args.label .. sep .. args.id)
        local t1 = hideinprint("[[" .. args.link .. "|" .. args.label .. "]]" .. sep .. "[" .. args.prefix .. url_string .. args.suffix .. " " .. nowiki(frame, args.id) .. "]")
        
        return t0 .. t1
    end
    
    function internallinkid(frame, args)
        local sep = args.separator or " "
        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, inactive, nocat)
        local cat = ""
        local text;
        if ( inactive ~= nil ) then 
            text = "[[Digital object identifier|doi]]:" .. id;
            cat = cat .. "[[Category:Pages with DOIs inactive since " .. selectyear(inactive) .. "]]"
            inactive = " (inactive " .. inactive .. ")" 
        else 
            text = externallinkid(frame, {link="Digital object identifier",label="doi",prefix="http://dx.doi.org/",id=id,separator=":"})
            inactive = "" 
        end
        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>'
        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 safeforurl( str )
        return str:gsub('%[','&#91;'):gsub('%]','&#93;'):gsub("\n", " ");
    end
    
    function hyphentodash( str )
        return str:gsub( '-', '–' );
    end
    
    function safeforitalics( str )
        if str == nil or str == '' then
            return str;
        else
            if str:sub(1,1) == "'" then str = "<span />" .. str; end
            if str:sub(-1,-1) == "'" then str = str .. "<span />"; end
            return str;
        end
    end
    
    function safejoin( tbl, duplicate_char, space_char )
        local str = '';
        for _, value in ipairs( tbl ) do
            if value == nil then value = ''; end
            
            -- Trim spaces
            value = value:match( '^%s*(.-)%s*$' ); 
            
            if str == '' then
                str = value;
            elseif value ~= '' then
                if value:sub(1,1) == duplicate_char then
                    if str:sub(-1,-1) == duplicate_char then
                        str = str .. space_char .. value:sub(2);
                    elseif str:sub(-3,-1) == duplicate_char .. "''" then                  
                        str = str .. space_char .. value:sub(2);
                    else
                        str = str .. space_char .. value;
                    end
                else
                    str = str .. space_char .. value;
                end
            end
        end
        return str;
    end  
    
    function selectyear( str )
        local lang = mw.getContentLanguage();
        local good, result;
        good, result = pcall( lang.formatDate, lang, 'Y', str )
        if good then 
            return result;
        else
            return '';
        end
    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;
        if sep:sub(-1,-1) ~= " " then sep = sep .. " " end
        local namesep = control.namesep
        local format = control.format
        local maximum = control.maximum
        local text = {}
        local etal = false;
        for i,person in ipairs(people) do
            if (person.last ~= nil or person.last ~= "") then
                local mask = person.mask
                local one
                if ( maximum ~= nil and i == maximum + 1 ) then
                    etal = true;
                    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 and person.link ~= "") then one = "[[" .. person.link .. "|" .. one .. "]]" end
                end
                table.insert(text, one)
            end
        end
        local count = #text;
        local result = table.concat(text, sep) -- construct list
        if etal then 
            local etal_text = "et al."
            if (sepc == ".") then etal_text = "et al" end
            result = result .. " " .. etal_text;
        end
        
        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, count
    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
        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 ( 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 = {};
        for k, v in pairs( frame.args ) do -- the arguments passed BY the template, in the wikitext of the template itself
            config[k] = v;
        end
    
        --------------------------------------------------- Get parameters    
        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 or args.authors
        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 or args.first1 or args.given or args.given1
        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 or args["publication-date"]
        local OrigYear = args.origyear
        local Date = args.date
        local LayDate = args.laydate
        ------------------------------------------------- Get title data
        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.contribution 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
        if ( config.CitationClass == "encyclopaedia" ) then
            if ( args.article and args.article ~= "") then
                if ( Title and Title ~= "") then Periodical = Title end
                Chapter = args.article
                TransChapter = TransTitle
                Title = ""            
            elseif ( Chapter == nil or Chapter == '' ) then
                Chapter = Title
                TransChapter = TransTitle
                Title = ""            
            end
            if ( Periodical and Periodical ~= "") then
                if Periodical == Title or Periodical == Chapter then Periodical = '' end
            end
        end
        local Series = args.series or args.version
        local Volume = args.volume
        local Issue = args.issue or args.number
        local Position = nil
        local Page
        local Pages = args.pages
        if Pages == nil or Pages == '' then
            Page = args.page  -- allows Pages to override Page
        else
            Pages = hyphentodash( Pages );
        end
    
        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["in"]
        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"] or 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
        local sepc = args.separator
    
        if ( config.CitationClass == "journal" ) then
            if (URL == nil or URL == "") then
              if (PMC ~= nil and PMC ~="")
                then URL="http://www.ncbi.nlm.nih.gov/pmc/articles/PMC" .. PMC
                else URL=""
              end
            end
        elseif ( config.CitationClass == "citation" ) then
            sepc = ","
            if ( Ref == nil ) then Ref = "harv" end
        end
        if ( sepc == nil ) then sepc = "." end 
        if ( DeadURL == nil ) then DeadURL = "yes" end
    
        -- 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:book"
        if ( nil ~= Periodical ) then
            OCinSdata.rft_val_fmt = "info:ofi/fmt:kev:mtx:journal"
            OCinSdata["rft.genre"] = "article"
            OCinSdata["rft.jtitle"] = Periodical
            if ( nil ~= Title ) then OCinSdata["rft.atitle"] = Title end
        end
        if ( nil ~= Chapter and "" ~= Chapter) then
            OCinSdata.rft_val_fmt = "info:ofi/fmt:kev:mtx:book"
            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 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;"
            AuthorNameSep = AuthorNameSep .. " "
            local AuthorSep = args["author-separator"] or args["separator"] or "&#59;"
            AuthorSep = AuthorSep .. " "
            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
        local EditorCount
        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 = EditorSep, namesep = EditorNameSep, format = EditorFormat, maximum = EditorMaximum }
            Editors, EditorCount = listpeople(control, e) 
        else
            EditorCount = 1;
        end
        if ( Date == nil or Date == "") 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 and Date ~="") then
                local Month = args.month
                if ( Month ~= nil and Month ~= "") then 
                    Date = Month .. " " .. Date 
                    local Day = args.day
                    if ( Day ~= nil ) then Date = Day .. " " .. Date end
                    else Month = ""
                end
                else Date = ""
            end
        end
        if ( PublicationDate == Date or PublicationDate == Year ) then PublicationDate = nil end
        if( (Date == nil or Date == "") and PublicationDate ~= nil ) then 
            Date = PublicationDate;
            PublicationDate = nil;
        end    
    
        -- Captures the value for Date prior to adding parens or other textual transformations
        local DateIn = Date
    
        if ( Format ~= nil and Format ~="" ) then
            Format = " (" .. Format .. ")" else Format = "" end
        if ( ArchiveURL and "" < ArchiveURL ) then
            if ( DeadURL ~= "no" ) then
              local temp = URL
              URL = ArchiveURL
            end
        end
        if ( TransTitle and "" < TransTitle ) then TransTitle = " [" .. TransTitle .. "&#93;" else TransTitle = "" end
        if ( TransChapter and "" < TransChapter ) then TransChapter = " [" .. TransChapter .. "&#93;" else TransChapter = "" end
        if ( Chapter and "" < Chapter ) then
            if ( ChapterLink and "" < ChapterLink ) then Chapter = "[[" .. ChapterLink .. "|" .. Chapter .. "]]" end
            if ( Periodical and "" < Periodical
                and config.CitationClass ~= "encyclopaedia"
            ) then
                Chapter = "''" .. safeforitalics(Chapter) .. "''"
            else
                Chapter = "\"" .. Chapter .. "\""
            end
            Chapter = Chapter .. TransChapter
            if ( ChapterLink == nil ) then
                if ( ChapterURL and "" < ChapterURL ) then
                    Chapter = "[" .. ChapterURL .. " " .. safeforurl( Chapter )  .. "]"
                elseif ( URL and "" < URL ) then 
                    Chapter = "[" .. URL .. " " .. safeforurl( Chapter ) .. "]" .. Format
                    URL = nil
                    Format = ""
                end
            end
            Chapter = Chapter .. sepc .. " " -- 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 = "''" .. safeforitalics(Title) .. "''"
            end
            Title = Title .. TransTitle
            if ( TitleLink == nil and URL and "" < URL ) then 
                Title = "[" .. URL .. " " .. safeforurl( Title ) .. "]" .. Format
                URL = nil
                Format = ''
            end
        else 
            Title = "" 
        end
        if ( Conference ~= nil and Conference ~="" ) then
            if ( ConferenceURL ~= nil ) then
                Conference = "[" .. ConferenceURL .. " " .. safeforurl( Conference ) .. "]"
            end
            Conference = " " .. Conference
        else 
            Conference = "" 
        end
        if ( nil ~= Position or nil ~= Page or nil ~= Pages ) then At = nil end
        if ( nil == Position and "" ~= 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 or "" == Page ) then 
            Page = "" 
        elseif ( Periodical ~= nil and Periodical ~= "" and
                 config.CitationClass ~= "encyclopaedia" and
                 config.CitationClass ~= "web" and
                 config.CitationClass ~= "book" and
                 config.CitationClass ~= "news") then
            Page = ": " .. Page
        else
            Page = sepc .." " .. PPrefix .. Page
        end
        if ( nil == Pages or "" == Pages) then 
            Pages = "" 
        elseif ( Periodical ~= nil and Periodical ~= "" and
                 config.CitationClass ~= "encyclopaedia" and
                 config.CitationClass ~= "web" and
                 config.CitationClass ~= "book" and
                 config.CitationClass ~= "news") then
            Pages = ": " .. Pages
        else
            if ( tonumber(Pages) ~= nil ) then
              Pages = sepc .." " .. PPrefix .. Pages
            else Pages = sepc .." " .. PPPrefix .. Pages
            end
        end
        if ( At ~= nil and At ~="") then At = sepc .. " " .. At
        else At = "" end
        if ( Coauthors == nil ) then Coauthors = "" end
        if ( Others ~= nil and Others ~="" ) then
            Others = sepc .. " " .. Others else Others = "" end
        if ( TitleType ~= nil and TitleType ~="" ) then
            TitleType = " (" .. TitleType .. ")" else TitleType = "" end
        if ( TitleNote ~= nil and TitleNote ~="" ) then
            TitleNote = sepc .. " " .. TitleNote else TitleNote = "" end
        if ( PublicationPlace ~= nil and PublicationPlace ~="" ) then
            PublicationPlace = PublicationPlace .. ": "
            else PublicationPlace = "" end
        if ( Language ~= nil and Language ~="" ) then
            Language = " (in " .. Language .. ")" else Language = "" end
        if ( Edition ~= nil and Edition ~="" ) then
            Edition = " (" .. Edition .. " ed.)" else Edition = "" end
        if ( Volume ~= nil and Volume ~="" )
        then
            if ( string.len(Volume) > 4 )
              then Volume = sepc .." " .. Volume
              else Volume = " <b>" .. Volume .. "</b>"
            end
        else Volume = "" end
        if ( Issue ~= nil and Issue ~="" ) then
            Issue = " (" .. Issue .. ")" else Issue = "" end
        if ( Series ~= nil and Series ~="" ) then
            Series = sepc .. " " .. Series else Series = "" end
        if ( OrigYear ~= nil and OrigYear ~="" ) then
            OrigYear = " [" .. OrigYear .. "]" else OrigYear = "" end
        if ( Agency ~= nil and Agency ~="" ) then
            Agency = sepc .. " " .. Agency else Agency = "" end
        ------------------------------------ totally unrelated data
        if ( Date ~= nil ) then Date = Date else Date = "" end
        if ( Via ~= nil and Via ~="" ) then
            Via = " &mdash; via " .. Via else Via = "" end
        if ( AccessDate ~= nil and AccessDate ~="" )
        then local retrv_text = " retrieved "
             if (sepc == ".") then retrv_text = " Retrieved " end
             AccessDate = '<span class="reference-accessdate">'
             .. sepc .. retrv_text .. AccessDate .. '</span>'
        else AccessDate = "" end
        if ( SubscriptionRequired ~= nil and
             SubscriptionRequired ~= "" ) then
            SubscriptionRequired = sepc .. " " .. 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 and ARXIV ~= "" ) then
            ARXIV = sepc .. " " .. externallinkid(frame, {label="arXiv",link="arXiv",prefix="http://arxiv.org/abs/",id=ARXIV,separator=":",encode=false}) else ARXIV = "" end
        if ( ASIN ~= nil and ASIN ~= "" ) then 
            ASIN = sepc .. " " .. amazon(frame, ASIN, ASINTLD) else ASIN = "" end
        if ( BIBCODE ~= nil and BIBCODE ~= "" ) then
            BIBCODE = sepc .. " " .. externallinkid(frame, {label="Bibcode",link="Bibcode",prefix="http://adsabs.harvard.edu/abs/",id=BIBCODE,separator=":"}) else BIBCODE = "" end
        if ( DOI ~= nil and DOI ~= "" ) then
           DOI = sepc .. " " .. doi(frame, DOI, DoiBroken) else DOI = "" end
        if ( ID ~= nil and ID ~="") then ID = sepc .." ".. ID else ID="" end
        if ( ISBN ~= nil and ISBN ~= "") then
            ISBN = sepc .. " " .. internallinkid(frame, {label="ISBN",link="International Standard Book Number",prefix="Special:BookSources/",id=ISBN}) else ISBN = "" end
        if ( ISSN ~= nil and ISSN ~="" ) then
            ISSN = sepc .. " " .. externallinkid(frame, {label="ISSN",link="International Standard Serial Number",prefix="//www.worldcat.org/issn/",id=ISSN,encode=false}) else ISSN = "" end
        if ( JFM ~= nil and JFM ~="" ) then
            JFM = sepc .." " .. 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 and JSTOR ~="") then
            JSTOR = sepc .." " .. externallinkid(frame, {label="JSTOR",link="JSTOR",prefix="http://www.jstor.org/stable/",id=JSTOR}) else JSTOR = "" end
        if ( LCCN ~= nil and LCCN ~="" ) then
            LCCN = sepc .." " .. externallinkid(frame, {label="LCCN",link="Library of Congress Control Number",prefix="http://lccn.loc.gov/",id=LCCN,encode=false}) else LCCN = "" end
        if ( MR ~= nil and MR ~="" ) then
            MR = sepc .." " .. externallinkid(frame, {label="MR",link="Mathematical Reviews",prefix="http://www.ams.org/mathscinet-getitem?mr=",id=MR}) else MR = "" end
        if ( OCLC ~= nil and OCLC ~="") then 
            OCLC = sepc .." " .. externallinkid(frame, {label="OCLC",link="OCLC",prefix="//www.worldcat.org/oclc/",id=OCLC}) else OCLC = "" end
        if ( OL ~= nil and OL ~="") then
            OL = sepc .." " .. openlibrary(frame, OL) else OL = "" end
        if ( OSTI ~= nil and OSTI ~="") then
            OSTI = sepc .." " .. 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 and PMC ~="") then
            PMC = sepc .." " .. externallinkid(frame, {label="PMC",link="PubMed Central",prefix="//www.ncbi.nlm.nih.gov/pmc/articles/PMC",suffix=" ",id=PMC}) else PMC = "" end
        if ( PMID ~= nil and PMID ~="") then
            PMID = sepc .." " .. externallinkid(frame, {label="PMID",link="PubMed Identifier",prefix="//www.ncbi.nlm.nih.gov/pubmed/",id=PMID,encode=false}) else PMID = "" end
        if ( RFC ~= nil and RFC ~="") then
            RFC = sepc .." " .. externallinkid(frame, {label="RFC",link="Request for Comments",prefix="//tools.ietf.org/html/rfc",id=RFC}) else RFC = "" end
        if ( SSRN ~= nil and SSRN ~="") then
            SSRN = sepc .." " .. externallinkid(frame, {label="SSRN",link="Social Science Research Network",prefix="http://ssrn.com/abstract=",id=SSRN}) else SSRN = "" end
        if ( URL ~= nil and URL ~="") then
           URL = " " .. url(frame, URL)
        else
           URL = ""
        end
        if ( ZBL ~= nil and ZBL ~="") then
            ZBL = sepc .." " .. 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 and Quote ~="" ) then 
            if Quote:sub(1,1) == '"' and Quote:sub(-1,-1) == '"' then
                Quote = Quote:sub(2,-2);
            end
            
            Quote = sepc .." \"" .. Quote .. "\"" 
            PostScript = ""
        else 
            if ( PostScript == nil) then PostScript = "" end
            Quote = "" 
        end
        local Archived
        if ( nil ~= ArchiveURL and "" ~= ArchiveURL ) then
            if ( ArchiveDate ~= nil and ArchiveDate ~="" ) then
                ArchiveDate = " " .. ArchiveDate
            else ArchiveDate = "" end
            local arch_text = " archived"
            if (sepc == ".") then arch_text = " Archived" end
            if ( "no" == DeadURL ) then
                Archived = sepc .. " [" .. ArchiveURL .. arch_text .. "] from the original on" .. ArchiveDate
            else
                Archived = sepc .. arch_text .. " from [" .. args.url .. " the original] on" .. ArchiveDate
            end
        else
            Archived = ""
        end
        local Lay
        if ( nil ~= LaySummary and "" ~= LaySummary ) then
            if ( LayDate ~= nil ) then LayDate = " (" .. LayDate .. ")" else LayDate = "" end
            if ( LaySource ~= nil ) then 
                LaySource = " &ndash; ''" .. safeforitalics(LaySource) .. "''" 
            else 
                LaySource = "" 
            end
            Lay = " [" .. LaySummary .. " lay summary]" .. LaySource .. LayDate
        else
            Lay = ""
        end
        if ( nil ~= Transcript and "" ~= Transcript ) then
            if ( TranscriptURL ~= nil ) then Transcript = "[" .. TranscriptURL .. Transcript .. "]" end
        else
            Transcript = ""
        end
        local Publisher = ""
        if ( Periodical and Periodical ~= "" and
             config.CitationClass ~= "encyclopaedia" and
             config.CitationClass ~= "web" ) then
            if ( PublicationDate and PublicationDate ~="" )
                then PublicationDate = " " .. PublicationDate
                else PublicationDate = "" end
            if ( PublisherName and PublisherName ~="" ) then
                Publisher = " (" .. PublicationPlace .. PublisherName .. PublicationDate .. ")"
            else
                if (Location ~= nil and Location ~= '') then Publisher= " (" .. Location .. ")"
                else Publisher = "" end
            end
        else
            if ( PublicationDate and PublicationDate ~="" ) then
                PublicationDate = " (published " .. PublicationDate .. ")"
                else PublicationDate = "" end
            if ( PublisherName and PublisherName ~="" ) then
                Publisher = sepc .. " " .. PublicationPlace .. PublisherName .. PublicationDate
            else
                if (Location ~= nil and Location ~= '') then Publisher= sepc .. " " .. Location
                else Publisher = "" end
            end
        end
        -- Several of the above rely upon detecting this as nil, so do it last.
        if ( Periodical ~= nil and Periodical ~="" ) then 
            if ( Title and Title ~= "") then 
                Periodical = sepc .. " ''" .. safeforitalics(Periodical) .. "''"
            else 
                Periodical = "''" .. safeforitalics(Periodical) .. "''"
            end
        else Periodical = "" end
    
        -- Piece all bits together at last.  Here, 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 tcommon
        if ( config.CitationClass == "journal" )
        then tcommon = Title .. TitleNote .. Format .. TitleType .. Conference .. Periodical .. Series .. Language .. Edition .. Publisher .. Agency .. Others .. Volume .. Issue .. Position
        elseif ( config.CitationClass == "citation" )
        then tcommon = Title .. TitleNote .. Format .. TitleType .. Conference .. Periodical .. Series .. Language .. Volume .. Issue .. Edition .. Publisher .. Agency .. Others .. Position
        else tcommon = Title .. TitleNote .. Series .. Format .. TitleType .. Conference .. Periodical .. Language .. Volume .. Issue .. Edition .. Publisher .. Agency .. Others .. Position
        end
        -- 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
    
        local idcommon = ARXIV .. ASIN .. BIBCODE .. DOI .. ISBN .. ISSN .. JFM .. JSTOR .. LCCN .. MR .. OCLC .. OL .. OSTI .. PMC .. PMID .. RFC .. SSRN .. URL .. ZBL .. ID .. Archived .. AccessDate .. Via .. SubscriptionRequired .. Lay .. Quote .. PostScript
        local enddot = ""
        if (Title ~= "") then enddot = "." end
        if (Periodical ~= "") then enddot = "." end
        if (Quote ~= "") then enddot = "" end
        if ( string.sub(idcommon,-1,-1) == sepc) then enddot = "" end
        if ( config.CitationClass == "citation") then enddot = "" end
        idcommon = idcommon .. enddot
    
        if ( config.CitationClass == "encyclopaedia" ) then
            Chapter = Chapter
        end
    
        local text
        local pgtext = Page .. Pages .. At
        if ( "" ~= Authors ) then
            if (Coauthors ~= "") 
              then Authors = Authors .. "; " .. Coauthors
            end
            if ( "" ~= Date )
              then Date = " ("..Date..")" .. OrigYear .. sepc .. " "
              else
                if ( string.sub(Authors,-1,-1) == sepc) --check end character
                  then Authors = Authors .. " "
                  else Authors = Authors .. sepc .. " "
                end
            end
            if ( "" ~= Editors) then
                local in_text = " in "
                if (sepc == '.') then in_text = " In " end
                if (string.sub(Editors,-1,-1) == sepc)
                    then Editors = in_text .. Editors .. " "
                    else Editors = in_text .. Editors .. sepc .. " "
                end
            end
            text = Authors .. Date .. Chapter .. Editors .. tcommon
            text = safejoin( {text, pgtext, idcommon}, sepc, ' ' );
        elseif ( "" ~= Editors) then
            if ( "" ~= Date ) then
                if EditorCount <= 1 then
                    Editors = Editors .. ", ed."
                else
                    Editors = Editors .. ", eds."
                end                
                Date = " (" .. Date ..")" .. OrigYear .. sepc .. " "
            else
                if EditorCount <= 1 then
                    Editors = Editors .. " (ed.)" .. sepc .. " "
                else
                    Editors = Editors .. " (eds.)" .. sepc .. " "
                end                
            end
            text = Editors .. Date .. Chapter .. tcommon
            text = safejoin( {text, pgtext, idcommon}, sepc );
        else
            if ( "" ~= Date ) then
                if ( string.sub(tcommon,-1,-1) ~= sepc )
                  then Date = sepc .." " .. Date
                  else Date = " " .. Date
                end
            end -- endif ""~=Date
            text = Chapter .. tcommon .. Date
            text = safejoin( {text, pgtext, idcommon}, sepc );
        end
        
        -- Now enclose the whole thing in a <span/> element
        if ( Year == nil ) then
            if ( DateIn ~= nil and DateIn ~= "" ) then 
                Year = selectyear( DateIn )
            elseif( PublicationDate ~= nil and PublicationDate ~= "" ) then
                Year = selectyear( PublicationDate )
            else
                Year = ""
            end        
        end
        local classname = "citation"
        if ( config.CitationClass ~= "citation" )
           then classname = "citation " .. (config.CitationClass or "") end
        local args = { class=classname }
        if ( Ref ~= nil ) then 
            local id = Ref
            if ( "harv" == Ref ) then
                local names = {} --table of last names & year
                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
        if ( text:sub(-4,-1) == ".''." ) then --when dot after title
            text = text:sub(1,-2) end --truncate end-dot
        text = z.mw.text.tag({name="span", contents=text, params=args})
    
        local empty_span = z.mw.text.tag( {name="span", contents="&nbsp;", params={style="display: none;"}} );
        
        -- Note: Using display: none on then COinS span breaks some clients.
        local OCinS = z.mw.text.tag({name="span", contents=empty_span, params={class="Z3988",title=OCinStitle }}) 
            
        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()
        
        local args = {};
        for k, v in pairs( pframe.args ) do
            args[k] = v;
        end    
        return citation0(frame, 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
    ---------------------------------------------------------------------
    --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:
    --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...).
    --19Oct2012 Fixed web-link to have spaces "[...  Archived] from the original".
    --19Oct2012 Fixed to show ";" between authors & coauthors.
    --19Oct2012 Fixed to omit extra "." 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".
    --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