Module:Citation/CS1: Difference between revisions

10,634 bytes removed ,  11 years ago
sync to sandbox, mostly translation handles almost uniformity for archiveurl errors.
m>Dragons flight
(D'oh, meant to edit sandbox)
m>Dragons flight
(sync to sandbox, mostly translation handles almost uniformity for archiveurl errors.)
Line 4: Line 4:
     message_tail = {};
     message_tail = {};
}
}
local SEEN = {};
local DATA = {};


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


-- Checks that parameter name is valid
-- Populates numbered arguments in a message string using
-- an argument table.
function substitute( message, arguments )
    if arguments == nil then
        return message;
    end
   
    message = message .. " ";
    for k, v in ipairs( arguments ) do
        v = v:gsub( "%%", "%%%%" );
        message = message:gsub( "$" .. k .. "(%D)", v .. "%1" );
    end   
    message = message:sub(1,-2);
    return message;
end
 
--[[
Argument wrapper.  This function provides support for argument
mapping defined in the configuration file so that multiple names
can be transparently aliased to single internal variable.
]]
function argument_wrapper( args )
    DATA = args;
    local tbl = {};
   
    local mt = {
        __index = function ( tbl, k )           
            if SEEN[k] then
                return nil;
            end
           
            local list = cfg.argument_map[k];                   
 
            if list == nil then
                error( cfg.message_list['unknown_argument_map'] );
            elseif type( list ) == 'string' then
                v = DATA[list];
            else                   
                v = selectone( DATA, cfg.argument_map[k],
                    'redundant_parameters' );
            end
            if v == nil then
                v = cfg.default_values[k];
            end
            SEEN[k] = true;
            tbl = rawset( tbl, k, v );
           
            return v;
        end,
    }
    return setmetatable( tbl, mt );
end
 
-- Checks that parameter name is valid using the whitelist
function validate( name )
function validate( name )
     name = tostring( name );
     name = tostring( name );
Line 33: Line 89:
function errorcomment( content, hidden )
function errorcomment( content, hidden )
     if hidden then  
     if hidden then  
         return '<span style="display:none;font-size:100%" class="error citation-comment">' .. content .. '</span>';
         return substitute( cfg.message_list['hidden-error'], { content } );
     else
     else
         return '<span style="font-size:100%" class="error">' .. content .. '</span>';
         return substitute( cfg.message_list['visible-error'], { content } );
     end         
     end         
end
end
Line 43: Line 99:
of the error message in the output is the responsibility of the calling function.
of the error message in the output is the responsibility of the calling function.
]]
]]
function seterror( error_id, args, raw, prefix, suffix )
function seterror( error_id, arguments, raw, prefix, suffix )
     local error_state = cfg.error_conditions[ error_id ];
     local error_state = cfg.error_conditions[ error_id ];
     prefix = prefix or "";
     prefix = prefix or "";
Line 57: Line 113:
      
      
     local message = error_state.message;
     local message = error_state.message;
     if args ~= nil then
     message = substitute( message, arguments );
        for k, m in ipairs( args ) do
            m = m:gsub( "%%", "%%%%" );
            message = message:gsub( "$" .. k .. "(%D)", m .. "%1" );
        end
    end


     message = wikiescape(message) .. " ([[" .. cfg.message_list['help page link'] ..  
     message = wikiescape(message) .. " ([[" .. cfg.message_list['help page link'] ..  
Line 91: Line 142:
             [']'] = '&#93;',     
             [']'] = '&#93;',     
             ['{'] = '&#123;',     
             ['{'] = '&#123;',     
             ['|'] = '&#124;',
             ['|'] = '&#124;',  
             ['}'] = '&#125;' } );
             ['}'] = '&#125;' } );
     return text;
     return text;
Line 289: Line 340:
         if str:sub(1,1) == "'" then str = "<span />" .. str; end
         if str:sub(1,1) == "'" then str = "<span />" .. str; end
         if str:sub(-1,-1) == "'" then str = str .. "<span />"; end
         if str:sub(-1,-1) == "'" then str = str .. "<span />"; end
       
        -- Remove newlines as they break italics.
         return str:gsub( '\n', ' ' );
         return str:gsub( '\n', ' ' );
     end
     end
Line 458: Line 511:
end
end


-- Gets author list from the input arguments
-- Gets name list from the input arguments
function extractauthors(args)
function extractnames(args, list_name)
    local authors = {};
     local names = {};
    local i = 1;
    local last;
    while true do
        if i == 1 then
            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 i == 1 then
                authors[i] = {
                    last = last,
                    first = selectone( args, {"author" .. i .. "-first", "author-first" .. i,
                        "first" .. i, "given" .. i, "author-first",
                        "first", "given"}, 'redundant_parameters' ),
                    link = selectone( args, {"author" .. i .. "-link", "author-link" .. 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
            break;
        end
        i = i + 1;
    end
    return authors;
end
 
-- Gets editor list from the input arguments
function extracteditors(args)
     local editors = {};
     local i = 1;
     local i = 1;
     local last;
     local last;
      
      
     while true do
     while true do
         if i == 1 then
         last = selectone( args, cfg.argument_map[list_name .. '-Last'], 'redundant_parameters', 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
             if i == 1 then
             names[i] = {
                editors[i] = {
                last = last,
                    last = last,
                first = selectone( args, cfg.argument_map[list_name .. '-First'], 'redundant_parameters', i ),
                    first = selectone( args, {"editor" .. i .. "-first",
                link = selectone( args, cfg.argument_map[list_name .. '-Link'], 'redundant_parameters', i ),
                        "editor-first" .. i, "EditorGiven" .. i, "editor-first",
                mask = selectone( args, cfg.argument_map[list_name .. '-Mask'], 'redundant_parameters', i )
                        "EditorGiven"}, 'redundant_parameters' ),
            }              
                    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 550: Line 531:
         i = i + 1;
         i = i + 1;
     end
     end
     return editors;
     return names;
end
end


Line 617: Line 598:
-- Chooses one matching parameter from a list of parameters to consider
-- Chooses one matching parameter from a list of parameters to consider
-- Generates an error if more than one match is present.
-- Generates an error if more than one match is present.
function selectone( args, possible, error_condition )
function selectone( args, possible, error_condition, index )
     local value = nil;
     local value = nil;
     local selected = '';
     local selected = '';
     local error_list = {};
     local error_list = {};
    if index ~= nil then index = tostring(index); end
      
      
    -- Handle special case of "#" replaced by empty string
    if index == '1' then
        for _, v in ipairs( possible ) do
            v = v:gsub( "#", "" );
            if args[v] ~= nil then
                if value ~= nil and selected ~= v then
                    table.insert( error_list, v );
                else
                    value = args[v];
                    selected = v;
                end
            end
        end       
    end
     for _, v in ipairs( possible ) do
     for _, v in ipairs( possible ) do
        if index ~= nil then
            v = v:gsub( "#", index );
        end
         if args[v] ~= nil then
         if args[v] ~= nil then
             if value ~= nil then
             if value ~= nil then
Line 632: Line 632:
         end
         end
     end
     end
           
 
     if #error_list > 0 then
     if #error_list > 0 then
         local error_str = "";
         local error_str = "";
Line 656: Line 656:
]]
]]
function citation0( config, args)
function citation0( config, args)
     -- Load Input Parameters
     --[[
    Load Input Parameters
    The argment_wrapper facillitates the mapping of multiple
    aliases to single internal variable.
    ]]
    local A = argument_wrapper( args );


     local i  
     local i  
     local PPrefix = config.PPrefix or "p.&nbsp;"
     local PPrefix = A['PPrefix']
     local PPPrefix = config.PPPrefix or "pp.&nbsp;"
     local PPPrefix = A['PPPrefix']
     if ( nil ~= args.nopp ) then PPPrefix = "" PPrefix = "" end
     if ( nil ~= A['NoPP'] ) then PPPrefix = "" PPrefix = "" end
      
      
     -- 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 = A['Authors'];
     local a = extractauthors( args );
     local a = extractnames( args, 'AuthorList' );


     local Coauthors = selectone( args, {'coauthors', 'coauthor' }, 'redundant_parameters' );
     local Coauthors = A['Coauthors'];
     local Others = args.others
     local Others = A['Others'];
     local Editors = args.editors
     local Editors = A['Editors'];
     local e = extracteditors( args );
     local e = extractnames( args, 'EditorList' );


     local Year = args.year
     local Year = A['Year'];
     local PublicationDate = selectone( args, {'publicationdate', 'publication-date' }, 'redundant_parameters' );
     local PublicationDate = A['PublicationDate'];
     local OrigYear = args.origyear
     local OrigYear = A['OrigYear'];
     local Date = args.date
     local Date = A['Date'];
     local LayDate = args.laydate
     local LayDate = A['LayDate'];
     ------------------------------------------------- Get title data
     ------------------------------------------------- Get title data
     local Title = args.title or args.encyclopaedia or args.encyclopedia or args.dictionary
     local Title = A['Title'];
     local BookTitle = args.booktitle
     local BookTitle = A['BookTitle'];
     local Conference = args.conference
     local Conference = A['Conference'];
     local TransTitle = selectone( args, {'trans-title', 'trans_title' }, 'redundant_parameters' );
     local TransTitle = A['TransTitle'];
     local TitleNote = args.department
     local TitleNote = A['TitleNote'];
     local TitleLink = selectone( args, {'titlelink', 'episodelink' }, 'redundant_parameters' );
     local TitleLink = A['TitleLink'];
     local Chapter = selectone( args, {'chapter', 'contribution', 'entry' }, 'redundant_parameters' );
     local Chapter = A['Chapter'];
     local ChapterLink = args.chapterlink
     local ChapterLink = A['ChapterLink'];
     local TransChapter = selectone( args, {'trans-chapter', 'trans_chapter' }, 'redundant_parameters' );
     local TransChapter = A['TransChapter'];
     local TitleType = args.type
     local TitleType = A['TitleType'];
     local ArchiveURL = selectone( args, {'archive-url', 'archiveurl' }, 'redundant_parameters' );
     local ArchiveURL = A['ArchiveURL'];
     local URL = selectone( args, {'url', 'URL'}, 'redundant_parameters' );
     local URL = A['URL'];
     local ChapterURL = selectone( args, {'chapter-url', 'chapterurl', 'contribution-url', 'contributionurl' }, 'redundant_parameters' );
     local ChapterURL = A['ChapterURL'];
     local ConferenceURL = selectone( args, {'conference-url', 'conferenceurl' }, 'redundant_parameters' );
     local ConferenceURL = A['ConferenceURL'];
     local Periodical = selectone( args, {'journal', 'newspaper', 'magazine', 'work', 'website',
     local Periodical = A['Periodical'];
        'periodical', 'encyclopedia', 'encyclopaedia'}, 'redundant_parameters' );
              
              
     if ( config.CitationClass == "encyclopaedia" ) then
     if ( config.CitationClass == "encyclopaedia" ) then
         if ( args.article and args.article ~= "") then
         if ( Chapter == nil or Chapter == '' ) then  
             if ( Title and Title ~= "") then Periodical = Title end
             if (Title == nil or Title == "") then
            Chapter = args.article
                Title = Periodical;
            TransChapter = TransTitle
                Periodical = nil;
            Title = nil         
             else
            TransTitle = nil
        elseif ( Chapter == nil or Chapter == '' ) then
             if Title ~= args.encyclopedia then
                 Chapter = Title
                 Chapter = Title
                 TransChapter = TransTitle
                 TransChapter = TransTitle
Line 710: Line 711:
                 TransTitle = nil
                 TransTitle = nil
             end
             end
        end
        if ( Periodical and Periodical ~= "") then
            if Periodical == Title or Periodical == Chapter then Periodical = nil end
         end
         end
     end
     end
     local Series = selectone( args, {'series', 'version'}, 'redundant_parameters' );
 
     local Volume = args.volume
     local Series = A['Series'];
     local Issue = selectone( args, {'issue', 'number'}, 'redundant_parameters' );
     local Volume = A['Volume'];
     local Issue = A['Issue'];
     local Position = nil
     local Position = nil
     local Page, Pages, At, page_type;
     local Page, Pages, At, page_type;
      
      
     Page, page_type = selectone( args, {'p', 'page', 'pp', 'pages', 'at'},
     Page = A['Page'];
        'extra_pages' );
    Pages = hyphentodash( A['Pages'] );
     if page_type == 'pp' or page_type == 'pages' then
    At = A['At'];
        Pages = hyphentodash( Page );
     if Page ~= nil then
        Page = nil;
        if Pages ~= nil or At ~= nil then
     elseif page_type == 'at' then
            Page = Page .. " " .. seterror('extra_pages');
         At = Page;
            Pages = nil;
        Page = nil;
            At = nil;
     end
        end
     elseif Pages ~= nil then
         if At ~= nil then
            Pages = Pages .. " " .. seterror('extra_pages');
            At = nil;
        end
     end  
                  
                  
     local Edition = args.edition
     local Edition = A['Edition'];
     local PublicationPlace = selectone( args, {'publication-place', 'publicationplace' }, 'redundant_parameters' );
     local PublicationPlace = A['PublicationPlace']
     local Place = selectone( args, {'place', 'location'}, 'redundant_parameters' );
     local Place = A['Place'];
     if PublicationPlace == nil and Place ~= nil then  
     if PublicationPlace == nil and Place ~= nil then  
         PublicationPlace = Place;
         PublicationPlace = Place;
Line 739: Line 744:
     if PublicationPlace == Place then Place = nil end
     if PublicationPlace == Place then Place = nil end
      
      
     local PublisherName = args.publisher
     local PublisherName = A['PublisherName'];
     local SubscriptionRequired = args.subscription
     local SubscriptionRequired = A['SubscriptionRequired'];
     local Via = args.via
     local Via = A['Via'];
     local AccessDate = selectone( args, {'access-date', 'accessdate' }, 'redundant_parameters' );
     local AccessDate = A['AccessDate'];
     local ArchiveDate = selectone( args, {'archive-date', 'archivedate' }, 'redundant_parameters' );
     local ArchiveDate = A['ArchiveDate'];
     local Agency = args.agency
     local Agency = A['Agency'];
     local DeadURL = args.deadurl or "yes"          -- Only used if ArchiveURL is present.
     local DeadURL = A['DeadURL']
     local Language = selectone( args, {'language', 'in'}, 'redundant_parameters' );
     local Language = A['Language'];
     local Format = args.format
     local Format = A['Format']
     local Ref = selectone( args, {'ref', 'Ref'}, 'redundant_parameters' );
     local Ref = A['Ref']


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


     local ID_list = extractids( args );
     local ID_list = extractids( args );
      
      
     local Quote = selectone( args, {'quote', 'quotation'}, 'redundant_parameters' );
     local Quote = A['Quote'];
     local PostScript = args.postscript or "."
     local PostScript = A['PostScript']
     local LaySummary = args.laysummary
     local LaySummary = A['LaySummary']
     local LaySource = args.laysource
     local LaySource = A['LaySource'];
     local Transcript = args.transcript
     local Transcript = A['Transcript'];
     local TranscriptURL = selectone( args, {'transcript-url', 'transcripturl'}, 'redundant_parameters' );
     local TranscriptURL = A['TranscriptURL'];
     local sepc = args.separator or "."
     local sepc = A['Separator']
     local LastAuthorAmp = args.lastauthoramp
     local LastAuthorAmp = A['LastAuthorAmp']
     local no_tracking_cats = selectone( args, {"template doc demo", 'nocat',
     local no_tracking_cats = A['NoTracking'];
        'notracking', "no-tracking"}, 'redundant_parameters' ) or "";


     if ( config.CitationClass == "journal" ) then         
     if ( config.CitationClass == "journal" ) then         
         if (URL == nil or URL == "") then
         if (URL == nil or URL == "") then
             if (ID_list['PMC'] ~= nil) then  
             if (ID_list['PMC'] ~= nil) then  
                 local Embargo = args.embargo or args.Embargo;
                 local Embargo = A['Embargo'];
                 if Embargo ~= nil then
                 if Embargo ~= nil then
                     local lang = mw.getContentLanguage();
                     local lang = mw.getContentLanguage();
Line 801: Line 805:
     -- Account for the oddity that is {{cite episode}}, before generation of COinS data.
     -- Account for the oddity that is {{cite episode}}, before generation of COinS data.
     if config.CitationClass == "episode" then
     if config.CitationClass == "episode" then
         local AirDate = args.airdate
         local AirDate = A['AirDate']
         local SeriesLink = args.serieslink
         local SeriesLink = A['SeriesLink']
         local Season = args.season
         local Season = A['Season']
         local SeriesNumber = args.seriesnumber or args.seriesno
         local SeriesNumber = A['SeriesNumber']
         local Network = args.network
         local Network = A['Network']
         local Station = args.station
         local Station = A['Station']
         local s = {}
         local s = {}
         if Issue ~= nil then table.insert(s, cfg.message_list["episode"] .. " " .. Issue) Issue = nil end
         if Issue ~= nil then table.insert(s, cfg.message_list["episode"] .. " " .. Issue) Issue = nil end
Line 821: Line 825:
         TitleLink = SeriesLink
         TitleLink = SeriesLink
         TransTitle = nil
         TransTitle = nil
         local Sep = args["series-separator"] or args["separator"] or ". "
         local Sep = (A["SeriesSeparator"] or A["Separator"]) .. " "
         Series = table.concat(s, Sep)
         Series = table.concat(s, Sep)
         ID = table.concat(n, Sep)
         ID = table.concat(n, Sep)
Line 880: Line 884:
         end
         end
         if last ~= nil and first ~= nil then
         if last ~= nil and first ~= nil then
             table.insert( OCinSauthors, last .. (args.NameSep or ", ") .. first );
             table.insert( OCinSauthors, last .. ", " .. first );
     elseif last ~= nil then
     elseif last ~= nil then
             table.insert( OCinSauthors, last );
             table.insert( OCinSauthors, last );
Line 923: Line 927:
     -- 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( (selectone( args, {"display-authors", "displayauthors"}, 'redundant_parameters' )) );
         local Maximum = tonumber( A['DisplayAuthors'] );
          
          
         -- Preserve old-style implicit et al.
         -- Preserve old-style implicit et al.
Line 934: Line 938:
              
              
         local control = {  
         local control = {  
             sep = (args["author-separator"] or ";") .. " ",
             sep = A["AuthorSeparator"] .. " ",
             namesep = (args["author-name-separator"] or args["name-separator"] or ",") .. " ",
             namesep = (A["AuthorNameSeparator"] or A["NameSeparator"]) .. " ",
             format = selectone( args, {"author-format", "authorformat" }, 'redundant_parameters' ),
             format = A["AuthorFormat"],
             maximum = Maximum,
             maximum = Maximum,
             lastauthoramp = LastAuthorAmp
             lastauthoramp = LastAuthorAmp
Line 951: Line 955:
     local EditorCount
     local EditorCount
     if ( Editors == nil ) then  
     if ( Editors == nil ) then  
         local Maximum = tonumber( (selectone( args, {"display-editors", "displayeditors"}, 'redundant_parameters' )) );
         local Maximum = tonumber( A['DisplayEditors'] );


         -- Preserve old-style implicit et al.
         -- Preserve old-style implicit et al.
Line 962: Line 966:


         local control = {  
         local control = {  
             sep = (args["editor-separator"] or ";") .. " ",
             sep = A["EditorSeparator"] .. " ",
             namesep = (args["editor-name-separator"] or args["name-separator"] or ",") .. " ",
             namesep = (A["EditorNameSeparator"] or A["NameSeparator"]) .. " ",
             format = selectone( args, {"editor-format", "editorformat" }, 'redundant_parameters' ),
             format = A['EditorFormat'],
             maximum = Maximum,
             maximum = Maximum,
             lastauthoramp = LastAuthorAmp
             lastauthoramp = LastAuthorAmp
Line 994: Line 998:
         Date = Year
         Date = Year
         if ( Date ~= nil and Date ~="") then
         if ( Date ~= nil and Date ~="") then
             local Month = args.month
             local Month = A['Month']
             if ( Month ~= nil and Month ~= "") then  
             if ( Month ~= nil and Month ~= "") then  
                 Date = Month .. " " .. Date  
                 Date = Month .. " " .. Date  
                 local Day = args.day
                 local Day = A['Day']
                 if ( Day ~= nil ) then Date = Day .. " " .. Date end
                 if ( Day ~= nil ) then Date = Day .. " " .. Date end
                 else Month = ""
                 else Month = ""
Line 1,057: Line 1,061:
     end
     end


     if ( TransTitle and "" < TransTitle ) then TransTitle = " [" .. TransTitle .. "&#93;" else TransTitle = "" end
     if ( TransTitle and "" < TransTitle ) then TransTitle = " " .. substitute( cfg.message_list['trans-title'], { TransTitle } ) else TransTitle = "" end
     if ( TransChapter and "" < TransChapter ) then TransChapter = " [" .. TransChapter .. "&#93;" else TransChapter = "" end
     if ( TransChapter and "" < TransChapter ) then TransChapter = " " .. substitute( cfg.message_list['trans-title'], { TransChapter } ) else TransChapter = "" end
          
          
     -- Format chapter / article title
     -- Format chapter / article title
Line 1,065: Line 1,069:
         if ( Periodical and "" < Periodical ) and (Title ~= nil and Title ~= "" )
         if ( Periodical and "" < Periodical ) and (Title ~= nil and Title ~= "" )
         then
         then
             Chapter = "''" .. safeforitalics(Chapter) .. "''"
             Chapter = substitute( cfg.message_list['italic-title'], { (safeforitalics(Chapter)) } );
         else
         else
             Chapter = "\"" .. Chapter .. "\""
             Chapter = substitute( cfg.message_list['quoted-title'], { Chapter } );
         end
         end
     else
     else
Line 1,109: Line 1,113:
             Title = "[[" .. TitleLink .. "|" .. Title .. "]]" end
             Title = "[[" .. TitleLink .. "|" .. Title .. "]]" end
         if ( Periodical and "" < Periodical ) then
         if ( Periodical and "" < Periodical ) then
             Title = "\"" .. Title .. "\""
             Title = substitute( cfg.message_list['quoted-title'], { Title } );
         elseif ( config.CitationClass == "web"
         elseif ( config.CitationClass == "web"
                 or config.CitationClass == "news"  
                 or config.CitationClass == "news"  
                 or config.CitationClass == "pressrelease" ) and  
                 or config.CitationClass == "pressrelease" ) and  
                 Chapter == "" then
                 Chapter == "" then
             Title = "\"" .. Title .. "\""
             Title = substitute( cfg.message_list['quoted-title'], { Title } );
         else
         else
             Title = "''" .. safeforitalics(Title) .. "''"
             Title = substitute( cfg.message_list['italic-title'], { (safeforitalics(Title)) } );
         end
         end
     else
     else
Line 1,139: Line 1,143:
     if ( Place ~= nil and Place ~= "" ) then
     if ( Place ~= nil and Place ~= "" ) then
         if sepc == '.' then
         if sepc == '.' then
             Place = " " .. cfg.message_list['written'] .. " " .. Place .. sepc .. " ";
             Place = " " .. substitute( cfg.message_list['written'], {Place} ) .. sepc .. " ";
         else
         else
             Place = " " .. cfg.message_list['written']:lower() .. " " .. Place .. sepc .. " ";
             Place = " " .. substitute( cfg.message_list['written']:lower(), {Place} ) .. sepc .. " ";
         end             
         end             
     else
     else
Line 1,159: Line 1,163:
     if ( nil ~= Position or nil ~= Page or nil ~= Pages ) then At = nil end
     if ( nil ~= Position or nil ~= Page or nil ~= Pages ) then At = nil end
     if ( nil == Position and "" ~= Position ) then
     if ( nil == Position and "" ~= Position ) then
         local Minutes = args.minutes
         local Minutes = A['Minutes'];
         if ( nil ~= Minutes ) then
         if ( nil ~= Minutes ) then
             Position = " " .. Minutes .. " " .. cfg.message_list['minutes'];
             Position = " " .. Minutes .. " " .. cfg.message_list['minutes'];
         else
         else
             local Time = args.time
             local Time = A['Time'];
             if ( nil ~= Time ) then
             if ( nil ~= Time ) then
                 local TimeCaption = args.timecaption
                 local TimeCaption = A['TimeCaption']
                 if TimeCaption == nil then
                 if TimeCaption == nil then
                     TimeCaption = cfg.message_list['event'];
                     TimeCaption = cfg.message_list['event'];
Line 1,218: Line 1,222:
         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 = " (" .. cfg.message_list['in'] .. " " .. Language .. ")" else Language = "" end
         Language = " " .. substitute( cfg.message_list['language'] , {Language} ) else Language = "" end
     if ( Edition ~= nil and Edition ~="" ) then
     if ( Edition ~= nil and Edition ~="" ) then
         Edition = " (" .. Edition .. " " .. cfg.message_list['edition'] .. ")" else Edition = "" end
         Edition = " " .. substitute( cfg.message_list['edition'] , {Edition} ) else Edition = "" end
     if ( Volume ~= nil and Volume ~="" )
     if ( Volume ~= nil and Volume ~="" )
     then
     then
Line 1,239: Line 1,243:
     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; " .. cfg.message_list['via'] .. " " .. Via else Via = "" end
         Via = " " .. substitute( cfg.message_list['via'], {Via} ) else Via = "" end
     if ( AccessDate ~= nil and AccessDate ~="" )
     if ( AccessDate ~= nil and AccessDate ~="" )
     then local retrv_text = " " .. cfg.message_list['retrieved'] .. " "
     then local retrv_text = " " .. cfg.message_list['retrieved']
         if (sepc ~= ".") then retrv_text = retrv_text:lower() 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>'
             .. substitute( retrv_text, {AccessDate} ) .. '</span>'
     else AccessDate = "" end
     else AccessDate = "" end
     if ( SubscriptionRequired ~= nil and
     if ( SubscriptionRequired ~= nil and
Line 1,273: Line 1,277:
         end
         end
          
          
         Quote = sepc .." \"" .. Quote .. "\""
         Quote = sepc .." " .. substitute( cfg.message_list['quoted-text'], { Quote } );
         PostScript = ""
         PostScript = ""
     else  
     else  
Line 1,282: Line 1,286:
     local Archived
     local Archived
     if ( nil ~= ArchiveURL and "" ~= ArchiveURL ) then
     if ( nil ~= ArchiveURL and "" ~= ArchiveURL ) then
         if ( ArchiveDate ~= nil and ArchiveDate ~="" ) then
         if ( ArchiveDate == nil or ArchiveDate =="" ) then
             ArchiveDate = " " .. ArchiveDate
             ArchiveDate = seterror('archive_missing_date');
        else
            ArchiveDate = " " .. seterror('archive_missing_date') .. " "
         end
         end
        local arch_text = cfg.message_list['archived'];
        if (sepc ~= ".") then arch_text = arch_text:lower() end
         if ( "no" == DeadURL ) then
         if ( "no" == DeadURL ) then
             Archived = sepc .. " " .. externallink( ArchiveURL, arch_text ) .. " " ..
             local arch_text = cfg.message_list['archived'];
                cfg.message_list['from'] .. " " .. cfg.message_list['original'] .. " " ..
            if (sepc ~= ".") then arch_text = arch_text:lower() end
                 cfg.message_list['on'] .. ArchiveDate
            Archived = sepc .. " " .. substitute( cfg.message_list['archived-not-dead'],
                 { externallink( ArchiveURL, arch_text ), ArchiveDate } );
             if OriginalURL == nil or OriginalUrl == '' then
             if OriginalURL == nil or OriginalUrl == '' then
                 Archived = Archived .. " " .. seterror('archive_missing_url_not_dead');                               
                 Archived = Archived .. " " .. seterror('archive_missing_url');                               
             end
             end
         else
         else
             if OriginalURL ~= nil and OriginalURL ~= '' then
             if OriginalURL ~= nil and OriginalURL ~= '' then
                 Archived = sepc .. " " .. arch_text .. " " .. cfg.message_list['from'] ..  
                 local arch_text = cfg.message_list['archived-dead'];
                    " " .. externallink( OriginalURL, cfg.message_list['original'] ) .. " "
                if (sepc ~= ".") then arch_text = arch_text:lower() end
                    .. cfg.message_list['on'] .. ArchiveDate
                Archived = sepc .. " " .. substitute( arch_text,
                    { externallink( OriginalURL, cfg.message_list['original'] ), ArchiveDate } );
             else
             else
                 if config.CitationClass ~= 'web' then
                 local arch_text = cfg.message_list['archived-missing'];
                    Archived = sepc .. " " .. arch_text .. " " .. cfg.message_list['from'] .. " " ..
                if (sepc ~= ".") then arch_text = arch_text:lower() end
                    cfg.message_list['original'] .. seterror('archive_missing_url') .. " " .. cfg.message_list['on'] .. ArchiveDate
                 Archived = sepc .. " " .. substitute( arch_text,
                 else
                     { seterror('archive_missing_url'), ArchiveDate } );
                    Archived = sepc .. " " .. arch_text .. " " .. cfg.message_list['from'] .. " " ..
                     cfg.message_list['original'] .. seterror('archive_missing_url_web') .. " " .. cfg.message_list['on'] .. ArchiveDate
                end
             end                 
             end                 
         end
         end
Line 1,355: Line 1,354:
         if ( PublicationDate and PublicationDate ~="" ) then
         if ( PublicationDate and PublicationDate ~="" ) then
             if Publisher ~= '' then
             if Publisher ~= '' then
                 Publisher = Publisher .. ", " .. cfg.message_list['published'] .. " " .. PublicationDate;
                 Publisher = Publisher .. ", " .. substitute( cfg.message_list['published'], {PublicationDate} );
             else
             else
                 Publisher = PublicationDate;
                 Publisher = PublicationDate;
Line 1,365: Line 1,364:
     else
     else
         if ( PublicationDate and PublicationDate ~="" ) then
         if ( PublicationDate and PublicationDate ~="" ) then
             PublicationDate = " (" .. cfg.message_list['published'] .. " " .. PublicationDate .. ")"
             PublicationDate = " (" .. substitute( cfg.message_list['published'], {PublicationDate} ) .. ")"
         else  
         else  
             PublicationDate = ""
             PublicationDate = ""
Line 1,384: Line 1,383:
     if ( Periodical ~= nil and Periodical ~="" ) then  
     if ( Periodical ~= nil and Periodical ~="" ) then  
         if ( Title and Title ~= "" ) or ( TitleNote and TitleNote ~= "" ) then  
         if ( Title and Title ~= "" ) or ( TitleNote and TitleNote ~= "" ) then  
             Periodical = sepc .. " ''" .. safeforitalics(Periodical) .. "''"
             Periodical = sepc .. " " .. substitute( cfg.message_list['italic-title'], { (safeforitalics(Periodical)) } )
         else  
         else  
             Periodical = "''" .. safeforitalics(Periodical) .. "''"
             Periodical = substitute( cfg.message_list['italic-title'], { (safeforitalics(Periodical)) } )
         end
         end
     else Periodical = "" end
     else Periodical = "" end
Line 1,417: Line 1,416:
     if ( "" ~= Authors ) then
     if ( "" ~= Authors ) then
         if (Coauthors ~= "")  
         if (Coauthors ~= "")  
           then Authors = Authors .. "; " .. Coauthors
           then Authors = Authors .. A['AuthorSeparator'] .. " " .. Coauthors
         end
         end
         if ( "" ~= Date )
         if ( "" ~= Date )
Line 1,531: Line 1,530:
      
      
     if #z.message_tail ~= 0 then
     if #z.message_tail ~= 0 then
        text = text .. " ";
         for i,v in ipairs( z.message_tail ) do
         for i,v in ipairs( z.message_tail ) do
             if v[1] ~= nil and v[1] ~= "" then  
             if v[1] ~= nil and v[1] ~= "" then  
Line 1,542: Line 1,542:
     end
     end
      
      
     if no_tracking_cats == '' then
     if no_tracking_cats == nil then
         for _, v in ipairs( z.error_categories ) do
         for _, v in ipairs( z.error_categories ) do
             text = text .. '[[Category:' .. v ..']]';
             text = text .. '[[Category:' .. v ..']]';
Line 1,601: Line 1,601:


return z
return z
---------------------------------------------------------------------
--NOTES
--
-- NOTE A1: This Lua module was originally designed to handle a mix
--      of citation styles, crossing Vancouver style with Wikipedia's
--      local Citation Style 1 (CS1) from {Template:Citation/core}.
--      However, the conflicting positions of parameters, scattered
--      in twisted locations across this module, led to a separate
--      variation just to untangle the CS1 format of citations.
--
-- NOTE D2: The placement of dots and other separators between the
--      displayed parameters has been a continual headache, to keep
--      coordinated with the data in parentheses "(data)". There
--      has been a need to pre-check for the existence of related
--      options, to keep from putting double-dots ".." in some cases.
--      In particular, the omission of the "title=" parameter has led
--      to several cases of a spurious dot ". ." because the original
--      design had treated the title as a mandatory parameter.
--
------------------------------------------------------------------------
--HISTORY:
--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.
--18Mar2013 Fixed "page=" to override "pages=" as in markup-based cites.
--19Mar2013 Fixed date of class=journal Periodical to show after page.
--19Mar2013 Changed null "postscript=" to suppress end-dot of citation.
--20Mar2013 If CitationClass is journal, show "others=" before title.
--20Mar2013 If CitationClass is book, show "others=" before edition.
--20Mar2013 If CitationClass is journal, adjust "others=" to have sepc.
--20Mar2013 For class "journal", use book format unless Periodical set.
--03Apr2013 Changed safejoin() to omit "." after wikilink ".]]" end dot.
--03Apr2013 Changed safejoin() to omit "." after external ".]" end dot.
--03Apr2013 Changed safejoin() to omit "." at italic wikilink ".]]" end.
--03Apr2013 Changed safejoin() to omit "." at italic external ".]" end.
--04Apr2013 Moved sepc before <span class="reference-accessdate"> for "..".
--
--End
Anonymous user