Jump to content

Module:Citation/CS1: Difference between revisions

sync to sandbox, very large update addressing configuration, error handling, id handling, and others
m>Dragons flight
(sync to sandbox, fixes COinS author list)
m>Dragons flight
(sync to sandbox, very large update addressing configuration, error handling, id handling, and others)
Line 4: Line 4:
}
}


-- Include translation message hooks, ID and error handling configuration settings.
local cfg = mw.loadData( 'Module:Citation/CS1/Configuration' );
-- Contains a list of all recognized parameters
local whitelist = mw.loadData( 'Module:Citation/CS1/Whitelist' );
local whitelist = mw.loadData( 'Module:Citation/CS1/Whitelist' );


Line 25: Line 29:
end
end


-- Formats a hidden comment for error trapping not intended to be visible to readers
-- Formats a comment for error trapping
function hiddencomment( content )
function errorcomment( content, hidden )
     return '<span style="display: none;" class="citation-comment">' .. content .. '</span>';
     if hidden then
        return '<span style="display:none;font-size:100%" class="error citation-comment">' .. content .. '</span>';
    else
        return '<span style="font-size:100%" class="error">' .. content .. '</span>';
    end       
end
 
--[[
Sets an error condition and returns the appropriate error message.  The actual placement
of the error message in the output is the responsibility of the calling function.
]]
function seterror( error_id, args, raw )
    local error_state = cfg.error_conditions[ error_id ];
 
    if error_state == nil then
        error( cfg.message_list['undefined_error'] );
    end
   
    if error_state.category ~= nil and error_state.category ~= "" then
        table.insert( z.error_categories, error_state.category );
    end
   
    local message = error_state.message;
    if args ~= nil then
        for k, m in ipairs( args ) do
            message = message:gsub( "$" .. k .. "(%D)", m .. "%1" );
        end
    end
 
    message = wikiescape(message) .. " ([[" .. cfg.message_list['help page link'] ..
        "#" .. error_state.anchor .. "|" ..
        cfg.message_list['help page label'] .. "]])";
 
    if raw == true then
        return message, error_state.hidden;
    end
       
    return errorcomment( message, error_state.hidden );
end
end


Line 41: Line 82:
             ['}'] = '&#125;' } );
             ['}'] = '&#125;' } );
     return text;
     return text;
end
-- Create an HTML tag
function createTag(t, frame)
    local name = t.name or "!-- --"
    local content = t.contents or ""
    local attrs = {}
    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
--[[
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


Line 104: Line 94:
      
      
     return "[[" .. options.link .. "|" .. options.label .. "]]" .. sep .. "[" ..  
     return "[[" .. options.link .. "|" .. options.label .. "]]" .. sep .. "[" ..  
             options.prefix .. url_string .. options.suffix .. " " .. nowiki(options.id) .. "]"
             options.prefix .. url_string .. options.suffix .. " " .. mw.text.nowiki(options.id) .. "]"
end
end


Line 112: Line 102:
     options.suffix = options.suffix or ""
     options.suffix = options.suffix or ""
     return "[[" .. options.link .. "|" .. options.label .. "]]" .. sep .. "[[" ..  
     return "[[" .. options.link .. "|" .. options.label .. "]]" .. sep .. "[[" ..  
             options.prefix .. options.id .. options.suffix .. "|" .. nowiki(options.id) .. "]]"
             options.prefix .. options.id .. options.suffix .. "|" .. mw.text.nowiki(options.id) .. "]]"
end
end


Line 122: Line 112:
         domain = "co." .. domain
         domain = "co." .. domain
     end
     end
     return externallinkid({link="Amazon Standard Identification Number",
    local handler = cfg.id_handlers['ASIN'];
         label="ASIN",prefix="//www.amazon."..domain.."/dp/",id=id,encode=false})
     return externallinkid({link = handler.link,
         label=handler.label , prefix="//www.amazon."..domain.."/dp/",id=id,
        encode=handler.encode, separator = handler.separator})
end
end


Line 129: Line 121:
function doi(id, inactive)
function doi(id, inactive)
     local cat = ""
     local cat = ""
    local handler = cfg.id_handlers['DOI'];
      
      
     local text;
     local text;
     if ( inactive ~= nil ) then  
     if ( inactive ~= nil ) then  
         text = "[[Digital object identifier|doi]]:" .. id;
         text = "[[" .. handler.link .. "|" .. handler.label .. "]]:" .. id;
         table.insert( z.error_categories, "Pages with DOIs inactive since " .. selectyear(inactive) );         
         table.insert( z.error_categories, "Pages with DOIs inactive since " .. selectyear(inactive) );         
         inactive = " (inactive " .. inactive .. ")"  
         inactive = " (" .. cfg.message_list['inactive'] .. " " .. inactive .. ")"  
     else  
     else  
         text = externallinkid({link="Digital object identifier",label="doi",
         text = externallinkid({link = handler.link, label = handler.label,
             prefix="http://dx.doi.org/",id=id,separator=":"})
             prefix=handler.prefix,id=id,separator=handler.separator, encode=handler.encode})
         inactive = ""  
         inactive = ""  
     end
     end
     if ( string.sub(id,1,3) ~= "10." ) then
     if ( string.sub(id,1,3) ~= "10." ) then    
        table.insert( z.error_categories, "Pages with DOI errors" );       
         cat = seterror( 'bad_doi' );
         cat = ' <span class="error">Bad DOI (expected "10." prefix) in code number</span>'
     end
     end
     return text .. inactive .. cat  
     return text .. inactive .. cat  
  end
end
 
-- Formats an OpenLibrary link, and checks for associated errors.
function openlibrary(id)
    local code = id:sub(-1,-1)
    local handler = cfg.id_handlers['OL'];
    if ( code == "A" ) then
        return externallinkid({link=handler.link, label=handler.label,
            prefix="http://openlibrary.org/authors/OL",id=id, separator=handler.separator,
            encode = handler.encode})
    elseif ( code == "M" ) then
        return externallinkid({link=handler.link, label=handler.label,
            prefix="http://openlibrary.org/books/OL",id=id, separator=handler.separator,
            encode = handler.encode})
    elseif ( code == "W" ) then
        return externallinkid({link=handler.link, label=handler.label,
            prefix= "http://openlibrary.org/works/OL",id=id, separator=handler.separator,
            encode = handler.encode})
    else
        return externallinkid({link=handler.link, label=handler.label,
            prefix= "http://openlibrary.org/OL",id=id, separator=handler.separator,
            encode = handler.encode}) ..
            ' ' .. seterror( 'bad_ol' );
    end
end
 
-- Determines whether an ISBN string is valid
function checkisbn( isbn_str )
    isbn_str = isbn_str:gsub("[- ]", ""):upper();
    local len = isbn_str:len();
   
    if len ~= 10 and len ~= 13 then
        return false;
    end
    local temp = 0;
    if len == 10 then
        if isbn_str:match( "^%d*X?$" ) == nil then return false; end
        isbn_str = { isbn_str:byte(1, len) };
        for i, v in ipairs( isbn_str ) do
            if v == string.byte( "X" ) then
                temp = temp + 10*( 11 - i );
            else
                temp = temp + tonumber( string.char(v) )*(11-i);
            end
        end
        return temp % 11 == 0;
    else
        if isbn_str:match( "^%d*$" ) == nil then return false; end
        isbn_str = { isbn_str:byte(1, len) };
        for i, v in ipairs( isbn_str ) do
            temp = temp + (3 - 2*(i % 2)) * tonumber( string.char(v) );
        end
        return temp % 10 == 0;
    end
end


-- Escape sequences for content that will be used for URL descriptions
-- Escape sequences for content that will be used for URL descriptions
function safeforurl( str )
function safeforurl( str )
     if str:match( "%[%[.-%]%]" ) ~= nil then  
     if str:match( "%[%[.-%]%]" ) ~= nil then  
         table.insert( z.error_categories, "Pages with citations having wikilinks embedded in URL titles" );
         table.insert( z.message_tail, { seterror( 'wikilink_in_url', {}, true ) } );
        table.insert( z.message_tail, "Wikilink embedded in URL title" );
     end
     end
      
      
Line 281: Line 327:
             return "";
             return "";
         end
         end
    end
end
-- Formats an OpenLibrary link, and checks for associated errors.
function openlibrary(id)
    local code = id:sub(-1,-1)
    if ( code == "A" ) then
        return externallinkid({link="Open Library",label="OL",
            prefix="http://openlibrary.org/authors/OL",id=id})
    elseif ( code == "M" ) then
        return externallinkid({link="Open Library",label="OL",
            prefix="http://openlibrary.org/books/OL",id=id})
    elseif ( code == "W" ) then
        return externallinkid({link="Open Library",label="OL",
            prefix= "http://openlibrary.org/works/OL",id=id})
    else
        table.insert( z.error_categories, "Pages with OL errors" );
        return externallinkid({link="Open Library",label="OL",
            prefix= "http://openlibrary.org/OL",id=id}) ..
            ' <span class="error">Bad OL specified</span>';
     end
     end
end
end
Line 356: Line 382:
     local result = table.concat(text, sep) -- construct list
     local result = table.concat(text, sep) -- construct list
     if etal then  
     if etal then  
         local etal_text = "et al."
         local etal_text = cfg.message_list['et al'];
        if (sepc == ".") then etal_text = "et al" end
         result = result .. " " .. etal_text;
         result = result .. " " .. etal_text;
     end
     end
      
      
     -- if necessary wrap result in <span> tag to format in Small Caps
     -- if necessary wrap result in <span> tag to format in Small Caps
     if ( "scap" == format ) then result= createTag({name="span", contents=result,
     if ( "scap" == format ) then result =  
         params={class="smallcaps", style="font-variant:small-caps;"}}) end  
         '<span class="smallcaps" style="font-variant:small-caps">' .. result .. '</span>';
    end  
     return result, count
     return result, count
end
end
Line 389: Line 415:
     local i = 1;
     local i = 1;
     local last;
     local last;
   
     while true do
     while true do
         last = args["author" .. i .. "-last"] or args["author-last" .. i] or
         if i == 1 then
                 args["last" .. i] or args["surname" .. i] or args["Author" .. i] or args["author" .. i]
            last = selectone( args, {"author" .. i .. "-last", "author-last" .. i,
                "last" .. i, "surname" .. i, "Author" .. i, "author" .. i,
                "author-last", "last", "surname", "Author", "author", "authors"}, 'redundant_parameters' );
        else
            last = selectone( args, {"author" .. i .. "-last", "author-last" .. i,
                 "last" .. i, "surname" .. i, "Author" .. i, "author" .. i}, 'redundant_parameters' );
        end
         if ( last and "" < last ) then -- just in case someone passed in an empty parameter
         if ( last and "" < last ) then -- just in case someone passed in an empty parameter
             authors[i] = {
             if i == 1 then
                last = last,
                authors[i] = {
                first = args["author" .. i .. "-first"] or args["author-first" .. i] or
                    last = last,
                         args["first" .. i] or args["given" .. i],
                    first = selectone( args, {"author" .. i .. "-first", "author-first" .. i,
                link = args["author" .. i .. "-link"] or args["author-link" .. i] or
                        "first" .. i, "given" .. i, "author-first",
                         args["author" .. i .. "link"] or args["authorlink" .. i],
                        "first", "given"}, 'redundant_parameters' ),
                mask = args["author" .. i .. "-mask"] or args["author-mask" .. i] or
                    link = selectone( args, {"author" .. i .. "-link", "author-link" .. i,
                         args["author" .. i .. "mask"] or args["authormask" .. i]
                        "author" .. i .. "link", "authorlink" .. i, "author-link", 
             }
                        "authorlink"}, 'redundant_parameters' ),
                    mask = selectone( args, {"author" .. i .. "-mask", "author-mask" .. i,
                        "author" .. i .. "mask", "authormask" .. i, "author-mask",
                        "authormask" }, 'redundant_parameters' )
                }
            else
                authors[i] = {
                    last = last,
                    first = selectone( args, {"author" .. i .. "-first", "author-first" .. i,
                         "first" .. i, "given" .. i}, 'redundant_parameters' ),
                    link = selectone( args, {"author" .. i .. "-link", "author-link" .. i,
                         "author" .. i .. "link", "authorlink" .. i}, 'redundant_parameters' ),
                    mask = selectone( args, {"author" .. i .. "-mask", "author-mask" .. i,
                         "author" .. i .. "mask", "authormask" .. i}, 'redundant_parameters' )
                }
             end           
         else
         else
             break;
             break;
Line 418: Line 464:
      
      
     while true do
     while true do
         last = args["editor" .. i .. "-last"] or args["editor-last" .. i] or
         if i == 1 then
                 args["EditorSurname" .. i] or args["Editor" .. i] or args["editor" .. i]
            last = selectone( args, {"editor" .. i .. "-last", "editor-last" .. i,
                "EditorSurname" .. i, "Editor" .. i, "editor" .. i, "editor-last",
                "EditorSurname", "Editor", "editor", "editors"}, 'redundant_parameters' );
        else
            last = selectone( args, {"editor" .. i .. "-last", "editor-last" .. i,
                 "EditorSurname" .. i, "Editor" .. i, "editor" .. i}, 'redundant_parameters' );
        end       
         if ( last and "" < last ) then -- just in case someone passed in an empty parameter
         if ( last and "" < last ) then -- just in case someone passed in an empty parameter
             editors[i] = {
             if i == 1 then
                last = last,
                editors[i] = {
                first = args["editor" .. i .. "-first"] or args["editor-first" .. i] or args["EditorGiven" .. i],
                    last = last,
                link = args["editor" .. i .. "-link"] or args["editor-link" .. i] or
                    first = selectone( args, {"editor" .. i .. "-first",
                         args["editor" .. i .. "link"] or args["editorlink" .. i],
                        "editor-first" .. i, "EditorGiven" .. i, "editor-first",
                mask = args["editor" .. i .. "-mask"] or args["editor-mask" .. i] or
                        "EditorGiven"}, 'redundant_parameters' ),
                         args["editor" .. i .. "mask"] or args["editormask" .. i]
                    link = selectone( args, {"editor" .. i .. "-link", "editor-link" .. i,
             }
                        "editor" .. i .. "link", "editorlink" .. i, "editor-link",
                        "editorlink"}, 'redundant_parameters' ),
                    mask = selectone( args, {"editor" .. i .. "-mask", "editor-mask" .. i,
                        "editor" .. i .. "mask", "editormask" .. i, "editor-mask", 
                        "editormask"}, 'redundant_parameters' )
                }               
            else
                editors[i] = {
                    last = last,
                    first = selectone( args, {"editor" .. i .. "-first",
                        "editor-first" .. i, "EditorGiven" .. i}, 'redundant_parameters' ),
                    link = selectone( args, {"editor" .. i .. "-link", "editor-link" .. i,
                         "editor" .. i .. "link", "editorlink" .. i}, 'redundant_parameters' ),
                    mask = selectone( args, {"editor" .. i .. "-mask", "editor-mask" .. i,
                         "editor" .. i .. "mask", "editormask" .. i}, 'redundant_parameters' )
                }
             end
         else
         else
             break;
             break;
Line 435: Line 503:
     end
     end
     return editors;
     return editors;
end
-- Populates ID table from arguments using configuration settings
function extractids( args )
    local id_list = {};
   
    for k, v in pairs( cfg.id_handlers ) do   
        id_list[k] = selectone( args, v.parameters, 'redundant_parameters' );
    end
    return id_list;
end
-- Takes a table of IDs and turns it into a table of formatted ID outputs.
function buildidlist( id_list, options )
    local handler;
    local new_list = {};
   
    for k, v in pairs( id_list ) do
        handler = {};
       
        --Becasue cfg is read-only we have to copy it the hard way.
        for k2, v2 in pairs( cfg.id_handlers[k] ) do
            handler[k2] = v2;
        end
        handler['id'] = v;
       
        if handler.mode == 'external' then       
            table.insert( new_list, {handler.label, externallinkid( handler ) } );
        elseif handler.mode == 'internal' then
            table.insert( new_list, {handler.label, internallinkid( handler ) } );
        elseif handler.mode == 'manual' then
            if k == 'DOI' then
                table.insert( new_list, {handler.label, doi( v, options.DoiBroken ) } );
            elseif k == 'ASIN' then
                table.insert( new_list, {handler.label, amazon( v, options.ASINTLD ) } );
            elseif k == 'OL' then
                table.insert( new_list, {handler.label, openlibrary( v ) } );
            elseif k == 'ISBN' then
                local ISBN = internallinkid( handler );
                if not checkisbn( v ) then
                    ISBN = ISBN .. seterror( 'bad_isbn' );
                end
                table.insert( new_list, {handler.label, ISBN } );               
            else
                error( cfg.message_list['unknown_manual_ID'] );
            end           
        else
            error( cfg.message_list['unknown_ID_mode'] );
        end
    end
    function comp( a, b )
        return a[1] < b[1];
    end
    table.sort( new_list, comp );
    for k, v in ipairs( new_list ) do
        new_list[k] = v[2];
    end
   
    return new_list;
end
 
-- Chooses one matching parameter from a list of parameters to consider
-- Generates an error if more than one match is present.
function selectone( args, possible, error_condition )
    local value = nil;
    local selected = '';
    local error_list = {};
   
    for _, v in ipairs( possible ) do
        if args[v] ~= nil then
            if value ~= nil then
                table.insert( error_list, v );
            else
                value = args[v];
                selected = v;
            end
        end
    end
           
    if #error_list > 0 then
        local error_str = "";
        for _, k in ipairs( error_list ) do
            if error_str ~= "" then error_str = error_str .. ", " end
            error_str = error_str .. "<code>|" .. k .. "=</code>";
        end
        if #error_list > 1 then
            error_str = error_str .. ", and ";
        else
            error_str = error_str .. " and ";
        end
        error_str = error_str .. "<code>|" .. selected .. "=</code>";
        table.insert( z.message_tail, { seterror( error_condition, {error_str}, true ) } );
    end
           
    return value, selected;
end
end


Line 444: Line 610:
     -- Load Input Parameters
     -- Load Input Parameters


    local i
     local PPrefix = config.PPrefix or "p.&nbsp;"
     local PPrefix = config.PPrefix or "p.&nbsp;"
     local PPPrefix = config.PPPrefix or "pp.&nbsp;"
     local PPPrefix = config.PPPrefix or "pp.&nbsp;"
     if ( nil ~= args.nopp ) then PPPrefix = "" PPrefix = "" end
     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"] or args["authormask"]
    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"] or args["editormask"]
    args["editor1link"] = args["editor1link"] or args["editorlink"]   
     -- Pick out the relevant fields from the arguments.  Different citation templates
     -- Pick out the relevant fields from the arguments.  Different citation templates
     -- define different field names for the same underlying things.     
     -- define different field names for the same underlying things.     
     local Authors = args.authors
     local Authors = args.authors
    local i
     local a = extractauthors( args );
     local a = extractauthors( args );


     local Coauthors = args.coauthors or args.coauthor  
     local Coauthors = args.coauthors or args.coauthor  
     local Others = args.others  
     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 Editors = args.editors
     local e = extracteditors( args );
     local e = extracteditors( args );
Line 488: Line 637:
     local TitleNote = args.department
     local TitleNote = args.department
     local TitleLink = args.titlelink or args.episodelink
     local TitleLink = args.titlelink or args.episodelink
     local Chapter = args.chapter or args.contribution or args.entry
     local Chapter = selectone( args, {'chapter', 'contribution', 'entry' }, 'redundant_parameters' );
     local ChapterLink = args.chapterlink
     local ChapterLink = args.chapterlink
     local TransChapter = args["trans-chapter"] or args.trans_chapter
     local TransChapter = args["trans-chapter"] or args.trans_chapter
Line 496: Line 645:
     local ChapterURL = args["chapter-url"] or args.chapterurl or args["contribution-url"]
     local ChapterURL = args["chapter-url"] or args.chapterurl or args["contribution-url"]
     local ConferenceURL = args["conference-url"] or args.conferenceurl
     local ConferenceURL = args["conference-url"] or args.conferenceurl
     local Periodical = args.journal or args.newspaper or args.magazine or args.work
     local Periodical = selectone( args, {'journal', 'newspaper', 'magazine', 'work', 'website',
            or args.periodical or args.encyclopedia or args.encyclopaedia
        'periodical', 'encyclopedia', 'encyclopaedia'}, 'redundant_parameters' );
              
              
     if ( config.CitationClass == "encyclopaedia" ) then
     if ( config.CitationClass == "encyclopaedia" ) then
Line 518: Line 667:
         end
         end
     end
     end
     local Series = args.series or args.version
     local Series = selectone( args, {'series', 'version'}, 'redundant_parameters' );
     local Volume = args.volume
     local Volume = args.volume
     local Issue = args.issue or args.number
     local Issue = selectone( args, {'issue', 'number'}, 'redundant_parameters' );
     local Position = nil
     local Position = nil
     local Page = args.p or args.page
     local Page, Pages, At, page_type;
    local Pages = hyphentodash( args.pp or args.pages )
    local At = args.at
    local page_error = false;
      
      
     if Page ~= nil and Page ~= '' then
     Page, page_type = selectone( args, {'p', 'page', 'pp', 'pages', 'at'},
         if (Pages ~= nil and Pages ~= '') or (At ~= nil and At ~= '') then
         'extra_pages' );
            Pages = nil;
    if page_type == 'pp' or page_type == 'pages' then
            At = nil;
        Pages = hyphentodash( Page );
            page_error = true;
        Page = nil;
        end
     elseif page_type == 'at' then
     elseif Pages ~= nil and Pages ~= '' then
         At = Page;
         if At ~= nil and At ~= '' then
        Page = nil;
            At = nil;
            page_error = true;
        end
     end
     end
   
               
     local Edition = args.edition
     local Edition = args.edition
     local PublicationPlace = args["publication-place"] or args.publicationplace  
     local PublicationPlace = args["publication-place"] or args.publicationplace  
            or args.place or args.location
    local Place = selectone( args, {'place', 'location'}, 'redundant_parameters' );
     local Place = args.place or args.location
     if PublicationPlace == nil and Place ~= nil then
     if PublicationPlace == Place then Place = nil; end
        PublicationPlace = Place;
    end
     if PublicationPlace == Place then Place = nil end
      
      
     local PublisherName = args.publisher
     local PublisherName = args.publisher
Line 553: Line 698:
     local Agency = args.agency
     local Agency = args.agency
     local DeadURL = args.deadurl or "yes"          -- Only used is ArchiveURL is present.
     local DeadURL = args.deadurl or "yes"          -- Only used is ArchiveURL is present.
     local Language = args.language or args["in"]
     local Language = selectone( args, {'language', 'in'}, 'redundant_parameters' );
     local Format = args.format
     local Format = args.format
     local Ref = args.ref or args.Ref
     local Ref = args.ref or args.Ref
     local ARXIV = args.arxiv or args.ARXIV
 
     local ASIN = args.asin or args.ASIN
     local DoiBroken = args.doi_inactivedate or args.doi_brokendate or args.DoiBroken
     local ID = selectone( args, {'id', 'ID', 'docket'}, 'redundant_parameters' );
     local ASINTLD = args["ASIN-TLD"] or args["asin-tld"]
     local ASINTLD = args["ASIN-TLD"] or args["asin-tld"]
    local BIBCODE = args.bibcode or args.BIBCODE
 
    local DOI = args.doi or args.DOI
     local ID_list = extractids( args );
    local DoiBroken = args.doi_inactivedate or args.doi_brokendate or args.DoiBroken
      
    local ID = args.id or args.ID
     local Quote = selectone( args, {'quote', 'quotation'}, 'redundant_parameters' );
    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 or "."
     local PostScript = args.postscript or "."
     local LaySummary = args.laysummary
     local LaySummary = args.laysummary
Line 588: Line 719:
             args.notracking or args["no-tracking"] or "";
             args.notracking or args["no-tracking"] or "";


     if ( config.CitationClass == "journal" ) then
     if ( config.CitationClass == "journal" ) then      
         if (URL == nil or URL == "") then
         if (URL == nil or URL == "") then
          if (PMC ~= nil and PMC ~="")
            if (ID_list['PMC'] ~= nil) then
            then URL="http://www.ncbi.nlm.nih.gov/pmc/articles/PMC" .. PMC
                local Embargo = args.embargo or args.Embargo;
            else URL=nil
                if Embargo ~= nil then
          end
                    local lang = mw.getContentLanguage();
                    local good1, result1, good2, result2;
                    good1, result1 = pcall( lang.formatDate, lang, 'U', Embargo );
                    good2, result2 = pcall( lang.formatDate, lang, 'U' );
 
                    if good1 and good2 and tonumber( result1 ) < tonumber( result2 ) then  
                        URL = "http://www.ncbi.nlm.nih.gov/pmc/articles/PMC" .. ID_list['PMC'];
                    end
                else
                    URL = "http://www.ncbi.nlm.nih.gov/pmc/articles/PMC" .. ID_list['PMC'];         
                end
            end
         end
         end
     end
     end
Line 617: Line 759:
         local Station = args.station
         local Station = args.station
         local s = {}
         local s = {}
         if Issue ~= nil then table.insert(s, "episode " .. Issue) Issue = nil end
         if Issue ~= nil then table.insert(s, cfg.message_list["episode"] .. " " .. Issue) Issue = nil end
         if Season ~= nil then table.insert(s, "season " .. Season) end
         if Season ~= nil then table.insert(s, cfg.message_list["season"] .. " " .. Season) end
         if SeriesNumber ~= nil then table.insert(s, "series " .. SeriesNumber) end
         if SeriesNumber ~= nil then table.insert(s, cfg.message_list["series"] .. " " .. SeriesNumber) end
         local n = {}
         local n = {}
         if Network ~= nil then table.insert(n, Network) end
         if Network ~= nil then table.insert(n, Network) end
Line 663: Line 805:
     OCinSdata["rft.edition"] = Edition
     OCinSdata["rft.edition"] = Edition
     OCinSdata["rft.pub"] = PublisherName
     OCinSdata["rft.pub"] = PublisherName
     OCinSdata["rft.isbn"] = ISBN
      
     OCinSdata["rft.issn"] = ISSN
     for k, v in pairs( ID_list ) do
    OCinSdata["rft.jfm"] = JFM
        if string.sub( cfg.id_handlers[k].COinS or "info", 1, 4 ) ~= 'info' then
    OCinSdata["rft.jstor"] = JSTOR
            OCinSdata[ cfg.id_handlers[k].COinS ] = v;
     OCinSdata["rft.lccn"] = LCCN
        end
     OCinSdata["rft.mr"] = MR
     end
      
     OCinSdata.rft_id = URL or ChapterURL
     OCinSdata.rft_id = URL or ChapterURL


Line 692: Line 835:


     local OCinSids = {} -- COinS data only for id, bibcode, doi, pmid, etc.
     local OCinSids = {} -- COinS data only for id, bibcode, doi, pmid, etc.
     OCinSids["info:arxiv"] = ARXIV
     for k, v in pairs( ID_list ) do
    OCinSids["info:asin"] = ASIN
        if string.sub( cfg.id_handlers[k].COinS or "", 1, 4 ) == 'info' then
    OCinSids["info:bibcode"] = BIBCODE
            OCinSids[ cfg.id_handlers[k].COinS ] = v;
    OCinSids["info:doi"] = DOI
        end
    OCinSids["info:oclcnum"] = OCLC
     end
    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"
     local OCinStitle = "ctx_ver=" .. ctx_ver  -- such as "Z39.88-2004"
     for name,value in pairs(OCinSdata) do
     for name,value in pairs(OCinSdata) do
Line 716: Line 853:
      
      
     local this_page = mw.title.getCurrentTitle();
     local this_page = mw.title.getCurrentTitle();
     OCinStitle = OCinStitle .. "&rfr_id=info:sid/en.wikipedia.org:"
     OCinStitle = OCinStitle .. "&rfr_id=info:sid/" .. mw.site.server:match( "[^/]*$" ) .. ":"
       .. this_page.prefixedText  -- end COinS data by page's non-encoded pagename
       .. this_page.prefixedText  -- end COinS data by page's non-encoded pagename


Line 739: Line 876:
         if Maximum == nil and #a == 9 then  
         if Maximum == nil and #a == 9 then  
             Maximum = 8;
             Maximum = 8;
             table.insert( z.error_categories, 'Pages using citations with old-style implicit et al.' );
             table.insert( z.message_tail, { seterror('implict_etal_author', {}, true ) } );
            table.insert( z.message_tail, 'Citation uses old-style implicit et al. for authors' );
         elseif Maximum == nil then
         elseif Maximum == nil then
             Maximum = #a + 1;
             Maximum = #a + 1;
Line 768: Line 904:
         if Maximum == nil and #e == 4 then  
         if Maximum == nil and #e == 4 then  
             Maximum = 3;
             Maximum = 3;
             table.insert( z.error_categories, 'Pages using citations with old-style implicit et al.' );
             table.insert( z.message_tail, { seterror('implict_etal_editor', {}, true) } );
            table.insert( z.message_tail, 'Citation uses old-style implicit et al. for editors' );
         elseif Maximum == nil then
         elseif Maximum == nil then
             Maximum = #e + 1;
             Maximum = #e + 1;
Line 834: Line 969:
         -- Test if cite web is called without giving a URL
         -- Test if cite web is called without giving a URL
         if ( config.CitationClass == "web" ) then
         if ( config.CitationClass == "web" ) then
             table.insert( z.error_categories, 'Pages using web citations with no URL' );
             table.insert( z.message_tail, { seterror( 'cite_web_url', {}, true ) } );
            table.insert( z.message_tail, 'No URL on cite web' );
         end
         end


         -- Test if accessdate is given without giving a URL
         -- Test if accessdate is given without giving a URL
         if ( AccessDate ~= nil and AccessDate ~= '' ) then
         if ( AccessDate ~= nil and AccessDate ~= '' ) then
             table.insert( z.error_categories, 'Pages using citations with accessdate and no URL' );
             table.insert( z.message_tail, { seterror( 'accessdate_missing_url', {}, true ) } );
            table.insert( z.message_tail, 'Accessdate used without URL' );
             AccessDate = nil;
             AccessDate = nil;
         end       
         end       
Line 847: Line 980:
         -- Test if format is given without giving a URL
         -- Test if format is given without giving a URL
         if ( Format ~= nil and Format ~= '' ) then
         if ( Format ~= nil and Format ~= '' ) then
            table.insert( z.error_categories, 'Pages using citations with format and no URL' );
             Format = Format .. seterror( 'format_missing_url' );
             Format = Format .. hiddencomment( "File format specified without giving a URL" );
         end         
         end         
     end     
     end     
Line 859: Line 991:
             ( TransTitle == nil or TransTitle == "" ) and
             ( TransTitle == nil or TransTitle == "" ) and
             ( TransChapter == nil or TransChapter == "" ) then
             ( TransChapter == nil or TransChapter == "" ) then
         table.insert( z.error_categories, 'Pages with citations lacking titles' );
         table.insert( z.message_tail, { seterror( 'citation_missing_title', {}, true ) } );
        table.insert( z.message_tail, 'Citation has no title' );
     end
     end


Line 890: Line 1,021:
     end
     end
     if TransChapter ~= "" and Chapter == "" then
     if TransChapter ~= "" and Chapter == "" then
        table.insert( z.error_categories, 'Pages with citations using translated terms without the original' );
         TransChapter = TransChapter .. seterror( 'trans_missing_chapter' );
         TransChapter = TransChapter .. hiddencomment( "Translated title included without the original" );
     end
     end
     Chapter = Chapter .. TransChapter
     Chapter = Chapter .. TransChapter
Line 907: Line 1,037:
                 Format = ""
                 Format = ""
             end
             end
        elseif ChapterURL ~= nil and ChapterURL ~= "" then
            Chapter = Chapter .. " [" .. ChapterURL .. " " .. safeforurl( ChapterURL ) .. "]" ..
                seterror( 'bare_url_missing_title' );
         end
         end
         Chapter = Chapter .. sepc .. " " -- with end-space
         Chapter = Chapter .. sepc .. " " -- with end-space
     end
    elseif ChapterURL ~= nil and ChapterURL ~= "" then
        Chapter = " [" .. ChapterURL .. " " .. safeforurl( ChapterURL ) .. "]" ..
            seterror( 'bare_url_missing_title' ) .. sepc .. " ";
     end      
      
      
     -- Format main title.
     -- Format main title.
Line 929: Line 1,065:
     end     
     end     
     if TransTitle ~= "" and Title == "" then
     if TransTitle ~= "" and Title == "" then
        table.insert( z.error_categories, 'Pages with citations using translated terms without the original' );
         TransTitle = TransTitle .. seterror( 'trans_missing_title' );
         TransTitle = TransTitle .. hiddencomment( "Translated title included without the original" );
     end
     end
     Title = Title .. TransTitle
     Title = Title .. TransTitle
Line 943: Line 1,078:
     if ( Place ~= nil and Place ~= "" ) then
     if ( Place ~= nil and Place ~= "" ) then
         if sepc == '.' then
         if sepc == '.' then
             Place = " Written at " .. Place .. sepc .. " ";
             Place = " " .. cfg.message_list['written'] .. " " .. Place .. sepc .. " ";
         else
         else
             Place = " written at " .. Place .. sepc .. " ";
             Place = " " .. cfg.message_list['written']:lower() .. " " .. Place .. sepc .. " ";
         end             
         end             
     else
     else
Line 956: Line 1,091:
         end
         end
         Conference = " " .. Conference
         Conference = " " .. Conference
     else  
    elseif ConferenceURL ~= nil and ConferenceURL ~= "" then
        Conference = " [" .. ConferenceURL .. " " .. safeforurl( ConferenceURL ) .. "]" ..
            seterror( 'bare_url_missing_title' );
     else
         Conference = ""  
         Conference = ""  
     end
     end
Line 963: Line 1,101:
         local Minutes = args.minutes
         local Minutes = args.minutes
         if ( nil ~= Minutes ) then
         if ( nil ~= Minutes ) then
             Position = " " .. Minutes .. " minutes in"
             Position = " " .. Minutes .. " " .. cfg.message_list['minutes'];
         else
         else
             local Time = args.time
             local Time = args.time
             if ( nil ~= Time ) then
             if ( nil ~= Time ) then
                 local TimeCaption = args.timecaption or "Event occurs at"
                 local TimeCaption = args.timecaption  
                if TimeCaption == nil then
                    TimeCaption = cfg.message_list['event'];
                    if sepc ~= '.' then
                        TimeCaption = TimeCaption:lower();
                    end
                end               
                 Position = " " .. TimeCaption .. " " .. Time
                 Position = " " .. TimeCaption .. " " .. Time
             else
             else
Line 1,014: Line 1,158:
         TitleNote = sepc .. " " .. TitleNote else TitleNote = "" end
         TitleNote = sepc .. " " .. TitleNote else TitleNote = "" end
     if ( Language ~= nil and Language ~="" ) then
     if ( Language ~= nil and Language ~="" ) then
         Language = " (in " .. Language .. ")" else Language = "" end
         Language = " (" .. cfg.message_list['in'] .. " " .. Language .. ")" else Language = "" end
     if ( Edition ~= nil and Edition ~="" ) then
     if ( Edition ~= nil and Edition ~="" ) then
         Edition = " (" .. Edition .. " ed.)" else Edition = "" end
         Edition = " (" .. Edition .. " " .. cfg.message_list['edition'] .. ")" else Edition = "" end
     if ( Volume ~= nil and Volume ~="" )
     if ( Volume ~= nil and Volume ~="" )
     then
     then
Line 1,035: Line 1,179:
     if ( Date ~= nil ) then Date = Date else Date = "" end
     if ( Date ~= nil ) then Date = Date else Date = "" end
     if ( Via ~= nil and Via ~="" ) then
     if ( Via ~= nil and Via ~="" ) then
         Via = " &mdash; via " .. Via else Via = "" end
         Via = " &mdash; " .. cfg.message_list['via'] .. " " .. Via else Via = "" end
     if ( AccessDate ~= nil and AccessDate ~="" )
     if ( AccessDate ~= nil and AccessDate ~="" )
     then local retrv_text = " retrieved "
     then local retrv_text = " " .. cfg.message_list['retrieved'] .. " "
         if (sepc == ".") then retrv_text = " Retrieved " end
         if (sepc ~= ".") then retrv_text = retrv_text:lower() end
         AccessDate = '<span class="reference-accessdate">' .. sepc
         AccessDate = '<span class="reference-accessdate">' .. sepc
             .. retrv_text .. AccessDate .. '</span>'
             .. retrv_text .. AccessDate .. '</span>'
Line 1,044: Line 1,188:
     if ( SubscriptionRequired ~= nil and
     if ( SubscriptionRequired ~= nil and
         SubscriptionRequired ~= "" ) then
         SubscriptionRequired ~= "" ) then
         SubscriptionRequired = sepc .. " " .. createTag({name="span", contents="(subscription required)",
         SubscriptionRequired = sepc .. " " .. cfg.message_list['subscription'];
            params={style="font-size:0.95em; font-size: 90%; color: #555"}})
     else
     else
         SubscriptionRequired = ""
         SubscriptionRequired = ""
     end
     end
    if ( ARXIV ~= nil and ARXIV ~= "" ) then
        ARXIV = sepc .. " " .. externallinkid({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(ASIN, ASINTLD) else ASIN = "" end
    if ( BIBCODE ~= nil and BIBCODE ~= "" ) then
        BIBCODE = sepc .. " " .. externallinkid({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(DOI, DoiBroken) else DOI = "" end
     if ( ID ~= nil and ID ~="") then ID = sepc .." ".. ID else ID="" end
     if ( ID ~= nil and ID ~="") then ID = sepc .." ".. ID else ID="" end
    if ( ISBN ~= nil and ISBN ~= "") then
 
        ISBN = sepc .. " " .. internallinkid({label="ISBN",link="International Standard Book Number",
     ID_list = buildidlist( ID_list, {DoiBroken = DoiBroken, ASINTLD = ASINTLD} );
            prefix="Special:BookSources/",id=ISBN}) else ISBN = "" end
     if ( ISSN ~= nil and ISSN ~="" ) then
        ISSN = sepc .. " " .. externallinkid({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({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({label="JSTOR",link="JSTOR",
            prefix="http://www.jstor.org/stable/",id=JSTOR}) else JSTOR = "" end
    if ( LCCN ~= nil and LCCN ~="" ) then
        LCCN = sepc .." " .. externallinkid({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({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({label="OCLC",link="OCLC",
            prefix="//www.worldcat.org/oclc/",id=OCLC}) else OCLC = "" end
    if ( OL ~= nil and OL ~="") then
        OL = sepc .. " " .. openlibrary(OL) else OL = "" end   
    if ( OSTI ~= nil and OSTI ~="") then
        OSTI = sepc .." " .. externallinkid({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({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({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({label="RFC",link="Request for Comments",
            prefix="//tools.ietf.org/html/rfc",id=RFC,encode=false}) else RFC = "" end
    if ( SSRN ~= nil and SSRN ~="") then
        SSRN = sepc .." " .. externallinkid({label="SSRN",link="Social Science Research Network",
            prefix="http://ssrn.com/abstract=",id=SSRN}) else SSRN = "" end
    if ( ZBL ~= nil and ZBL ~="") then
        ZBL = sepc .." " .. externallinkid({label="Zbl",link="Zentralblatt MATH",
            prefix="http://www.zentralblatt-math.org/zmath/en/search/?format=complete&q=an:",id=ZBL}) else ZBL = "" end


     if ( URL ~= nil and URL ~="") then
     if ( URL ~= nil and URL ~="") then
         URL = " " .. "[" .. URL .. " " .. nowiki(URL) .. "]";
         URL = " " .. "[" .. URL .. " " .. mw.text.nowiki(URL) .. "]";
         table.insert( z.error_categories, "Pages with citations having bare URLs" );
         local error_text = seterror( 'bare_url_missing_title' );
         if config.CitationClass == "web" then
         if config.CitationClass == "web" then
             table.insert( z.error_categories, "Pages using web citations with no title" );
             URL = URL .. " " .. seterror( 'cite_web_title' );
            URL = URL .. " <span class='error'>No <code>title=</code> specified</span>"
         else
         else
             URL = URL .. hiddencomment("Bare URL needs a title");
             URL = URL .. error_text;
         end       
         end       
     else
     else
Line 1,132: Line 1,225:
             ArchiveDate = " " .. ArchiveDate
             ArchiveDate = " " .. ArchiveDate
         else  
         else  
             ArchiveDate = " <span class='error'>If you specify <code>archiveurl=</code>, " ..
             ArchiveDate = " " .. seterror('archive_missing_date') .. " "
                "you must also specify <code>archivedate=</code></span> "
            table.insert( z.error_categories, 'Pages with archiveurl citation errors' );
         end
         end
         local arch_text = " archived"
         local arch_text = " " .. cfg.message_list['archived'];
         if (sepc == ".") then arch_text = " Archived" end
         if (sepc ~= ".") then arch_text = arch_text:lower() end
         if ( "no" == DeadURL ) then
         if ( "no" == DeadURL ) then
             Archived = sepc .. " [" .. ArchiveURL .. arch_text .. "] from the original on" .. ArchiveDate
             Archived = sepc .. " [" .. ArchiveURL .. arch_text .. "] " ..
                cfg.message_list['from'] .. " " .. cfg.message_list['original'] .. " " ..
                cfg.message_list['on'] .. ArchiveDate
             if OriginalURL == nil or OriginalUrl == '' then
             if OriginalURL == nil or OriginalUrl == '' then
                table.insert( z.error_categories, 'Pages with archiveurl citation errors' );
                 Archived = Archived .. " " .. seterror('archive_missing_url_not_dead');                               
                 Archived = Archived .. " <span class='error'>If you specify <code>archiveurl=</code>" ..
                    " and <code>deadurl=no</code>, then you must also specify <code>url=</code></span>";                               
             end
             end
         else
         else
             if OriginalURL ~= nil and OriginalURL ~= '' then
             if OriginalURL ~= nil and OriginalURL ~= '' then
                 Archived = sepc .. arch_text .. " from [" .. OriginalURL .. " the original] on" .. ArchiveDate
                 Archived = sepc .. arch_text .. " " .. cfg.message_list['from'] .. " [" .. OriginalURL .. " " ..
                    cfg.message_list['original'] .. "] " .. cfg.message_list['on'] .. ArchiveDate
             else
             else
                 if config.CitationClass ~= 'web' then  
                 if config.CitationClass ~= 'web' then  
                     Archived = sepc .. arch_text .. " from <span class='error'>If you specify <code>archiveurl=</code>" ..
                     Archived = sepc .. arch_text .. " " .. cfg.message_list['from'] .. " " ..  
                        ", you must also specify <code>url=</code></span> on" .. ArchiveDate
                     seterror('archive_missing_url') .. " " .. cfg.message_list['on'] .. ArchiveDate
                     table.insert( z.error_categories, 'Pages with archiveurl citation errors' );
                 else
                 else
                     Archived = sepc .. arch_text .. " from the original on" .. ArchiveDate
                     Archived = sepc .. arch_text .. " " .. cfg.message_list['from'] ..
                        " " .. cfg.message_list['original'] .. " " ..
                        cfg.message_list['on'] .. ArchiveDate
                 end
                 end
             end                 
             end                 
Line 1,170: Line 1,263:
         end
         end
         if sepc == '.' then
         if sepc == '.' then
             Lay = sepc .. " [" .. LaySummary .. " Lay summary]" .. LaySource .. LayDate
             Lay = sepc .. " [" .. LaySummary .. " " .. cfg.message_list['lay summary'] .. "]" .. LaySource .. LayDate
         else
         else
             Lay = sepc .. " [" .. LaySummary .. " lay summary]" .. LaySource .. LayDate
             Lay = sepc .. " [" .. LaySummary .. " " .. cfg.message_list['lay summary']:lower() .. "]" .. LaySource .. LayDate
         end             
         end             
     else
     else
Line 1,179: Line 1,272:
     if ( nil ~= Transcript and "" ~= Transcript ) then
     if ( nil ~= Transcript and "" ~= Transcript ) then
         if ( TranscriptURL ~= nil ) then Transcript = "[" .. TranscriptURL .. Transcript .. "]" end
         if ( TranscriptURL ~= nil ) then Transcript = "[" .. TranscriptURL .. Transcript .. "]" end
    elseif TranscriptURL ~= nil and TranscriptURL ~= "" then
        Transcript = "[" .. TranscriptURL .. " " .. safeforurl( TranscriptURL ) .. "]" ..
            seterror( 'bare_url_missing_title' )       
     else
     else
         Transcript = ""
         Transcript = ""
Line 1,200: Line 1,296:
         if ( PublicationDate and PublicationDate ~="" ) then
         if ( PublicationDate and PublicationDate ~="" ) then
             if Publisher ~= '' then
             if Publisher ~= '' then
                 Publisher = Publisher .. ", published " .. PublicationDate;
                 Publisher = Publisher .. ", " .. cfg.message_list['published'] .. " " .. PublicationDate;
             else
             else
                 Publisher = PublicationDate;
                 Publisher = PublicationDate;
Line 1,210: Line 1,306:
     else
     else
         if ( PublicationDate and PublicationDate ~="" ) then
         if ( PublicationDate and PublicationDate ~="" ) then
             PublicationDate = " (published " .. PublicationDate .. ")"
             PublicationDate = " (" .. cfg.message_list['published'] .. " " .. PublicationDate .. ")"
         else  
         else  
             PublicationDate = ""
             PublicationDate = ""
Line 1,250: Line 1,346:
     end
     end
      
      
     local idcommon = safejoin( { ARXIV, ASIN, BIBCODE, DOI, ISBN, ISSN, JFM, JSTOR, LCCN, MR, OCLC, OL, OSTI,  
     if #ID_list > 0 then
         PMC, PMID, RFC, SSRN, URL, ZBL, ID, Archived, AccessDate, Via, SubscriptionRequired, Lay, Quote }, sepc );
        ID_list = safejoin( { sepc .. " ", table.concat( ID_list, sepc .. " " ), ID }, sepc );
    else
         ID_list = ID;
    end   
    local idcommon = safejoin( { ID_list, URL, Archived, AccessDate, Via, SubscriptionRequired, Lay, Quote }, sepc );


     local text
     local text
     local pgtext = Page .. Pages .. At
     local pgtext = Page .. Pages .. At
    if page_error then
        table.insert( z.error_categories, 'Pages with citations using conflicting page specifications' );
        pgtext = pgtext .. hiddencomment('Bad page specification here');
    end
      
      
     if ( "" ~= Authors ) then
     if ( "" ~= Authors ) then
Line 1,285: Line 1,381:
         if ( "" ~= Date ) then
         if ( "" ~= Date ) then
             if EditorCount <= 1 then
             if EditorCount <= 1 then
                 Editors = Editors .. ", ed."
                 Editors = Editors .. ", " .. cfg.message_list['editor'];
             else
             else
                 Editors = Editors .. ", eds."
                 Editors = Editors .. ", " .. cfg.message_list['editors'];
             end
             end
             Date = " (" .. Date ..")" .. OrigYear .. sepc .. " "
             Date = " (" .. Date ..")" .. OrigYear .. sepc .. " "
         else
         else
             if EditorCount <= 1 then
             if EditorCount <= 1 then
                 Editors = Editors .. " (ed.)" .. sepc .. " "
                 Editors = Editors .. " (" .. cfg.message_list['editor'] .. ")" .. sepc .. " "
             else
             else
                 Editors = Editors .. " (eds.)" .. sepc .. " "
                 Editors = Editors .. " (" .. cfg.message_list['editors'] .. ")" .. sepc .. " "
             end
             end
         end
         end
Line 1,335: Line 1,431:
     if ( config.CitationClass ~= "citation" )
     if ( config.CitationClass ~= "citation" )
       then classname = "citation " .. (config.CitationClass or "") end
       then classname = "citation " .. (config.CitationClass or "") end
     local args = { class=classname }
     local options = { class=classname }
     if ( Ref ~= nil ) then  
     if ( Ref ~= nil ) then  
         local id = Ref
         local id = Ref
Line 1,358: Line 1,454:
             id = anchorid(names)
             id = anchorid(names)
         end
         end
         args.id = id;
         options.id = id;
     end
     end
      
      
     if string.len(text:gsub("<span[^>/]*>.-</span>", ""):gsub("%b<>","")) <= 2 then
     if string.len(text:gsub("<span[^>/]*>.-</span>", ""):gsub("%b<>","")) <= 2 then
         z.error_categories = { 'Pages with empty citations' };
         z.error_categories = {};
         text = '<span class="error">Citation is empty</span>';
         text = seterror('empty_citation');
         z.message_tail = {};
         z.message_tail = {};
     end
     end
      
      
     text = createTag({name="span", contents=text, params=args})
     if options.id ~= nil then
        text = '<span id="' .. wikiescape(options.id) ..'" class="' .. wikiescape(options.class) .. '">' .. text .. "</span>";
    else
        text = '<span class="' .. wikiescape(options.class) .. '">' .. text .. "</span>";
    end       


     local empty_span = createTag( {name="span", contents="&nbsp;", params={style="display: none;"}} );
     local empty_span = '<span style="display: none;">&nbsp;</span>';
      
      
     -- Note: Using display: none on then COinS span breaks some clients.
     -- Note: Using display: none on then COinS span breaks some clients.
     local OCinS = createTag({name="span", contents=empty_span, params={class="Z3988",title=OCinStitle }})
     local OCinS = '<span title="' .. wikiescape(OCinStitle) .. '" class="Z3988">' .. empty_span .. '</span>';
     text = text .. OCinS;
     text = text .. OCinS;
      
      
     if #z.message_tail ~= 0 then
     if #z.message_tail ~= 0 then
         text = text .. hiddencomment( table.concat( z.message_tail, "; " ) );
         for i,v in ipairs( z.message_tail ) do
            if i == #z.message_tail then
                text = text .. errorcomment( v[1], v[2] );
            else
                text = text .. errorcomment( v[1] .. "; ", v[2] );
            end
        end
     end
     end
      
      
Line 1,393: Line 1,499:
      
      
     local args = {};
     local args = {};
    local suggestions = {};
    local error_text, error_state;
     for k, v in pairs( pframe.args ) do
     for k, v in pairs( pframe.args ) do
         if v ~= '' then
         if v ~= '' then
             if not validate( k ) then
             if not validate( k ) then          
                 if type( k ) ~= 'string' then
                 if type( k ) ~= 'string' then
                     -- Exclude empty numbered parameters
                     -- Exclude empty numbered parameters
                     if v:match("%S+") ~= nil then
                     if v:match("%S+") ~= nil then
                         table.insert( z.message_tail, 'Unnamed parameter containing "' .. v .. '" ignored' );                       
                         error_text, error_state = seterror( 'text_ignored', {v}, true );
                        table.insert( z.error_categories, 'Pages with citations using unsupported parameters' );
                     end
                     end
                 elseif validate( k:lower() ) then  
                 elseif validate( k:lower() ) then  
                     table.insert( z.message_tail, 'Unknown parameter "' .. k .. '=" ignored (suggest "' .. k:lower() .. '=")' );
                     error_text, error_state = seterror( 'parameter_ignored_suggest', {k, k:lower()}, true );
                    table.insert( z.error_categories, 'Pages with citations using unsupported parameters' );
                 else
                 else
                     table.insert( z.message_tail, 'Unknown parameter "' .. k .. '=" ignored' );
                     if #suggestions == 0 then
                     table.insert( z.error_categories, 'Pages with citations using unsupported parameters' );
                        suggestions = mw.loadData( 'Module:Citation/CS1/Suggestions' );
                 end                  
                    end
                    if suggestions[ k:lower() ] ~= nil then
                        error_text, error_state = seterror( 'parameter_ignored_suggest', {k, suggestions[ k:lower() ]}, true );
                    else
                        error_text, error_state = seterror( 'parameter_ignored', {k}, true );
                    end
                end                 
                if error_text ~= '' then
                     table.insert( z.message_tail, {error_text, error_state} );
                 end              
             end             
             end             
             args[k] = v;
             args[k] = v;
Anonymous user
Cookies help us deliver our services. By using our services, you agree to our use of cookies.