Module:Citation/CS1: Difference between revisions

sync to sandbox, add additional redundant parameters checks, check for malformed URLs, removal of wikilinks in COinS data, and various code formatting.
m>Dragons flight
(sync with sandbox, reposition translation error to avoid wrapping in url)
m>Dragons flight
(sync to sandbox, add additional redundant parameters checks, check for malformed URLs, removal of wikilinks in COinS data, and various code formatting.)
Line 1: Line 1:
local z = {
local z = {
     error_categories = {};
     error_categories = {};
    error_ids = {};
     message_tail = {};
     message_tail = {};
}
}
Line 65: Line 66:
         cfg.message_list['help page label'] .. "]])";
         cfg.message_list['help page label'] .. "]])";


    z.error_ids[ error_id ] = true;
    if (error_id == 'bare_url_missing_title' or error_id == 'trans_missing_title')
            and z.error_ids['citation_missing_title'] then
        return '', false;
    end
   
     if raw == true then
     if raw == true then
         return message, error_state.hidden;
         return message, error_state.hidden;
     end
     end      
          
          
     return errorcomment( message, error_state.hidden );
     return errorcomment( message, error_state.hidden );
Line 104: Line 111:
     return "[[" .. options.link .. "|" .. options.label .. "]]" .. sep .. "[[" ..  
     return "[[" .. options.link .. "|" .. options.label .. "]]" .. sep .. "[[" ..  
             options.prefix .. options.id .. options.suffix .. "|" .. mw.text.nowiki(options.id) .. "]]"
             options.prefix .. options.id .. options.suffix .. "|" .. mw.text.nowiki(options.id) .. "]]"
end
-- Format an external link with error checking
function externallink( URL, label )
    local error_str = "";
    if label == nil or label == "" then
        label = URL;
        error_str = seterror( 'bare_url_missing_title' );
    end
    if not checkurl( URL ) then
        error_str = seterror( 'bad_url' ) .. error_str;
    end
    return "[" .. URL .. ' ' .. safeforurl( label ) .. "]" .. error_str;
end
end


Line 161: Line 182:
             encode = handler.encode}) ..  
             encode = handler.encode}) ..  
             ' ' .. seterror( 'bad_ol' );
             ' ' .. seterror( 'bad_ol' );
    end
end
--[[
Determines whether an URL string is valid
At present the only check is whether the string appears to
be prefixed with a URI scheme.  It is not determined whether
the URI scheme is valid or whether the URL is otherwise well
formed.
]]
function checkurl( url_str )
    if url_str:sub(1,2) == "//" then 
        -- Protocol-less URLs
        return true;
    elseif url_str:match( "^[^/]*:" ) ~= nil then 
        -- Look for ":" prefix and assume it is a URI scheme
        return true;
    else
        -- Anything else is an error
        return false;
     end
     end
end
end
Line 193: Line 235:
         return temp % 10 == 0;
         return temp % 10 == 0;
     end
     end
end
-- Gets the display text for a wikilink like [[A|B]] or [[B]] gives B
function removewikilink( str )
    str = str:gsub( "%[%[[^|%]]*|([^%]]*)%]%]", "%1" );
    str = str:gsub( "%[%[([^%]]*)%]%]", "%1" );   
    return str
end
end


Line 395: Line 444:


-- Generates a CITEREF anchor ID.
-- Generates a CITEREF anchor ID.
function anchorid(options)
function anchorid( options )
     local P1 = options[1] or ""
     return "CITEREF" .. mw.uri.anchorEncode( table.concat( options ) );
    local P2 = options[2] or ""
    local P3 = options[3] or ""
    local P4 = options[4] or ""
    local P5 = options[5] or ""
   
    -- Bugzilla 46608
    local encoded = mw.uri.anchorEncode( P1 .. P2 .. P3 .. P4 .. P5 );
    if encoded == false then
        encoded = "";
    end
   
    return "CITEREF" .. encoded;
end
end


Line 544: Line 581:
             elseif k == 'ISBN' then
             elseif k == 'ISBN' then
                 local ISBN = internallinkid( handler );
                 local ISBN = internallinkid( handler );
                 if not checkisbn( v ) then  
                 if not checkisbn( v ) and (IgnoreISBN == nil or IgnoreISBN == "") then  
                     ISBN = ISBN .. seterror( 'bad_isbn' );
                     ISBN = ISBN .. seterror( 'bad_isbn' );
                 end
                 end
Line 621: Line 658:
     local a = extractauthors( args );
     local a = extractauthors( args );


     local Coauthors = args.coauthors or args.coauthor  
     local Coauthors = selectone( args, {'coauthors', 'coauthor' }, 'redundant_parameters' );
     local Others = args.others  
     local Others = args.others  
     local Editors = args.editors
     local Editors = args.editors
Line 627: Line 664:


     local Year = args.year  
     local Year = args.year  
     local PublicationDate = args.publicationdate or args["publication-date"]
     local PublicationDate = selectone( args, {'publicationdate', 'publication-date' }, 'redundant_parameters' );
     local OrigYear = args.origyear
     local OrigYear = args.origyear
     local Date = args.date
     local Date = args.date
Line 635: Line 672:
     local BookTitle = args.booktitle
     local BookTitle = args.booktitle
     local Conference = args.conference
     local Conference = args.conference
     local TransTitle = args.trans_title
     local TransTitle = selectone( args, {'trans-title', 'trans_title' }, 'redundant_parameters' );
     local TitleNote = args.department
     local TitleNote = args.department
     local TitleLink = args.titlelink or args.episodelink
     local TitleLink = selectone( args, {'titlelink', 'episodelink' }, 'redundant_parameters' );
     local Chapter = selectone( args, {'chapter', 'contribution', 'entry' }, 'redundant_parameters' );
     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 = selectone( args, {'trans-chapter', 'trans_chapter' }, 'redundant_parameters' );
     local TitleType = args.type
     local TitleType = args.type
     local ArchiveURL = args["archive-url"] or args.archiveurl
     local ArchiveURL = selectone( args, {'archive-url', 'archiveurl' }, 'redundant_parameters' );
     local URL = args.url or args.URL
     local URL = selectone( args, {'url', 'URL'}, 'redundant_parameters' );
     local ChapterURL = args["chapter-url"] or args.chapterurl or args["contribution-url"]
     local ChapterURL = selectone( args, {'chapter-url', 'chapterurl', 'contribution-url', 'contributionurl' }, 'redundant_parameters' );
     local ConferenceURL = args["conference-url"] or args.conferenceurl
     local ConferenceURL = selectone( args, {'conference-url', 'conferenceurl' }, 'redundant_parameters' );
     local Periodical = selectone( args, {'journal', 'newspaper', 'magazine', 'work', 'website',  
     local Periodical = selectone( args, {'journal', 'newspaper', 'magazine', 'work', 'website',  
         'periodical', 'encyclopedia', 'encyclopaedia'}, 'redundant_parameters' );
         'periodical', 'encyclopedia', 'encyclopaedia'}, 'redundant_parameters' );
Line 685: Line 722:
                  
                  
     local Edition = args.edition
     local Edition = args.edition
     local PublicationPlace = args["publication-place"] or args.publicationplace  
     local PublicationPlace = selectone( args, {'publication-place', 'publicationplace' }, 'redundant_parameters' );
     local Place = selectone( args, {'place', 'location'}, 'redundant_parameters' );
     local Place = selectone( args, {'place', 'location'}, 'redundant_parameters' );
     if PublicationPlace == nil and Place ~= nil then  
     if PublicationPlace == nil and Place ~= nil then  
Line 695: Line 732:
     local SubscriptionRequired = args.subscription
     local SubscriptionRequired = args.subscription
     local Via = args.via
     local Via = args.via
     local AccessDate = args["access-date"] or args.accessdate
     local AccessDate = selectone( args, {'access-date', 'accessdate' }, 'redundant_parameters' );
     local ArchiveDate = args["archive-date"] or args.archivedate
     local ArchiveDate = selectone( args, {'archive-date', 'archivedate' }, 'redundant_parameters' );
     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 if ArchiveURL is present.
     local Language = selectone( args, {'language', 'in'}, 'redundant_parameters' );
     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 = selectone( args, {'ref', 'Ref'}, 'redundant_parameters' );


     local DoiBroken = args.doi_inactivedate or args.doi_brokendate or args.DoiBroken
     local DoiBroken = selectone( args, {'doi_inactivedate', 'doi_brokendate', 'DoiBroken'}, 'redundant_parameters' );
     local ID = selectone( args, {'id', 'ID', 'docket'}, 'redundant_parameters' );
     local ID = selectone( args, {'id', 'ID', 'docket'}, 'redundant_parameters' );
     local ASINTLD = args["ASIN-TLD"] or args["asin-tld"]
     local ASINTLD = selectone( args, {'ASIN-TLD', 'asin-tld'}, 'redundant_parameters' );
    local IgnoreISBN = selectone( args, {'ignore-isbn-error', 'ignoreisbnerror'}, 'redundant_parameters' );


     local ID_list = extractids( args );
     local ID_list = extractids( args );
Line 714: Line 752:
     local LaySource = args.laysource
     local LaySource = args.laysource
     local Transcript = args.transcript
     local Transcript = args.transcript
     local TranscriptURL = args["transcript-url"] or args.transcripturl
     local TranscriptURL = selectone( args, {'transcript-url', 'transcripturl'}, 'redundant_parameters' );
     local sepc = args.separator or "."
     local sepc = args.separator or "."
     local LastAuthorAmp = args.lastauthoramp
     local LastAuthorAmp = args.lastauthoramp
     local no_tracking_cats = args["template doc demo"] or args.nocat or
     local no_tracking_cats = selectone( args, {"template doc demo", 'nocat',
            args.notracking or args["no-tracking"] or "";
        'notracking', "no-tracking"}, 'redundant_parameters' ) or "";


     if ( config.CitationClass == "journal" ) then         
     if ( config.CitationClass == "journal" ) then         
Line 844: Line 882:
     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
         OCinStitle = OCinStitle .. "&" .. name .. "=" .. mw.uri.encode(value)
         OCinStitle = OCinStitle .. "&" .. name .. "=" .. mw.uri.encode( removewikilink(value) );
     end
     end
     for _, value in ipairs(OCinSauthors) do
     for _, value in ipairs(OCinSauthors) do
         OCinStitle = OCinStitle .. "&rft.au=" .. mw.uri.encode(value)
         OCinStitle = OCinStitle .. "&rft.au=" .. mw.uri.encode( removewikilink(value) );
     end
     end
     for name,value in pairs(OCinSids) do
     for name,value in pairs(OCinSids) do
         OCinStitle = OCinStitle .. "&rft_id=" .. mw.uri.encode(name .. "/" .. value)
         OCinStitle = OCinStitle .. "&rft_id=" .. mw.uri.encode(name .. "/" .. removewikilink(value) );
     end
     end
      
      
Line 872: Line 910:
     -- various parts of the citation, but only when they are non-nil.
     -- various parts of the citation, but only when they are non-nil.
     if ( Authors == nil ) then  
     if ( Authors == nil ) then  
         local Maximum = tonumber(args["display-authors"] or args.displayauthors);
         local Maximum = tonumber( (selectone( args, {"display-authors", "displayauthors"}, 'redundant_parameters' )) );
          
          
         -- Preserve old-style implicit et al.
         -- Preserve old-style implicit et al.
Line 885: Line 923:
             sep = (args["author-separator"] or ";") .. " ",
             sep = (args["author-separator"] or ";") .. " ",
             namesep = (args["author-name-separator"] or args["name-separator"] or ",") .. " ",
             namesep = (args["author-name-separator"] or args["name-separator"] or ",") .. " ",
             format = args["author-format"] or args.authorformat,
             format = selectone( args, {"author-format", "authorformat" }, 'redundant_parameters' ),
             maximum = Maximum,
             maximum = Maximum,
             lastauthoramp = LastAuthorAmp
             lastauthoramp = LastAuthorAmp
Line 900: Line 938:
     local EditorCount
     local EditorCount
     if ( Editors == nil ) then  
     if ( Editors == nil ) then  
         local Maximum = tonumber(args["display-editors"] or args.displayeditors);
         local Maximum = tonumber( (selectone( args, {"display-editors", "displayeditors"}, 'redundant_parameters' )) );


         -- Preserve old-style implicit et al.
         -- Preserve old-style implicit et al.
Line 913: Line 951:
             sep = (args["editor-separator"] or ";") .. " ",
             sep = (args["editor-separator"] or ";") .. " ",
             namesep = (args["editor-name-separator"] or args["name-separator"] or ",") .. " ",
             namesep = (args["editor-name-separator"] or args["name-separator"] or ",") .. " ",
             format = args["editor-format"] or args.editorformat,
             format = selectone( args, {"editor-format", "editorformat" }, 'redundant_parameters' ),
             maximum = Maximum,
             maximum = Maximum,
             lastauthoramp = LastAuthorAmp
             lastauthoramp = LastAuthorAmp
Line 1,029: Line 1,067:
     if Chapter ~= "" then
     if Chapter ~= "" then
         if ( ChapterLink == nil ) then
         if ( ChapterLink == nil ) then
             if ( ChapterURL and "" < ChapterURL ) then
             if ( ChapterURL and "" < ChapterURL ) then              
                 Chapter = "[" .. ChapterURL .. " " .. safeforurl( Chapter ) .. "]" .. TransError;
                 Chapter = externallink( ChapterURL, Chapter ) .. TransError;
                 if URL == nil or URL == "" then
                 if URL == nil or URL == "" then
                     Chapter = Chapter .. Format;
                     Chapter = Chapter .. Format;
Line 1,036: Line 1,074:
                 end
                 end
             elseif ( URL and "" < URL ) then  
             elseif ( URL and "" < URL ) then  
                 Chapter = "[" .. URL .. " " .. safeforurl( Chapter ) .. "]" .. TransError .. Format
                 Chapter = externallink( URL, Chapter ) .. TransError .. Format;
                 URL = nil
                 URL = nil
                 Format = ""
                 Format = ""
Line 1,043: Line 1,081:
             end             
             end             
         elseif ChapterURL ~= nil and ChapterURL ~= "" then
         elseif ChapterURL ~= nil and ChapterURL ~= "" then
             Chapter = Chapter .. " [" .. ChapterURL .. " " .. safeforurl( ChapterURL ) .. "]" ..  
             Chapter = Chapter .. " " .. externallink( ChapterURL ) ..  
                 TransError .. " " .. seterror( 'bare_url_missing_title' );
                 TransError;
         else
         else
             Chapter = Chapter .. TransError;
             Chapter = Chapter .. TransError;
Line 1,050: Line 1,088:
         Chapter = Chapter .. sepc .. " " -- with end-space
         Chapter = Chapter .. sepc .. " " -- with end-space
     elseif ChapterURL ~= nil and ChapterURL ~= "" then
     elseif ChapterURL ~= nil and ChapterURL ~= "" then
         Chapter = " [" .. ChapterURL .. " " .. safeforurl( ChapterURL ) .. "]" ..
         Chapter = " " .. externallink( ChapterURL ) .. sepc .. " ";
            seterror( 'bare_url_missing_title' ) .. sepc .. " ";
     end         
     end         
      
      
Line 1,079: Line 1,116:
     if Title ~= "" then
     if Title ~= "" then
         if ( TitleLink == nil and URL and "" < URL ) then  
         if ( TitleLink == nil and URL and "" < URL ) then  
             Title = "[" .. URL .. " " .. safeforurl( Title ) .. "]" .. TransError .. Format
             Title = externallink( URL, Title ) .. TransError .. Format      
             URL = nil
             URL = nil
             Format = ''
             Format = ''
Line 1,099: Line 1,136:
     if ( Conference ~= nil and Conference ~="" ) then
     if ( Conference ~= nil and Conference ~="" ) then
         if ( ConferenceURL ~= nil ) then
         if ( ConferenceURL ~= nil ) then
             Conference = "[" .. ConferenceURL .. " " .. safeforurl( Conference ) .. "]"
             Conference = externallink( ConferenceURL, Conference );
         end
         end
         Conference = " " .. Conference
         Conference = " " .. Conference
     elseif ConferenceURL ~= nil and ConferenceURL ~= "" then
     elseif ConferenceURL ~= nil and ConferenceURL ~= "" then
         Conference = " [" .. ConferenceURL .. " " .. safeforurl( ConferenceURL ) .. "]" ..
         Conference = " " .. externallink( ConferenceURL );
            seterror( 'bare_url_missing_title' );
     else
     else
         Conference = ""  
         Conference = ""  
Line 1,205: Line 1,241:
     if ( ID ~= nil and ID ~="") then ID = sepc .." ".. ID else ID="" end
     if ( ID ~= nil and ID ~="") then ID = sepc .." ".. ID else ID="" end


     ID_list = buildidlist( ID_list, {DoiBroken = DoiBroken, ASINTLD = ASINTLD} );
     ID_list = buildidlist( ID_list, {DoiBroken = DoiBroken, ASINTLD = ASINTLD, IgnoreISBN = IgnoreISBN} );


     if ( URL ~= nil and URL ~="") then
     if ( URL ~= nil and URL ~="") then
         URL = " " .. "[" .. URL .. " " .. mw.text.nowiki(URL) .. "]";
         URL = " " .. externallink( URL, URL );
         local error_text = seterror( 'bare_url_missing_title' );
         local error_text = seterror( 'bare_url_missing_title' );
         if config.CitationClass == "web" then
         if config.CitationClass == "web" then
Line 1,238: Line 1,274:
             ArchiveDate = " " .. seterror('archive_missing_date') .. " "
             ArchiveDate = " " .. seterror('archive_missing_date') .. " "
         end
         end
         local arch_text = " " .. cfg.message_list['archived'];
         local arch_text = cfg.message_list['archived'];
         if (sepc ~= ".") then arch_text = arch_text:lower() end
         if (sepc ~= ".") then arch_text = arch_text:lower() end
         if ( "no" == DeadURL ) then
         if ( "no" == DeadURL ) then
             Archived = sepc .. " [" .. ArchiveURL .. arch_text .. "] " ..  
             Archived = sepc .. " " .. externallink( ArchiveURL, arch_text ) .. " " ..  
                 cfg.message_list['from'] .. " " .. cfg.message_list['original'] .. " " ..  
                 cfg.message_list['from'] .. " " .. cfg.message_list['original'] .. " " ..  
                 cfg.message_list['on'] .. ArchiveDate
                 cfg.message_list['on'] .. ArchiveDate
Line 1,249: Line 1,285:
         else
         else
             if OriginalURL ~= nil and OriginalURL ~= '' then
             if OriginalURL ~= nil and OriginalURL ~= '' then
                 Archived = sepc .. arch_text .. " " .. cfg.message_list['from'] .. " [" .. OriginalURL .. " " ..
                 Archived = sepc .. " " .. arch_text .. " " .. cfg.message_list['from'] ..  
                    cfg.message_list['original'] .. "] " .. cfg.message_list['on'] .. ArchiveDate
                    " " .. externallink( 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 .. " " .. cfg.message_list['from'] .. " " ..  
                     Archived = sepc .. " " .. arch_text .. " " .. cfg.message_list['from'] .. " " ..  
                     seterror('archive_missing_url') .. " " .. cfg.message_list['on'] .. ArchiveDate
                     seterror('archive_missing_url') .. " " .. cfg.message_list['on'] .. ArchiveDate
                 else
                 else
                     Archived = sepc .. arch_text .. " " .. cfg.message_list['from'] ..  
                     Archived = sepc .. " " .. arch_text .. " " .. cfg.message_list['from'] ..  
                         " " .. cfg.message_list['original'] .. " " ..  
                         " " .. cfg.message_list['original'] .. " " ..  
                         cfg.message_list['on'] .. ArchiveDate
                         cfg.message_list['on'] .. ArchiveDate
Line 1,282: Line 1,319:
     end
     end
     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 = externallink( TranscriptURL, Transcript ) end
     elseif TranscriptURL ~= nil and TranscriptURL ~= "" then
     elseif TranscriptURL ~= nil and TranscriptURL ~= "" then
         Transcript = "[" .. TranscriptURL .. " " .. safeforurl( TranscriptURL ) .. "]" ..
         Transcript = externallink( TranscriptURL )    
            seterror( 'bare_url_missing_title' )       
     else
     else
         Transcript = ""
         Transcript = ""
Line 1,448: Line 1,484:
             local names = {} --table of last names & year
             local names = {} --table of last names & year
             if ( "" ~= Authors ) then
             if ( "" ~= Authors ) then
                 for i,v in ipairs(a) do names[i] = v.last end
                 for i,v in ipairs(a) do  
                    names[i] = v.last  
                    if i == 4 then break end
                end
             elseif ( "" ~= Editors ) then
             elseif ( "" ~= Editors ) then
                 for i,v in ipairs(e) do names[i] = v.last end
                 for i,v in ipairs(e) do  
            end
                    names[i] = v.last  
            if ( names[1] == nil ) then
                    if i == 4 then break end               
                names[1] = Year
                 end
            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
             end
            names[ #names + 1 ] = Year;
             id = anchorid(names)
             id = anchorid(names)
         end
         end
Line 1,480: Line 1,512:
     end         
     end         


     local empty_span = '<span style="display: none;">&nbsp;</span>';
     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.
Line 1,488: Line 1,520:
     if #z.message_tail ~= 0 then
     if #z.message_tail ~= 0 then
         for i,v in ipairs( z.message_tail ) do
         for i,v in ipairs( z.message_tail ) do
             if i == #z.message_tail then
             if v[1] ~= nil and v[1] ~= "" then
                text = text .. errorcomment( v[1], v[2] );
                if i == #z.message_tail then
            else
                    text = text .. errorcomment( v[1], v[2] );
                text = text .. errorcomment( v[1] .. "; ", v[2] );
                else
                    text = text .. errorcomment( v[1] .. "; ", v[2] );
                end
             end
             end
         end
         end
Anonymous user