Editing Module:Citation/CS1
Warning: You are not logged in.
Your IP address will be recorded in this page's edit history.The edit can be undone.
Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.
Latest revision | Your text | ||
Line 1: | Line 1: | ||
− | |||
local z = { | local z = { | ||
− | + | error_categories = {}; | |
− | + | error_ids = {}; | |
− | + | message_tail = {}; | |
− | + | ||
− | + | ||
} | } | ||
− | -- | + | -- 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' ); | ||
− | -- | + | -- Checks that parameter name is valid |
− | function | + | function validate( name ) |
− | + | name = tostring( name ); | |
− | + | ||
− | + | -- Normal arguments | |
− | + | if whitelist.basic_arguments[ name ] then | |
− | + | return true; | |
− | + | end | |
+ | |||
+ | -- Arguments with numbers in them | ||
+ | name = name:gsub( "%d+", "#" ); | ||
+ | if whitelist.numbered_arguments[ name ] then | ||
+ | return true; | ||
+ | end | ||
+ | |||
+ | -- Not found, argument not supported. | ||
+ | return false | ||
end | end | ||
− | -- | + | -- Formats a comment for error trapping |
− | function | + | function errorcomment( content, hidden ) |
− | + | 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 | 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 | + | function seterror( error_id, args, raw, prefix, suffix ) |
− | + | local error_state = cfg.error_conditions[ error_id ]; | |
− | + | prefix = prefix or ""; | |
− | + | suffix = suffix or ""; | |
− | + | ||
− | + | ||
− | + | if error_state == nil then | |
− | + | error( cfg.message_list['undefined_error'] ); | |
− | + | end | |
− | 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 | |
− | + | m = m:gsub( "%%", "%%%%" ); | |
− | + | 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'] .. "]])"; | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | 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 | |
+ | |||
+ | message = prefix .. message .. suffix; | ||
+ | |||
+ | if raw == true then | ||
+ | return message, error_state.hidden; | ||
+ | end | ||
+ | |||
+ | return errorcomment( message, error_state.hidden ); | ||
end | end | ||
− | -- | + | -- This returns a string with HTML character entities for wikitext markup characters. |
− | + | function wikiescape(text) | |
− | + | text = text:gsub( '[&\'%[%]{|}]', { | |
− | + | ['&'] = '&', | |
− | + | ["'"] = ''', | |
− | + | ['['] = '[', | |
− | + | [']'] = ']', | |
− | + | ['{'] = '{', | |
− | + | ['|'] = '|', | |
− | + | ['}'] = '}' } ); | |
− | + | return text; | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | function | + | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
end | end | ||
-- Formats a wiki style external link | -- Formats a wiki style external link | ||
function externallinkid(options) | function externallinkid(options) | ||
− | + | local sep = options.separator or " " | |
− | + | options.suffix = options.suffix or "" | |
− | + | local url_string = options.id | |
− | + | if options.encode == true or options.encode == nil then | |
− | + | url_string = mw.uri.encode( url_string ); | |
− | + | end | |
− | + | ||
− | + | return "[[" .. options.link .. "|" .. options.label .. "]]" .. sep .. "[" .. | |
− | + | options.prefix .. url_string .. options.suffix .. " " .. mw.text.nowiki(options.id) .. "]" | |
end | end | ||
-- Formats a wiki style internal link | -- Formats a wiki style internal link | ||
function internallinkid(options) | function internallinkid(options) | ||
− | + | local sep = options.separator or " " | |
− | + | options.suffix = options.suffix or "" | |
− | + | return "[[" .. options.link .. "|" .. options.label .. "]]" .. sep .. "[[" .. | |
− | + | options.prefix .. options.id .. options.suffix .. "|" .. mw.text.nowiki(options.id) .. "]]" | |
− | + | ||
end | end | ||
-- Format an external link with error checking | -- Format an external link with error checking | ||
− | function externallink( URL, label | + | function externallink( URL, label ) |
− | + | local error_str = ""; | |
− | + | if label == nil or label == "" then | |
− | + | label = URL; | |
− | + | error_str = seterror( 'bare_url_missing_title', {}, false, " " ); | |
− | + | end | |
− | + | if not checkurl( URL ) then | |
− | + | error_str = seterror( 'bad_url', {}, false, " " ) .. error_str; | |
− | + | end | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | end | + | |
− | + | return "[" .. URL .. ' ' .. safeforurl( label ) .. "]" .. error_str; | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
end | end | ||
− | -- | + | -- Formats a link to Amazon |
− | + | ||
− | Formats a link to Amazon | + | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
function amazon(id, domain) | function amazon(id, domain) | ||
− | + | if ( nil == domain ) then | |
− | + | domain = "com" | |
− | + | elseif ( "jp" == domain or "uk" == domain ) then | |
− | + | domain = "co." .. domain | |
− | + | end | |
− | + | local handler = cfg.id_handlers['ASIN']; | |
− | + | return externallinkid({link = handler.link, | |
− | + | label=handler.label , prefix="//www.amazon."..domain.."/dp/",id=id, | |
− | + | encode=handler.encode, separator = handler.separator}) | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
end | end | ||
-- Formats a DOI and checks for DOI errors. | -- Formats a DOI and checks for DOI errors. | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
function doi(id, inactive) | function doi(id, inactive) | ||
− | + | local cat = "" | |
− | + | local handler = cfg.id_handlers['DOI']; | |
− | + | ||
− | + | local text; | |
− | + | if ( inactive ~= nil ) then | |
− | + | text = "[[" .. handler.link .. "|" .. handler.label .. "]]:" .. id; | |
− | + | table.insert( z.error_categories, "Pages with DOIs inactive since " .. selectyear(inactive) ); | |
− | + | inactive = " (" .. cfg.message_list['inactive'] .. " " .. inactive .. ")" | |
− | + | else | |
− | + | text = externallinkid({link = handler.link, label = handler.label, | |
− | + | prefix=handler.prefix,id=id,separator=handler.separator, encode=handler.encode}) | |
− | + | inactive = "" | |
− | + | end | |
− | + | if ( string.sub(id,1,3) ~= "10." ) then | |
− | + | cat = seterror( 'bad_doi' ); | |
− | + | end | |
− | + | return text .. inactive .. cat | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
end | end | ||
-- Formats an OpenLibrary link, and checks for associated errors. | -- Formats an OpenLibrary link, and checks for associated errors. | ||
function openlibrary(id) | 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 | end | ||
--[[ | --[[ | ||
− | Determines whether | + | Determines whether an URL string is valid |
At present the only check is whether the string appears to | At present the only check is whether the string appears to | ||
Line 848: | Line 198: | ||
]] | ]] | ||
function checkurl( url_str ) | 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 | ||
Line 855: | Line 213: | ||
-- Similar to that used for Special:BookSources | -- Similar to that used for Special:BookSources | ||
function cleanisbn( isbn_str ) | function cleanisbn( isbn_str ) | ||
− | + | return isbn_str:gsub( "[^-0-9X]", "" ); | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
end | end | ||
-- Determines whether an ISBN string is valid | -- Determines whether an ISBN string is valid | ||
function checkisbn( isbn_str ) | function checkisbn( isbn_str ) | ||
− | + | isbn_str = cleanisbn( isbn_str ):gsub( "-", "" ); | |
− | + | 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 | end | ||
-- Gets the display text for a wikilink like [[A|B]] or [[B]] gives B | -- Gets the display text for a wikilink like [[A|B]] or [[B]] gives B | ||
function removewikilink( str ) | function removewikilink( str ) | ||
− | + | str = str:gsub( "%[%[[^|%]]*|([^%]]*)%]%]", "%1" ); | |
− | + | str = str:gsub( "%[%[([^%]]*)%]%]", "%1" ); | |
− | + | return str | |
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 | |
− | + | table.insert( z.message_tail, { seterror( 'wikilink_in_url', {}, true ) } ); | |
− | + | end | |
− | + | ||
− | + | return str:gsub( '[%[%]\n]', { | |
− | + | ['['] = '[', | |
− | + | [']'] = ']', | |
− | + | ['\n'] = ' ' } ); | |
end | end | ||
-- Converts a hyphen to a dash | -- Converts a hyphen to a dash | ||
function hyphentodash( str ) | function hyphentodash( str ) | ||
− | + | if str == nil then | |
− | + | return nil; | |
− | + | end | |
− | + | if str:match( "[%[%]{}<>]" ) ~= nil then | |
+ | return str; | ||
+ | end | ||
+ | return str:gsub( '-', '–' ); | ||
end | end | ||
-- Protects a string that will be wrapped in wiki italic markup '' ... '' | -- Protects a string that will be wrapped in wiki italic markup '' ... '' | ||
function safeforitalics( str ) | function safeforitalics( str ) | ||
− | + | --[[ Note: We can not use <i> for italics, as the expected behavior for | |
− | + | italics specified by ''...'' in the title is that they will be inverted | |
− | + | (i.e. unitalicized) in the resulting references. In addition, <i> and '' | |
− | + | tend to interact poorly under Mediawiki's HTML tidy. ]] | |
− | + | ||
− | + | if str == nil or str == '' then | |
− | + | return str; | |
− | + | else | |
− | + | if str:sub(1,1) == "'" then str = "<span />" .. str; end | |
− | + | if str:sub(-1,-1) == "'" then str = str .. "<span />"; end | |
− | + | return str:gsub( '\n', ' ' ); | |
− | + | end | |
− | + | ||
− | + | ||
end | end | ||
− | --[[ | + | --[[ |
− | + | Joins a sequence of strings together while checking for duplicate separation | |
− | Joins a sequence of strings together while checking for duplicate separation characters. | + | characters. |
− | + | ||
]] | ]] | ||
function safejoin( tbl, duplicate_char ) | function safejoin( tbl, duplicate_char ) | ||
− | + | --[[ | |
− | + | Note: we use string functions here, rather than ustring functions. | |
− | + | ||
− | + | This has considerably faster performance and should work correctly as | |
− | + | long as the duplicate_char is strict ASCII. The strings | |
− | + | in tbl may be ASCII or UTF8. | |
− | + | ]] | |
− | + | ||
− | + | local str = ''; | |
− | + | local comp = ''; | |
− | + | local end_chr = ''; | |
− | + | local trim; | |
− | + | for _, value in ipairs( tbl ) do | |
− | + | if value == nil then value = ''; end | |
− | + | ||
− | + | if str == '' then | |
− | + | str = value; | |
− | + | elseif value ~= '' then | |
− | + | if value:sub(1,1) == '<' then | |
− | + | -- Special case of values enclosed in spans and other markup. | |
− | + | comp = value:gsub( "%b<>", "" ); | |
− | + | else | |
− | + | comp = value; | |
− | + | end | |
− | + | ||
− | + | if comp:sub(1,1) == duplicate_char then | |
− | + | trim = false; | |
− | + | end_chr = str:sub(-1,-1); | |
− | + | -- str = str .. "<HERE(enchr=" .. end_chr.. ")" | |
− | + | if end_chr == duplicate_char then | |
− | + | str = str:sub(1,-2); | |
− | + | elseif end_chr == "'" then | |
− | + | if str:sub(-3,-1) == duplicate_char .. "''" then | |
− | + | str = str:sub(1, -4) .. "''"; | |
− | + | elseif str:sub(-5,-1) == duplicate_char .. "]]''" then | |
− | + | trim = true; | |
− | + | elseif str:sub(-4,-1) == duplicate_char .. "]''" then | |
− | + | trim = true; | |
− | + | end | |
− | + | elseif end_chr == "]" then | |
− | + | if str:sub(-3,-1) == duplicate_char .. "]]" then | |
− | + | trim = true; | |
− | + | elseif str:sub(-2,-1) == duplicate_char .. "]" then | |
− | + | trim = true; | |
− | + | end | |
− | + | elseif end_chr == " " then | |
− | + | if str:sub(-2,-1) == duplicate_char .. " " then | |
− | + | str = str:sub(1,-3); | |
− | + | end | |
− | + | end | |
− | + | ||
− | + | ||
− | + | ||
− | + | if trim then | |
− | + | if value ~= comp then | |
− | + | local dup2 = duplicate_char; | |
− | + | if dup2:match( "%A" ) then dup2 = "%" .. dup2; end | |
− | + | ||
− | + | value = value:gsub( "(%b<>)" .. dup2, "%1", 1 ) | |
− | + | else | |
− | + | value = value:sub( 2, -1 ); | |
− | + | end | |
− | + | end | |
− | + | end | |
− | + | str = str .. value; | |
− | + | end | |
− | + | end | |
− | + | return str; | |
end | end | ||
+ | |||
+ | --[[ | ||
+ | Return the year portion of a date string, if possible. | ||
+ | Returns empty string if the argument can not be interpreted | ||
+ | as a year. | ||
+ | ]] | ||
+ | function selectyear( str ) | ||
+ | -- Is the input a simple number? | ||
+ | local num = tonumber( str ); | ||
+ | if num ~= nil and num > 0 and num < 2100 and num == math.abs(num) then | ||
+ | return str; | ||
+ | else | ||
+ | -- Use formatDate to interpret more complicated formats | ||
+ | local lang = mw.getContentLanguage(); | ||
+ | local good, result; | ||
+ | good, result = pcall( lang.formatDate, lang, 'Y', str ) | ||
+ | if good then | ||
+ | return result; | ||
+ | else | ||
+ | -- Can't make sense of this input, return blank. | ||
+ | return ""; | ||
+ | end | ||
+ | end | ||
+ | end | ||
-- Attempts to convert names to initials. | -- Attempts to convert names to initials. | ||
function reducetoinitials(first) | function reducetoinitials(first) | ||
− | + | local initials = {} | |
− | + | for word in string.gmatch(first, "%S+") do | |
− | + | table.insert(initials, string.sub(word,1,1)) -- Vancouver format does not include full stops. | |
− | + | end | |
− | + | return table.concat(initials) -- Vancouver format does not include spaces. | |
− | + | ||
− | + | ||
− | + | ||
end | end | ||
-- Formats a list of people (e.g. authors / editors) | -- Formats a list of people (e.g. authors / editors) | ||
function listpeople(control, people) | function listpeople(control, people) | ||
− | + | local sep = control.sep; | |
− | + | if sep:sub(-1,-1) ~= " " then sep = sep .. " " end | |
− | + | local namesep = control.namesep | |
− | + | local format = control.format | |
− | + | local maximum = control.maximum | |
− | + | local lastauthoramp = control.lastauthoramp; | |
− | + | local text = {} | |
− | + | local etal = false; | |
− | + | for i,person in ipairs(people) do | |
− | + | if (person.last ~= nil or person.last ~= "") then | |
− | + | local mask = person.mask | |
− | + | local one | |
− | + | if ( maximum ~= nil and i == maximum + 1 ) then | |
− | + | etal = true; | |
− | + | break; | |
− | + | elseif (mask ~= nil) then | |
− | + | local n = tonumber(mask) | |
− | + | if (n ~= nil) then | |
− | + | one = string.rep("—",n) | |
− | + | else | |
− | + | one = mask | |
− | + | end | |
− | + | else | |
− | + | one = person.last | |
− | + | local first = person.first | |
− | + | if (first ~= nil and first ~= '') then | |
− | + | if ( "vanc" == format ) then first = reducetoinitials(first) end | |
− | + | one = one .. namesep .. first | |
− | + | end | |
− | + | if (person.link ~= nil and person.link ~= "") then one = "[[" .. person.link .. "|" .. one .. "]]" end | |
− | + | end | |
− | + | table.insert(text, one) | |
− | + | end | |
− | + | end | |
− | + | local count = #text; | |
− | + | if count > 1 and lastauthoramp ~= nil and lastauthoramp ~= "" and not etal then | |
− | + | text[count-1] = text[count-1] .. " & " .. text[count]; | |
− | + | text[count] = nil; | |
− | + | end | |
− | + | local result = table.concat(text, sep) -- construct list | |
− | + | if etal then | |
− | + | local etal_text = cfg.message_list['et al']; | |
− | + | result = result .. " " .. etal_text; | |
− | + | end | |
− | + | ||
− | + | -- if necessary wrap result in <span> tag to format in Small Caps | |
− | + | if ( "scap" == format ) then result = | |
− | + | '<span class="smallcaps" style="font-variant:small-caps">' .. result .. '</span>'; | |
− | + | end | |
− | + | return result, count | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
end | end | ||
− | -- | + | -- Generates a CITEREF anchor ID. |
− | Generates a CITEREF anchor ID | + | |
− | + | ||
− | + | ||
− | + | ||
function anchorid( options ) | function anchorid( options ) | ||
− | + | return "CITEREF" .. mw.uri.anchorEncode( table.concat( options ) ); | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
end | end | ||
− | -- | + | -- Gets author list from the input arguments |
− | Gets | + | function extractauthors(args) |
− | + | local authors = {}; | |
− | + | 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 last; | |
− | + | ||
− | + | while true do | |
− | + | if i == 1 then | |
− | + | 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 i == 1 then | |
− | + | editors[i] = { | |
+ | last = last, | ||
+ | first = selectone( args, {"editor" .. i .. "-first", | ||
+ | "editor-first" .. i, "EditorGiven" .. i, "editor-first", | ||
+ | "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 | ||
+ | break; | ||
+ | end | ||
+ | i = i + 1; | ||
+ | end | ||
+ | return editors; | ||
end | end | ||
-- Populates ID table from arguments using configuration settings | -- Populates ID table from arguments using configuration settings | ||
function extractids( args ) | 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 | end | ||
− | -- | + | -- Takes a table of IDs and turns it into a table of formatted ID outputs. |
− | 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 ) and ( options.IgnoreISBN == nil or options.IgnoreISBN == "" ) then | ||
+ | ISBN = ISBN .. seterror( 'bad_isbn', {}, false, " ", "" ); | ||
+ | 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 ) | |
− | function | + | 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 | end | ||
-- 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 ) |
− | + | 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 | ||
− | + | --[[ | |
− | + | This is the main function foing the majority of the citation | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | --[[ | + | |
− | This is the main function | + | |
formatting. | formatting. | ||
]] | ]] | ||
function citation0( config, args) | function citation0( config, args) | ||
− | + | -- Load Input Parameters | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | local i | |
− | + | local PPrefix = config.PPrefix or "p. " | |
− | + | local PPPrefix = config.PPPrefix or "pp. " | |
− | + | if ( nil ~= args.nopp ) then PPPrefix = "" PPrefix = "" end | |
− | + | ||
− | + | -- Pick out the relevant fields from the arguments. Different citation templates | |
− | + | -- define different field names for the same underlying things. | |
− | + | local Authors = args.authors | |
− | + | local a = extractauthors( args ); | |
− | + | local Coauthors = selectone( args, {'coauthors', 'coauthor' }, 'redundant_parameters' ); | |
− | + | local Others = args.others | |
− | + | local Editors = args.editors | |
− | + | local e = extracteditors( args ); | |
− | + | local Year = args.year | |
− | + | local PublicationDate = selectone( args, {'publicationdate', 'publication-date' }, 'redundant_parameters' ); | |
− | + | local OrigYear = args.origyear | |
− | + | local Date = args.date | |
− | + | local LayDate = args.laydate | |
+ | ------------------------------------------------- Get title data | ||
+ | local Title = args.title or args.encyclopaedia or args.encyclopedia or args.dictionary | ||
+ | local BookTitle = args.booktitle | ||
+ | local Conference = args.conference | ||
+ | local TransTitle = selectone( args, {'trans-title', 'trans_title' }, 'redundant_parameters' ); | ||
+ | local TitleNote = args.department | ||
+ | local TitleLink = selectone( args, {'titlelink', 'episodelink' }, 'redundant_parameters' ); | ||
+ | local Chapter = selectone( args, {'chapter', 'contribution', 'entry' }, 'redundant_parameters' ); | ||
+ | local ChapterLink = args.chapterlink | ||
+ | local TransChapter = selectone( args, {'trans-chapter', 'trans_chapter' }, 'redundant_parameters' ); | ||
+ | local TitleType = args.type | ||
+ | local ArchiveURL = selectone( args, {'archive-url', 'archiveurl' }, 'redundant_parameters' ); | ||
+ | local URL = selectone( args, {'url', 'URL'}, 'redundant_parameters' ); | ||
+ | local ChapterURL = selectone( args, {'chapter-url', 'chapterurl', 'contribution-url', 'contributionurl' }, 'redundant_parameters' ); | ||
+ | local ConferenceURL = selectone( args, {'conference-url', 'conferenceurl' }, 'redundant_parameters' ); | ||
+ | local Periodical = selectone( args, {'journal', 'newspaper', 'magazine', 'work', 'website', | ||
+ | 'periodical', 'encyclopedia', 'encyclopaedia'}, 'redundant_parameters' ); | ||
+ | |||
+ | if ( config.CitationClass == "encyclopaedia" ) then | ||
+ | if ( args.article and args.article ~= "") then | ||
+ | if ( Title and Title ~= "") then Periodical = Title end | ||
+ | Chapter = args.article | ||
+ | TransChapter = TransTitle | ||
+ | Title = nil | ||
+ | TransTitle = nil | ||
+ | elseif ( Chapter == nil or Chapter == '' ) then | ||
+ | if Title ~= args.encyclopedia then | ||
+ | Chapter = Title | ||
+ | TransChapter = TransTitle | ||
+ | Title = nil | ||
+ | TransTitle = nil | ||
+ | end | ||
+ | end | ||
+ | if ( Periodical and Periodical ~= "") then | ||
+ | if Periodical == Title or Periodical == Chapter then Periodical = nil end | ||
+ | end | ||
+ | end | ||
+ | local Series = selectone( args, {'series', 'version'}, 'redundant_parameters' ); | ||
+ | local Volume = args.volume | ||
+ | local Issue = selectone( args, {'issue', 'number'}, 'redundant_parameters' ); | ||
+ | local Position = nil | ||
+ | local Page, Pages, At, page_type; | ||
+ | |||
+ | Page, page_type = selectone( args, {'p', 'page', 'pp', 'pages', 'at'}, | ||
+ | 'extra_pages' ); | ||
+ | if page_type == 'pp' or page_type == 'pages' then | ||
+ | Pages = hyphentodash( Page ); | ||
+ | Page = nil; | ||
+ | elseif page_type == 'at' then | ||
+ | At = Page; | ||
+ | Page = nil; | ||
+ | end | ||
+ | |||
+ | local Edition = args.edition | ||
+ | local PublicationPlace = selectone( args, {'publication-place', 'publicationplace' }, 'redundant_parameters' ); | ||
+ | local Place = selectone( args, {'place', 'location'}, 'redundant_parameters' ); | ||
+ | if PublicationPlace == nil and Place ~= nil then | ||
+ | PublicationPlace = Place; | ||
+ | end | ||
+ | if PublicationPlace == Place then Place = nil end | ||
+ | |||
+ | local PublisherName = args.publisher | ||
+ | local SubscriptionRequired = args.subscription | ||
+ | local Via = args.via | ||
+ | local AccessDate = selectone( args, {'access-date', 'accessdate' }, 'redundant_parameters' ); | ||
+ | local ArchiveDate = selectone( args, {'archive-date', 'archivedate' }, 'redundant_parameters' ); | ||
+ | local Agency = args.agency | ||
+ | local DeadURL = args.deadurl or "yes" -- Only used if ArchiveURL is present. | ||
+ | local Language = selectone( args, {'language', 'in'}, 'redundant_parameters' ); | ||
+ | local Format = args.format | ||
+ | local Ref = selectone( args, {'ref', 'Ref'}, 'redundant_parameters' ); | ||
− | + | local DoiBroken = selectone( args, {'doi_inactivedate', 'doi_brokendate', 'DoiBroken'}, 'redundant_parameters' ); | |
− | + | local ID = selectone( args, {'id', 'ID', 'docket'}, 'redundant_parameters' ); | |
− | + | 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 Quote = selectone( args, {'quote', 'quotation'}, 'redundant_parameters' ); | |
− | + | local PostScript = args.postscript or "." | |
− | + | local LaySummary = args.laysummary | |
− | + | local LaySource = args.laysource | |
− | + | local Transcript = args.transcript | |
+ | local TranscriptURL = selectone( args, {'transcript-url', 'transcripturl'}, 'redundant_parameters' ); | ||
+ | local sepc = args.separator or "." | ||
+ | local LastAuthorAmp = args.lastauthoramp | ||
+ | local no_tracking_cats = selectone( args, {"template doc demo", 'nocat', | ||
+ | 'notracking', "no-tracking"}, 'redundant_parameters' ) or ""; | ||
− | + | if ( config.CitationClass == "journal" ) then | |
− | + | if (URL == nil or URL == "") then | |
− | + | if (ID_list['PMC'] ~= nil) then | |
− | + | local Embargo = args.embargo or args.Embargo; | |
− | + | if Embargo ~= nil then | |
− | + | 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 | ||
− | + | -- At this point fields may be nil if they weren't specified in the template use. We can use that fact. | |
+ | |||
+ | -- Account for the oddity that is {{cite conference}}, before generation of COinS data. | ||
+ | if ( BookTitle ) then | ||
+ | Chapter = Title | ||
+ | ChapterLink = TitleLink | ||
+ | TransChapter = TransTitle | ||
+ | Title = BookTitle | ||
+ | TitleLink = nil | ||
+ | TransTitle = nil | ||
+ | end | ||
+ | -- Account for the oddity that is {{cite episode}}, before generation of COinS data. | ||
+ | if config.CitationClass == "episode" then | ||
+ | local AirDate = args.airdate | ||
+ | local SeriesLink = args.serieslink | ||
+ | local Season = args.season | ||
+ | local SeriesNumber = args.seriesnumber or args.seriesno | ||
+ | local Network = args.network | ||
+ | local Station = args.station | ||
+ | local s = {} | ||
+ | if Issue ~= nil then table.insert(s, cfg.message_list["episode"] .. " " .. Issue) Issue = nil end | ||
+ | if Season ~= nil then table.insert(s, cfg.message_list["season"] .. " " .. Season) end | ||
+ | if SeriesNumber ~= nil then table.insert(s, cfg.message_list["series"] .. " " .. SeriesNumber) end | ||
+ | local n = {} | ||
+ | if Network ~= nil then table.insert(n, Network) end | ||
+ | if Station ~= nil then table.insert(n, Station) end | ||
+ | Date = Date or AirDate | ||
+ | Chapter = Title | ||
+ | ChapterLink = TitleLink | ||
+ | TransChapter = TransTitle | ||
+ | Title = Series | ||
+ | TitleLink = SeriesLink | ||
+ | TransTitle = nil | ||
+ | local Sep = args["series-separator"] or args["separator"] or ". " | ||
+ | Series = table.concat(s, Sep) | ||
+ | ID = table.concat(n, Sep) | ||
+ | end | ||
+ | |||
+ | -- These data form a COinS tag (see <http://ocoins.info/>) which allows | ||
+ | -- automated tools to parse the citation information. | ||
+ | local OCinSdata = {} -- COinS metadata excluding id, bibcode, doi, etc. | ||
+ | local ctx_ver = "Z39.88-2004" | ||
+ | OCinSdata.rft_val_fmt = "info:ofi/fmt:kev:mtx:book" | ||
+ | if ( nil ~= Periodical ) then | ||
+ | OCinSdata.rft_val_fmt = "info:ofi/fmt:kev:mtx:journal" | ||
+ | OCinSdata["rft.genre"] = "article" | ||
+ | OCinSdata["rft.jtitle"] = Periodical | ||
+ | if ( nil ~= Title ) then OCinSdata["rft.atitle"] = Title end | ||
+ | end | ||
+ | if ( nil ~= Chapter and "" ~= Chapter) then | ||
+ | OCinSdata.rft_val_fmt = "info:ofi/fmt:kev:mtx:book" | ||
+ | OCinSdata["rft.genre"] = "bookitem" | ||
+ | OCinSdata["rft.btitle"] = Chapter | ||
+ | if ( nil ~= Title ) then OCinSdata["rft.atitle"] = Title end | ||
+ | else | ||
+ | OCinSdata["rft.genre"] = "book" | ||
+ | if ( nil ~= Title ) then OCinSdata["rft.btitle"] = Title end | ||
+ | end | ||
+ | OCinSdata["rft.place"] = PublicationPlace | ||
+ | OCinSdata["rft.date"] = Date or Year or PublicationDate | ||
+ | OCinSdata["rft.series"] = Series | ||
+ | OCinSdata["rft.volume"] = Volume | ||
+ | OCinSdata["rft.issue"] = Issue | ||
+ | OCinSdata["rft.pages"] = Page or Pages or At | ||
+ | OCinSdata["rft.edition"] = Edition | ||
+ | OCinSdata["rft.pub"] = PublisherName | ||
+ | |||
+ | for k, v in pairs( ID_list ) do | ||
+ | if k == 'ISBN' then | ||
+ | v = cleanisbn( v ); | ||
+ | end | ||
+ | if string.sub( cfg.id_handlers[k].COinS or "info", 1, 4 ) ~= 'info' then | ||
+ | OCinSdata[ cfg.id_handlers[k].COinS ] = v; | ||
+ | end | ||
+ | end | ||
+ | |||
+ | OCinSdata.rft_id = URL or ChapterURL | ||
− | + | local last, first; | |
− | + | local OCinSauthors = {}; | |
− | + | for k, v in ipairs( a ) do | |
− | + | last = v.last; | |
− | + | first = v.first; | |
+ | if k == 1 then | ||
+ | if last ~= nil then | ||
+ | OCinSdata["rft.aulast"] = last; | ||
+ | end | ||
+ | if first ~= nil then | ||
+ | OCinSdata["rft.aufirst"] = first; | ||
+ | end | ||
+ | end | ||
+ | if last ~= nil and first ~= nil then | ||
+ | table.insert( OCinSauthors, last .. (args.NameSep or ", ") .. first ); | ||
+ | elseif last ~= nil then | ||
+ | table.insert( OCinSauthors, last ); | ||
+ | end | ||
+ | end | ||
− | + | local OCinSids = {} -- COinS data only for id, bibcode, doi, pmid, etc. | |
− | + | for k, v in pairs( ID_list ) do | |
+ | if string.sub( cfg.id_handlers[k].COinS or "", 1, 4 ) == 'info' then | ||
+ | OCinSids[ cfg.id_handlers[k].COinS ] = v; | ||
+ | end | ||
+ | end | ||
− | -- | + | local OCinStitle = "ctx_ver=" .. ctx_ver -- such as "Z39.88-2004" |
− | + | for name,value in pairs(OCinSdata) do | |
− | + | OCinStitle = OCinStitle .. "&" .. name .. "=" .. mw.uri.encode( removewikilink(value) ); | |
− | + | end | |
+ | for _, value in ipairs(OCinSauthors) do | ||
+ | OCinStitle = OCinStitle .. "&rft.au=" .. mw.uri.encode( removewikilink(value) ); | ||
+ | end | ||
+ | for name,value in pairs(OCinSids) do | ||
+ | OCinStitle = OCinStitle .. "&rft_id=" .. mw.uri.encode(name .. "/" .. removewikilink(value) ); | ||
+ | end | ||
+ | |||
+ | local this_page = mw.title.getCurrentTitle(); | ||
+ | OCinStitle = OCinStitle .. "&rfr_id=info:sid/" .. mw.site.server:match( "[^/]*$" ) .. ":" | ||
+ | .. this_page.prefixedText -- end COinS data by page's non-encoded pagename | ||
− | + | if (Periodical ~= nil and Periodical ~= "") and | |
− | + | (Chapter == nil or Chapter == '') and | |
− | + | (Title ~= nil and Title ~= "") then | |
− | + | Chapter = Title | |
− | + | ChapterLink = TitleLink | |
+ | TransChapter = TransTitle | ||
+ | Title = nil | ||
+ | TitleLink = nil | ||
+ | TransTitle = nil | ||
+ | end | ||
− | -- | + | -- Now perform various field substitutions. |
− | + | -- We also add leading spaces and surrounding markup and punctuation to the | |
− | + | -- various parts of the citation, but only when they are non-nil. | |
− | + | if ( Authors == nil ) then | |
− | + | local Maximum = tonumber( (selectone( args, {"display-authors", "displayauthors"}, 'redundant_parameters' )) ); | |
− | + | ||
+ | -- Preserve old-style implicit et al. | ||
+ | if Maximum == nil and #a == 9 then | ||
+ | Maximum = 8; | ||
+ | table.insert( z.message_tail, { seterror('implict_etal_author', {}, true ) } ); | ||
+ | elseif Maximum == nil then | ||
+ | Maximum = #a + 1; | ||
+ | end | ||
+ | |||
+ | local control = { | ||
+ | sep = (args["author-separator"] or ";") .. " ", | ||
+ | namesep = (args["author-name-separator"] or args["name-separator"] or ",") .. " ", | ||
+ | format = selectone( args, {"author-format", "authorformat" }, 'redundant_parameters' ), | ||
+ | maximum = Maximum, | ||
+ | lastauthoramp = LastAuthorAmp | ||
+ | } | ||
+ | |||
+ | -- If the coauthor field is also used, prevent ampersand and et al. formatting. | ||
+ | if Coauthors ~= nil and Coauthors ~= "" then | ||
+ | control.lastauthoramp = nil; | ||
+ | control.maximum = #a + 1; | ||
+ | end | ||
+ | |||
+ | Authors = listpeople(control, a) | ||
+ | end | ||
+ | local EditorCount | ||
+ | if ( Editors == nil ) then | ||
+ | local Maximum = tonumber( (selectone( args, {"display-editors", "displayeditors"}, 'redundant_parameters' )) ); | ||
− | -- | + | -- Preserve old-style implicit et al. |
− | + | if Maximum == nil and #e == 4 then | |
− | + | Maximum = 3; | |
− | + | table.insert( z.message_tail, { seterror('implict_etal_editor', {}, true) } ); | |
− | + | elseif Maximum == nil then | |
− | + | Maximum = #e + 1; | |
+ | end | ||
− | + | local control = { | |
− | + | sep = (args["editor-separator"] or ";") .. " ", | |
− | + | namesep = (args["editor-name-separator"] or args["name-separator"] or ",") .. " ", | |
− | + | format = selectone( args, {"editor-format", "editorformat" }, 'redundant_parameters' ), | |
− | + | maximum = Maximum, | |
− | + | lastauthoramp = LastAuthorAmp | |
− | + | } | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | Editors, EditorCount = listpeople(control, e) | |
− | + | else | |
− | + | EditorCount = 1; | |
− | + | end | |
− | + | if ( Date == nil or Date == "") then | |
− | + | -- there's something hinky with how this adds dashes to perfectly-good free-standing years | |
− | + | --[[ Date = Year | |
− | -- | + | if ( Date ~= nil ) then |
− | + | local Month = args.month | |
− | + | if ( Month == nil ) then | |
− | + | local Began = args.began | |
− | + | local Ended = args.ended | |
− | + | if Began ~= nil and Ended ~= nil then | |
+ | Month = Began .. "–" .. Ended | ||
+ | else | ||
+ | Month = "–" | ||
+ | end | ||
+ | end | ||
+ | Date = Month .. " " .. Date | ||
+ | local Day = args.day | ||
+ | if ( Day ~= nil ) then Date = Day .. " " .. Date end | ||
+ | end | ||
+ | ]] -- so let's use the original version for now | ||
+ | Date = Year | ||
+ | if ( Date ~= nil and Date ~="") then | ||
+ | local Month = args.month | ||
+ | if ( Month ~= nil and Month ~= "") then | ||
+ | Date = Month .. " " .. Date | ||
+ | local Day = args.day | ||
+ | if ( Day ~= nil ) then Date = Day .. " " .. Date end | ||
+ | else Month = "" | ||
+ | end | ||
+ | else Date = "" | ||
+ | end | ||
+ | end | ||
+ | if ( PublicationDate == Date or PublicationDate == Year ) then PublicationDate = nil end | ||
+ | if( (Date == nil or Date == "") and PublicationDate ~= nil ) then | ||
+ | Date = PublicationDate; | ||
+ | PublicationDate = nil; | ||
+ | end | ||
− | + | -- Captures the value for Date prior to adding parens or other textual transformations | |
− | + | local DateIn = Date | |
+ | |||
+ | if ( URL == nil or URL == '' ) and | ||
+ | ( ChapterURL == nil or ChapterURL == '' ) and | ||
+ | ( ArchiveURL == nil or ArchiveURL == '' ) and | ||
+ | ( ConferenceURL == nil or ConferenceURL == '' ) and | ||
+ | ( TranscriptURL == nil or TranscriptURL == '' ) then | ||
− | + | -- Test if cite web is called without giving a URL | |
− | + | if ( config.CitationClass == "web" ) then | |
− | + | table.insert( z.message_tail, { seterror( 'cite_web_url', {}, true ) } ); | |
+ | end | ||
− | + | -- Test if accessdate is given without giving a URL | |
+ | if ( AccessDate ~= nil and AccessDate ~= '' ) then | ||
+ | table.insert( z.message_tail, { seterror( 'accessdate_missing_url', {}, true ) } ); | ||
+ | AccessDate = nil; | ||
+ | end | ||
+ | |||
+ | -- Test if format is given without giving a URL | ||
+ | if ( Format ~= nil and Format ~= '' ) then | ||
+ | Format = Format .. seterror( 'format_missing_url' ); | ||
+ | end | ||
+ | end | ||
− | + | -- Test if citation has no title | |
− | + | if ( Chapter == nil or Chapter == "" ) and | |
− | + | ( Title == nil or Title == "" ) and | |
− | + | ( Periodical == nil or Periodical == "" ) and | |
− | + | ( Conference == nil or Conference == "" ) and | |
− | + | ( TransTitle == nil or TransTitle == "" ) and | |
− | + | ( TransChapter == nil or TransChapter == "" ) then | |
− | + | table.insert( z.message_tail, { seterror( 'citation_missing_title', {}, true ) } ); | |
− | + | end | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | if ( Format ~= nil and Format ~="" ) then | |
− | + | Format = " (" .. Format .. ")" else Format = "" end | |
− | + | ||
− | + | local OriginalURL = URL | |
− | + | DeadURL = DeadURL:lower(); | |
− | + | if ( ArchiveURL and "" < ArchiveURL ) then | |
− | + | if ( DeadURL ~= "no" ) then | |
− | + | URL = ArchiveURL | |
− | + | end | |
− | + | end | |
− | + | ||
− | -- | + | if ( TransTitle and "" < TransTitle ) then TransTitle = " [" .. TransTitle .. "]" else TransTitle = "" end |
− | + | if ( TransChapter and "" < TransChapter ) then TransChapter = " [" .. TransChapter .. "]" else TransChapter = "" end | |
− | + | ||
− | + | -- Format chapter / article title | |
− | + | if ( Chapter ~= nil and Chapter ~= "" ) then | |
− | + | if ( ChapterLink and "" < ChapterLink ) then Chapter = "[[" .. ChapterLink .. "|" .. Chapter .. "]]" end | |
− | + | if ( Periodical and "" < Periodical ) and (Title ~= nil and Title ~= "" ) | |
− | + | then | |
− | + | Chapter = "''" .. safeforitalics(Chapter) .. "''" | |
− | + | else | |
− | + | Chapter = "\"" .. Chapter .. "\"" | |
− | + | end | |
− | + | else | |
− | + | Chapter = ""; | |
− | + | end | |
− | + | ||
− | + | local TransError = "" | |
− | + | if TransChapter ~= "" and Chapter == "" then | |
− | + | TransError = " " .. seterror( 'trans_missing_chapter' ); | |
+ | end | ||
+ | Chapter = Chapter .. TransChapter | ||
+ | if Chapter ~= "" then | ||
+ | if ( ChapterLink == nil ) then | ||
+ | if ( ChapterURL and "" < ChapterURL ) then | ||
+ | Chapter = externallink( ChapterURL, Chapter ) .. TransError; | ||
+ | if URL == nil or URL == "" then | ||
+ | Chapter = Chapter .. Format; | ||
+ | Format = ""; | ||
+ | end | ||
+ | elseif ( URL and "" < URL ) then | ||
+ | Chapter = externallink( URL, Chapter ) .. TransError .. Format; | ||
+ | URL = nil | ||
+ | Format = "" | ||
+ | else | ||
+ | Chapter = Chapter .. TransError; | ||
+ | end | ||
+ | elseif ChapterURL ~= nil and ChapterURL ~= "" then | ||
+ | Chapter = Chapter .. " " .. externallink( ChapterURL ) .. | ||
+ | TransError; | ||
+ | else | ||
+ | Chapter = Chapter .. TransError; | ||
+ | end | ||
+ | Chapter = Chapter .. sepc .. " " -- with end-space | ||
+ | elseif ChapterURL ~= nil and ChapterURL ~= "" then | ||
+ | Chapter = " " .. externallink( ChapterURL ) .. sepc .. " "; | ||
+ | end | ||
+ | |||
+ | -- Format main title. | ||
+ | if ( Title and "" < Title ) then | ||
+ | if ( TitleLink and "" < TitleLink ) then | ||
+ | Title = "[[" .. TitleLink .. "|" .. Title .. "]]" end | ||
+ | if ( Periodical and "" < Periodical ) then | ||
+ | Title = "\"" .. Title .. "\"" | ||
+ | elseif ( config.CitationClass == "web" | ||
+ | or config.CitationClass == "news" | ||
+ | or config.CitationClass == "pressrelease" ) and | ||
+ | Chapter == "" then | ||
+ | Title = "\"" .. Title .. "\"" | ||
+ | else | ||
+ | Title = "''" .. safeforitalics(Title) .. "''" | ||
+ | end | ||
+ | else | ||
+ | Title = ""; | ||
+ | end | ||
+ | |||
+ | local TransError = ""; | ||
+ | if TransTitle ~= "" and Title == "" then | ||
+ | TransError = " " .. seterror( 'trans_missing_title' ); | ||
+ | end | ||
+ | Title = Title .. TransTitle | ||
+ | if Title ~= "" then | ||
+ | if ( TitleLink == nil and URL and "" < URL ) then | ||
+ | Title = externallink( URL, Title ) .. TransError .. Format | ||
+ | URL = nil | ||
+ | Format = '' | ||
+ | else | ||
+ | Title = Title .. TransError; | ||
+ | end | ||
+ | end | ||
− | + | if ( Place ~= nil and Place ~= "" ) then | |
− | + | if sepc == '.' then | |
− | + | Place = " " .. cfg.message_list['written'] .. " " .. Place .. sepc .. " "; | |
− | + | else | |
− | + | Place = " " .. cfg.message_list['written']:lower() .. " " .. Place .. sepc .. " "; | |
− | + | end | |
− | + | else | |
− | + | Place = ""; | |
− | + | end | |
− | + | ||
− | + | if ( Conference ~= nil and Conference ~="" ) then | |
+ | if ( ConferenceURL ~= nil ) then | ||
+ | Conference = externallink( ConferenceURL, Conference ); | ||
+ | end | ||
+ | Conference = " " .. Conference | ||
+ | elseif ConferenceURL ~= nil and ConferenceURL ~= "" then | ||
+ | Conference = " " .. externallink( ConferenceURL ); | ||
+ | else | ||
+ | Conference = "" | ||
+ | end | ||
+ | if ( nil ~= Position or nil ~= Page or nil ~= Pages ) then At = nil end | ||
+ | if ( nil == Position and "" ~= Position ) then | ||
+ | local Minutes = args.minutes | ||
+ | if ( nil ~= Minutes ) then | ||
+ | Position = " " .. Minutes .. " " .. cfg.message_list['minutes']; | ||
+ | else | ||
+ | local Time = args.time | ||
+ | if ( nil ~= Time ) then | ||
+ | local TimeCaption = args.timecaption | ||
+ | if TimeCaption == nil then | ||
+ | TimeCaption = cfg.message_list['event']; | ||
+ | if sepc ~= '.' then | ||
+ | TimeCaption = TimeCaption:lower(); | ||
+ | end | ||
+ | end | ||
+ | Position = " " .. TimeCaption .. " " .. Time | ||
+ | else | ||
+ | Position = "" | ||
+ | end | ||
+ | end | ||
+ | else | ||
+ | Position = " " .. Position | ||
+ | end | ||
+ | if ( nil == Page or "" == Page ) then | ||
+ | Page = "" | ||
+ | if ( nil == Pages or "" == Pages) then | ||
+ | Pages = "" | ||
+ | elseif ( Periodical ~= nil and Periodical ~= "" and | ||
+ | config.CitationClass ~= "encyclopaedia" and | ||
+ | config.CitationClass ~= "web" and | ||
+ | config.CitationClass ~= "book" and | ||
+ | config.CitationClass ~= "news") then | ||
+ | Pages = ": " .. Pages | ||
+ | else | ||
+ | if ( tonumber(Pages) ~= nil ) then | ||
+ | Pages = sepc .." " .. PPrefix .. Pages | ||
+ | else Pages = sepc .." " .. PPPrefix .. Pages | ||
+ | end | ||
+ | end | ||
+ | else | ||
+ | Pages = "" | ||
+ | if ( Periodical ~= nil and Periodical ~= "" and | ||
+ | config.CitationClass ~= "encyclopaedia" and | ||
+ | config.CitationClass ~= "web" and | ||
+ | config.CitationClass ~= "book" and | ||
+ | config.CitationClass ~= "news") then | ||
+ | Page = ": " .. Page | ||
+ | else | ||
+ | Page = sepc .." " .. PPrefix .. Page | ||
+ | end | ||
+ | end | ||
+ | if ( At ~= nil and At ~="") then At = sepc .. " " .. At | ||
+ | else At = "" end | ||
+ | if ( Coauthors == nil ) then Coauthors = "" end | ||
+ | if ( Others ~= nil and Others ~="" ) then | ||
+ | Others = sepc .. " " .. Others else Others = "" end | ||
+ | if ( TitleType ~= nil and TitleType ~="" ) then | ||
+ | TitleType = " (" .. TitleType .. ")" else TitleType = "" end | ||
+ | if ( TitleNote ~= nil and TitleNote ~="" ) then | ||
+ | TitleNote = sepc .. " " .. TitleNote else TitleNote = "" end | ||
+ | if ( Language ~= nil and Language ~="" ) then | ||
+ | Language = " (" .. cfg.message_list['in'] .. " " .. Language .. ")" else Language = "" end | ||
+ | if ( Edition ~= nil and Edition ~="" ) then | ||
+ | Edition = " (" .. Edition .. " " .. cfg.message_list['edition'] .. ")" else Edition = "" end | ||
+ | if ( Volume ~= nil and Volume ~="" ) | ||
+ | then | ||
+ | if ( mw.ustring.len(Volume) > 4 ) | ||
+ | then Volume = sepc .." " .. Volume | ||
+ | else Volume = " <b>" .. hyphentodash(Volume) .. "</b>" | ||
+ | end | ||
+ | else Volume = "" end | ||
+ | if ( Issue ~= nil and Issue ~="" ) then | ||
+ | Issue = " (" .. Issue .. ")" else Issue = "" end | ||
+ | if ( Series ~= nil and Series ~="" ) then | ||
+ | Series = sepc .. " " .. Series else Series = "" end | ||
+ | if ( OrigYear ~= nil and OrigYear ~="" ) then | ||
+ | OrigYear = " [" .. OrigYear .. "]" else OrigYear = "" end | ||
+ | if ( Agency ~= nil and Agency ~="" ) then | ||
+ | Agency = sepc .. " " .. Agency else Agency = "" end | ||
+ | ------------------------------------ totally unrelated data | ||
+ | if ( Date ~= nil ) then Date = Date else Date = "" end | ||
+ | if ( Via ~= nil and Via ~="" ) then | ||
+ | Via = " — " .. cfg.message_list['via'] .. " " .. Via else Via = "" end | ||
+ | if ( AccessDate ~= nil and AccessDate ~="" ) | ||
+ | then local retrv_text = " " .. cfg.message_list['retrieved'] .. " " | ||
+ | if (sepc ~= ".") then retrv_text = retrv_text:lower() end | ||
+ | AccessDate = '<span class="reference-accessdate">' .. sepc | ||
+ | .. retrv_text .. AccessDate .. '</span>' | ||
+ | else AccessDate = "" end | ||
+ | if ( SubscriptionRequired ~= nil and | ||
+ | SubscriptionRequired ~= "" ) then | ||
+ | SubscriptionRequired = sepc .. " " .. cfg.message_list['subscription']; | ||
+ | else | ||
+ | SubscriptionRequired = "" | ||
+ | end | ||
+ | if ( ID ~= nil and ID ~="") then ID = sepc .." ".. ID else ID="" end | ||
− | + | ID_list = buildidlist( ID_list, {DoiBroken = DoiBroken, ASINTLD = ASINTLD, IgnoreISBN = IgnoreISBN} ); | |
− | + | ||
− | + | ||
− | + | ||
− | + | if ( URL ~= nil and URL ~="") then | |
− | + | URL = " " .. externallink( URL, URL ); | |
− | + | local error_text = seterror( 'bare_url_missing_title' ); | |
− | + | if config.CitationClass == "web" then | |
− | + | URL = URL .. " " .. seterror( 'cite_web_title' ); | |
− | + | else | |
− | + | URL = URL .. error_text; | |
+ | end | ||
+ | else | ||
+ | URL = "" | ||
+ | end | ||
− | -- | + | if ( Quote and Quote ~="" ) then |
− | + | if Quote:sub(1,1) == '"' and Quote:sub(-1,-1) == '"' then | |
− | + | Quote = Quote:sub(2,-2); | |
− | + | end | |
− | + | ||
− | + | Quote = sepc .." \"" .. Quote .. "\"" | |
− | + | PostScript = "" | |
− | + | else | |
− | + | if ( PostScript == nil) then PostScript = "" end | |
− | + | Quote = "" | |
− | + | end | |
− | + | ||
− | + | local Archived | |
− | + | if ( nil ~= ArchiveURL and "" ~= ArchiveURL ) then | |
− | + | if ( ArchiveDate ~= nil and ArchiveDate ~="" ) then | |
− | + | ArchiveDate = " " .. ArchiveDate | |
− | + | else | |
− | + | ArchiveDate = " " .. seterror('archive_missing_date') .. " " | |
− | + | end | |
+ | local arch_text = cfg.message_list['archived']; | ||
+ | if (sepc ~= ".") then arch_text = arch_text:lower() end | ||
+ | if ( "no" == DeadURL ) then | ||
+ | Archived = sepc .. " " .. externallink( ArchiveURL, arch_text ) .. " " .. | ||
+ | cfg.message_list['from'] .. " " .. cfg.message_list['original'] .. " " .. | ||
+ | cfg.message_list['on'] .. ArchiveDate | ||
+ | if OriginalURL == nil or OriginalUrl == '' then | ||
+ | Archived = Archived .. " " .. seterror('archive_missing_url_not_dead'); | ||
+ | end | ||
+ | else | ||
+ | if OriginalURL ~= nil and OriginalURL ~= '' then | ||
+ | Archived = sepc .. " " .. arch_text .. " " .. cfg.message_list['from'] .. | ||
+ | " " .. externallink( OriginalURL, cfg.message_list['original'] ) .. " " | ||
+ | .. cfg.message_list['on'] .. ArchiveDate | ||
+ | else | ||
+ | if config.CitationClass ~= 'web' then | ||
+ | Archived = sepc .. " " .. arch_text .. " " .. cfg.message_list['from'] .. " " .. | ||
+ | cfg.message_list['original'] .. seterror('archive_missing_url') .. " " .. cfg.message_list['on'] .. ArchiveDate | ||
+ | else | ||
+ | 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 | ||
+ | else | ||
+ | Archived = "" | ||
+ | end | ||
+ | local Lay | ||
+ | if ( nil ~= LaySummary and "" ~= LaySummary ) then | ||
+ | if ( LayDate ~= nil ) then LayDate = " (" .. LayDate .. ")" else LayDate = "" end | ||
+ | if ( LaySource ~= nil ) then | ||
+ | LaySource = " – ''" .. safeforitalics(LaySource) .. "''" | ||
+ | else | ||
+ | LaySource = "" | ||
+ | end | ||
+ | if sepc == '.' then | ||
+ | Lay = sepc .. " [" .. LaySummary .. " " .. cfg.message_list['lay summary'] .. "]" .. LaySource .. LayDate | ||
+ | else | ||
+ | Lay = sepc .. " [" .. LaySummary .. " " .. cfg.message_list['lay summary']:lower() .. "]" .. LaySource .. LayDate | ||
+ | end | ||
+ | else | ||
+ | Lay = "" | ||
+ | end | ||
+ | if ( nil ~= Transcript and "" ~= Transcript ) then | ||
+ | if ( TranscriptURL ~= nil ) then Transcript = externallink( TranscriptURL, Transcript ) end | ||
+ | elseif TranscriptURL ~= nil and TranscriptURL ~= "" then | ||
+ | Transcript = externallink( TranscriptURL ) | ||
+ | else | ||
+ | Transcript = "" | ||
+ | end | ||
+ | local Publisher = "" | ||
+ | if ( Periodical and Periodical ~= "" and | ||
+ | config.CitationClass ~= "encyclopaedia" and | ||
+ | config.CitationClass ~= "web" and | ||
+ | config.CitationClass ~= "pressrelease" ) then | ||
+ | if ( PublisherName ~= nil and PublisherName ~="" ) then | ||
+ | if (PublicationPlace ~= nil and PublicationPlace ~= '') then | ||
+ | Publisher = PublicationPlace .. ": " .. PublisherName; | ||
+ | else | ||
+ | Publisher = PublisherName; | ||
+ | end | ||
+ | elseif (PublicationPlace ~= nil and PublicationPlace ~= '') then | ||
+ | Publisher= PublicationPlace; | ||
+ | else | ||
+ | Publisher = ""; | ||
+ | end | ||
+ | if ( PublicationDate and PublicationDate ~="" ) then | ||
+ | if Publisher ~= '' then | ||
+ | Publisher = Publisher .. ", " .. cfg.message_list['published'] .. " " .. PublicationDate; | ||
+ | else | ||
+ | Publisher = PublicationDate; | ||
+ | end | ||
+ | end | ||
+ | if Publisher ~= "" then | ||
+ | Publisher = " (" .. Publisher .. ")"; | ||
+ | end | ||
+ | else | ||
+ | if ( PublicationDate and PublicationDate ~="" ) then | ||
+ | PublicationDate = " (" .. cfg.message_list['published'] .. " " .. PublicationDate .. ")" | ||
+ | else | ||
+ | PublicationDate = "" | ||
+ | end | ||
+ | if ( PublisherName ~= nil and PublisherName ~="" ) then | ||
+ | if (PublicationPlace ~= nil and PublicationPlace ~= '') then | ||
+ | Publisher = sepc .. " " .. PublicationPlace .. ": " .. PublisherName .. PublicationDate; | ||
+ | else | ||
+ | Publisher = sepc .. " " .. PublisherName .. PublicationDate; | ||
+ | end | ||
+ | elseif (PublicationPlace ~= nil and PublicationPlace ~= '') then | ||
+ | Publisher= sepc .. " " .. PublicationPlace .. PublicationDate; | ||
+ | else | ||
+ | Publisher = PublicationDate; | ||
+ | end | ||
+ | end | ||
+ | -- Several of the above rely upon detecting this as nil, so do it last. | ||
+ | if ( Periodical ~= nil and Periodical ~="" ) then | ||
+ | if ( Title and Title ~= "" ) or ( TitleNote and TitleNote ~= "" ) then | ||
+ | Periodical = sepc .. " ''" .. safeforitalics(Periodical) .. "''" | ||
+ | else | ||
+ | Periodical = "''" .. safeforitalics(Periodical) .. "''" | ||
+ | end | ||
+ | else Periodical = "" end | ||
− | -- | + | -- Piece all bits together at last. Here, all should be non-nil. |
− | -- | + | -- We build things this way because it is more efficient in LUA |
− | + | -- not to keep reassigning to the same string variable over and over. | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | local tcommon | |
− | + | if ( ( (config.CitationClass == "journal") or (config.CitationClass == "citation") ) and | |
− | + | Periodical ~= "" ) then | |
− | + | if (Others ~= "") then Others = Others .. sepc .. " " end | |
− | + | tcommon = safejoin( {Others, Title, TitleNote, Conference, Periodical, Format, TitleType, Series, | |
− | + | Language, Edition, Publisher, Agency, Volume, Issue, Position}, sepc ); | |
− | + | else | |
− | + | tcommon = safejoin( {Title, TitleNote, Conference, Periodical, Format, TitleType, Series, Language, | |
− | + | Volume, Issue, Others, Edition, Publisher, Agency, Position}, sepc ); | |
− | + | end | |
− | + | ||
− | + | if #ID_list > 0 then | |
− | + | 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 pgtext = Page .. Pages .. At | ||
+ | |||
+ | if ( "" ~= Authors ) then | ||
+ | if (Coauthors ~= "") | ||
+ | then Authors = Authors .. "; " .. Coauthors | ||
+ | end | ||
+ | if ( "" ~= Date ) | ||
+ | then Date = " ("..Date..")" .. OrigYear .. sepc .. " " | ||
+ | else | ||
+ | if ( string.sub(Authors,-1,-1) == sepc) --check end character | ||
+ | then Authors = Authors .. " " | ||
+ | else Authors = Authors .. sepc .. " " | ||
+ | end | ||
+ | end | ||
+ | if ( "" ~= Editors) then | ||
+ | local in_text = " in " | ||
+ | if (sepc == '.') then in_text = " In " end | ||
+ | if (string.sub(Editors,-1,-1) == sepc) | ||
+ | then Editors = in_text .. Editors .. " " | ||
+ | else Editors = in_text .. Editors .. sepc .. " " | ||
+ | end | ||
+ | end | ||
+ | text = safejoin( {Authors, Date, Chapter, Place, Editors, tcommon }, sepc ); | ||
+ | text = safejoin( {text, pgtext, idcommon}, sepc ); | ||
+ | elseif ( "" ~= Editors) then | ||
+ | if ( "" ~= Date ) then | ||
+ | if EditorCount <= 1 then | ||
+ | Editors = Editors .. ", " .. cfg.message_list['editor']; | ||
+ | else | ||
+ | Editors = Editors .. ", " .. cfg.message_list['editors']; | ||
+ | end | ||
+ | Date = " (" .. Date ..")" .. OrigYear .. sepc .. " " | ||
+ | else | ||
+ | if EditorCount <= 1 then | ||
+ | Editors = Editors .. " (" .. cfg.message_list['editor'] .. ")" .. sepc .. " " | ||
+ | else | ||
+ | Editors = Editors .. " (" .. cfg.message_list['editors'] .. ")" .. sepc .. " " | ||
+ | end | ||
+ | end | ||
+ | text = safejoin( {Editors, Date, Chapter, Place, tcommon}, sepc ); | ||
+ | text = safejoin( {text, pgtext, idcommon}, sepc ); | ||
+ | else | ||
+ | if ( "" ~= Date ) then | ||
+ | if ( string.sub(tcommon,-1,-1) ~= sepc ) | ||
+ | then Date = sepc .." " .. Date .. OrigYear | ||
+ | else Date = " " .. Date .. OrigYear | ||
+ | end | ||
+ | end -- endif ""~=Date | ||
+ | if ( config.CitationClass=="journal" and Periodical ) then | ||
+ | text = safejoin( {Chapter, Place, tcommon}, sepc ); | ||
+ | text = safejoin( {text, pgtext, Date, idcommon}, sepc ); | ||
+ | else | ||
+ | text = safejoin( {Chapter, Place, tcommon, Date}, sepc ); | ||
+ | text = safejoin( {text, pgtext, idcommon}, sepc ); | ||
+ | end | ||
+ | end | ||
+ | |||
+ | if PostScript ~= '' and PostScript ~= nil and PostScript ~= sepc then | ||
+ | text = safejoin( {text, sepc}, sepc ); --Deals with italics, spaces, etc. | ||
+ | text = text:sub(1,-2); --Remove final seperator | ||
+ | end | ||
+ | |||
+ | text = safejoin( {text, PostScript}, sepc ); | ||
+ | -- Now enclose the whole thing in a <span/> element | ||
+ | if ( Year == nil ) then | ||
+ | if ( DateIn ~= nil and DateIn ~= "" ) then | ||
+ | Year = selectyear( DateIn ) | ||
+ | elseif( PublicationDate ~= nil and PublicationDate ~= "" ) then | ||
+ | Year = selectyear( PublicationDate ) | ||
+ | else | ||
+ | Year = "" | ||
+ | end | ||
+ | end | ||
+ | local classname = "citation" | ||
+ | if ( config.CitationClass ~= "citation" ) | ||
+ | then classname = "citation " .. (config.CitationClass or "") end | ||
+ | local options = { class=classname } | ||
+ | if ( Ref ~= nil ) then | ||
+ | local id = Ref | ||
+ | if ( "harv" == Ref ) then | ||
+ | local names = {} --table of last names & year | ||
+ | if ( "" ~= Authors ) then | ||
+ | for i,v in ipairs(a) do | ||
+ | names[i] = v.last | ||
+ | if i == 4 then break end | ||
+ | end | ||
+ | elseif ( "" ~= Editors ) then | ||
+ | for i,v in ipairs(e) do | ||
+ | names[i] = v.last | ||
+ | if i == 4 then break end | ||
+ | end | ||
+ | end | ||
+ | names[ #names + 1 ] = Year; | ||
+ | id = anchorid(names) | ||
+ | end | ||
+ | options.id = id; | ||
+ | end | ||
+ | |||
+ | if string.len(text:gsub("<span[^>/]*>.-</span>", ""):gsub("%b<>","")) <= 2 then | ||
+ | z.error_categories = {}; | ||
+ | text = seterror('empty_citation'); | ||
+ | z.message_tail = {}; | ||
+ | end | ||
+ | |||
+ | 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 = '<span style="display:none;"> </span>'; | |
− | + | ||
− | + | -- Note: Using display: none on then COinS span breaks some clients. | |
− | + | local OCinS = '<span title="' .. wikiescape(OCinStitle) .. '" class="Z3988">' .. empty_span .. '</span>'; | |
− | + | text = text .. OCinS; | |
− | + | ||
− | + | if #z.message_tail ~= 0 then | |
− | + | for i,v in ipairs( z.message_tail ) do | |
− | + | if v[1] ~= nil and v[1] ~= "" then | |
− | + | 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 | |
− | + | ||
− | + | if no_tracking_cats == '' then | |
− | + | for _, v in ipairs( z.error_categories ) do | |
− | + | text = text .. '[[Category:' .. v ..']]'; | |
− | + | end | |
− | + | end | |
− | + | ||
− | + | return text | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
end | end | ||
-- This is used by templates such as {{cite book}} to create the actual citation text. | -- This is used by templates such as {{cite book}} to create the actual citation text. | ||
function z.citation(frame) | function z.citation(frame) | ||
− | + | local pframe = frame:getParent() | |
− | + | ||
− | + | local args = {}; | |
− | + | local suggestions = {}; | |
− | + | local error_text, error_state; | |
− | + | for k, v in pairs( pframe.args ) do | |
− | + | if v ~= '' then | |
− | + | if not validate( k ) then | |
− | + | error_text = ""; | |
− | + | if type( k ) ~= 'string' then | |
− | + | -- Exclude empty numbered parameters | |
− | + | if v:match("%S+") ~= nil then | |
− | + | error_text, error_state = seterror( 'text_ignored', {v}, true ); | |
− | + | end | |
− | + | elseif validate( k:lower() ) then | |
− | + | error_text, error_state = seterror( 'parameter_ignored_suggest', {k, k:lower()}, true ); | |
− | + | else | |
− | + | if #suggestions == 0 then | |
− | + | suggestions = mw.loadData( 'Module:Citation/CS1/Suggestions' ); | |
− | + | 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 | ||
+ | args[k] = v; | ||
+ | elseif k == 'postscript' then | ||
+ | args[k] = v; | ||
+ | end | ||
+ | end | ||
− | + | local config = {}; | |
− | + | for k, v in pairs( frame.args ) do | |
− | + | config[k] = v; | |
− | + | if args[k] == nil and (v ~= '' or k == 'postscript') then | |
− | + | args[k] = v; | |
− | + | end | |
− | + | end | |
− | + | ||
− | + | return citation0( config, args) | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
end | end | ||
return z | return z | ||
+ | --------------------------------------------------------------------- | ||
+ | --NOTES | ||
+ | -- | ||
+ | -- NOTE A1: This Lua module was originally designed to handle a mix | ||
+ | -- of citation styles, crossing Vancouver style with Wikipedia's | ||
+ | -- local Citation Style 1 (CS1) from {Template:Citation/core}. | ||
+ | -- However, the conflicting positions of parameters, scattered | ||
+ | -- in twisted locations across this module, led to a separate | ||
+ | -- variation just to untangle the CS1 format of citations. | ||
+ | -- | ||
+ | -- NOTE D2: The placement of dots and other separators between the | ||
+ | -- displayed parameters has been a continual headache, to keep | ||
+ | -- coordinated with the data in parentheses "(data)". There | ||
+ | -- has been a need to pre-check for the existence of related | ||
+ | -- options, to keep from putting double-dots ".." in some cases. | ||
+ | -- In particular, the omission of the "title=" parameter has led | ||
+ | -- to several cases of a spurious dot ". ." because the original | ||
+ | -- design had treated the title as a mandatory parameter. | ||
+ | -- | ||
+ | ------------------------------------------------------------------------ | ||
+ | --HISTORY: | ||
+ | --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   in "p. " 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 |