Module:Citation/CS1: Difference between revisions
Synch from sandbox;
m>Trappist the monk (Better version of strip_apostrophe_markup()?) |
m>Trappist the monk (Synch from sandbox;) |
||
Line 37: | Line 37: | ||
--[[ | --[[ | ||
Categorize and emit an error message when the citation contains one or more deprecated parameters. Because deprecated parameters (currently | Categorize and emit an error message when the citation contains one or more deprecated parameters. Because deprecated parameters (currently |month=, | ||
|coauthor=, and |coauthors=) aren't related to each other and because these parameters may be concatenated into the variables used by |date= and |author#= (and aliases) | |coauthor=, and |coauthors=) aren't related to each other and because these parameters may be concatenated into the variables used by |date= and |author#= (and aliases) | ||
details of which parameter caused the error message are not provided. Only one error message is emitted regardless of the number of deprecated parameters in the citation. | details of which parameter caused the error message are not provided. Only one error message is emitted regardless of the number of deprecated parameters in the citation. | ||
Line 50: | Line 50: | ||
-- Populates numbered arguments in a message string using an argument table. | -- Populates numbered arguments in a message string using an argument table. | ||
function substitute( msg, args ) | function substitute( msg, args ) | ||
return args and mw.message.newRawMessage( msg, args ):plain() or msg; | return args and mw.message.newRawMessage( msg, args ):plain() or msg; | ||
end | end | ||
--[[ | --[[--------------------------< K E R N _ Q U O T E S >-------------------------------------------------------- | ||
Apply kerning to open the space between the quote mark provided by the Module and a leading or trailing quote mark contained in a |title= or |chapter= parameter's value. | Apply kerning to open the space between the quote mark provided by the Module and a leading or trailing quote mark contained in a |title= or |chapter= parameter's value. | ||
This function will positive kern | This function will positive kern either single or double quotes: | ||
"'Unkerned title with leading and trailing single quote marks'" | "'Unkerned title with leading and trailing single quote marks'" | ||
" 'Kerned title with leading and trailing single quote marks' " (in real life the kerning isn't as wide as this example) | " 'Kerned title with leading and trailing single quote marks' " (in real life the kerning isn't as wide as this example) | ||
Double single quotes (italic or bold wikimarkup) are not kerned. | |||
Call this function for chapter titles, for website titles, etc; not for book titles. | |||
]] | ]] | ||
function kern_quotes (str) | function kern_quotes (str) | ||
local | local cap=''; | ||
local | local cap2=''; | ||
cap, cap2 = str:match ("^([\"\'])([^\'].+)"); -- match leading double or single quote but not double single quotes | |||
str = | if is_set (cap) then | ||
str = substitute (cfg.presentation['kern-left'], {cap, cap2}); | |||
end | end | ||
str = | cap, cap2 = str:match ("^(.+[^\'])([\"\'])$") | ||
if is_set (cap) then | |||
str = substitute (cfg.presentation['kern-right'], {cap, cap2}); | |||
end | end | ||
return str; | return str; | ||
Line 110: | Line 118: | ||
if is_set (name) then -- is prefix a proper ISO 639-1 language code? | if is_set (name) then -- is prefix a proper ISO 639-1 language code? | ||
script_value = script_value:gsub ('^%l%l%s*:%s*', ''); -- strip prefix from script | script_value = script_value:gsub ('^%l%l%s*:%s*', ''); -- strip prefix from script | ||
if inArray (lang, {'ar', 'ja', 'ko', 'he', 'zh'}) then | -- is prefix one of these language codes? | ||
if inArray (lang, {'ar', 'bs', 'dv', 'el', 'fa', 'hy', 'ja', 'ko', 'ku', 'he', 'ps', 'ru', 'sd', 'sr', 'th', 'uk', 'ug', 'yi', 'zh'}) then | |||
table.insert( z.properties_cats, 'CS1 uses ' .. name .. '-language script ('..lang..')'); -- categorize in language-specific categories | table.insert( z.properties_cats, 'CS1 uses ' .. name .. '-language script ('..lang..')'); -- categorize in language-specific categories | ||
else | else | ||
Line 120: | Line 129: | ||
end | end | ||
end | end | ||
script_value = ' | script_value = substitute (cfg.presentation['bdi'], {lang, script_value}); -- isolate in case script is rtl | ||
return script_value; | return script_value; | ||
Line 141: | Line 150: | ||
end | end | ||
-- | |||
function | --[[--------------------------< W R A P _ S T Y L E >---------------------------------------------------------- | ||
Applies styling to various parameters. Supplied string is wrapped using a message_list configuration taking one | |||
argument; protects italic styled parameters. Additional text taken from citation_config.presentation - the reason | |||
this function is similar to but separate from wrap_msg(). | |||
]] | |||
function wrap_style (key, str) | |||
if not is_set( str ) then | if not is_set( str ) then | ||
return ""; | return ""; | ||
Line 148: | Line 165: | ||
str = safeforitalics( str ); | str = safeforitalics( str ); | ||
end | end | ||
if | |||
return substitute( cfg.presentation[key], {str} ); | |||
end | |||
--[[--------------------------< W R A P _ M S G >-------------------------------------------------------------- | |||
Applies additional message text to various parameter values. Supplied string is wrapped using a message_list | |||
configuration taking one argument. Supports lower case text for {{citation}} templates. Additional text taken | |||
from citation_config.messages - the reason this function is similar to but separate from wrap_style(). | |||
]] | |||
function wrap_msg (key, str, lower) | |||
if not is_set( str ) then | |||
return ""; | |||
end | |||
if true == lower then | |||
local msg; | |||
msg = cfg.messages[key]:lower(); -- set the message to lower case before | |||
str = substitute( msg, {str} ); -- including template text | |||
return str; | |||
else | else | ||
return substitute( cfg.messages[key], {str} ); | return substitute( cfg.messages[key], {str} ); | ||
Line 155: | Line 192: | ||
end | end | ||
--[[ | --[[--------------------------< F O R M A T _ C H A P T E R _ T I T L E >-------------------------------------- | ||
Format the three chapter parameters: |chapter=, |trans-chapter=, and |chapter-url= into a single Chapter meta- | |||
parameter (chapter_url_source used for error messages). | |||
]] | ]] | ||
function argument_wrapper( args ) | |||
function format_chapter_title (chapter, transchapter, chapterurl, chapter_url_source) | |||
local chapter_error = ''; | |||
if not is_set (chapter) then | |||
chapter = ''; -- just to be safe for concatenation | |||
if is_set (transchapter) then | |||
chapter = wrap_style ('trans-quoted-title', transchapter); | |||
chapter_error = " " .. seterror ('trans_missing_chapter'); | |||
end | |||
if is_set (chapterurl) then | |||
chapter = externallink (chapterurl, chapter, chapter_url_source); -- adds bare_url_missing_title error if appropriate | |||
end | |||
return chapter .. chapter_error; | |||
else -- here when chapter is set | |||
chapter = kern_quotes (chapter); -- if necessary, separate chapter title's leading and trailing quote marks from Module provided quote marks | |||
chapter = wrap_style ('quoted-title', chapter); | |||
if is_set (transchapter) then | |||
transchapter = wrap_style ('trans-quoted-title', transchapter); | |||
chapter = chapter .. ' ' .. transchapter; | |||
end | |||
if is_set (chapterurl) then | |||
chapter = externallink (chapterurl, chapter); -- adds bare_url_missing_title error if appropriate | |||
end | |||
end | |||
return chapter; | |||
end | |||
--[[ | |||
Argument wrapper. This function provides support for argument | |||
mapping defined in the configuration file so that multiple names | |||
can be transparently aliased to single internal variable. | |||
]] | |||
function argument_wrapper( args ) | |||
local origin = {}; | local origin = {}; | ||
Line 233: | Line 304: | ||
end | end | ||
-- | --[[--------------------------< E R R O R C O M M E N T >------------------------------------------------------ | ||
Wraps error messages with css markup according to the state of hidden. | |||
]] | |||
function errorcomment( content, hidden ) | function errorcomment( content, hidden ) | ||
return | return substitute( hidden and cfg.presentation['hidden-error'] or cfg.presentation['visible-error'], content ); | ||
end | end | ||
Line 303: | Line 378: | ||
label = URL; | label = URL; | ||
if is_set( source ) then | if is_set( source ) then | ||
error_str = seterror( 'bare_url_missing_title', { | error_str = seterror( 'bare_url_missing_title', { wrap_style ('parameter', source) }, false, " " ); | ||
else | else | ||
error( cfg.messages["bare_url_no_origin"] ); | error( cfg.messages["bare_url_no_origin"] ); | ||
Line 314: | Line 389: | ||
end | end | ||
-- | --[[--------------------------< N O W R A P _ D A T E >-------------------------------------------------------- | ||
function | |||
if | When date is YYYY-MM-DD format wrap in nowrap span: <span ...>YYYY-MM-DD</span>. When date is DD MMMM YYYY or is | ||
MMMM DD, YYYY then wrap in nowrap span: <span ...>DD MMMM</span> YYYY or <span ...>MMMM DD,</span> YYYY | |||
DOES NOT yet support MMMM YYYY or any of the date ranges. | |||
]] | |||
function nowrap_date (date) | |||
local cap=''; | |||
local cap2=''; | |||
if date:match("^%d%d%d%d%-%d%d%-%d%d$") then | |||
date = substitute (cfg.presentation['nowrap1'], date); | |||
elseif date:match("%a+%s*%d%d?,%s*%d%d%d%d") or date:match ("%d%d?%s*%a+%s*%d%d%d%d") then | |||
cap, cap2 = string.match (date, "^(.*)%s+(%d%d%d%d)$"); | |||
date = substitute (cfg.presentation['nowrap2'], {cap, cap2}); | |||
end | end | ||
if not is_set(domain) then | |||
domain = "com"; | return date; | ||
elseif inArray (domain, {'jp', 'uk'}) then -- Japan, United Kingdom | end | ||
domain = "co." .. domain; | |||
--[[--------------------------< A M A Z O N >------------------------------------------------------------------ | |||
Formats a link to Amazon. Do simple error checking: asin must be mix of 10 numeric or uppercase alpha | |||
characters. If a mix, first character must be uppercase alpha; if all numeric, asins must be 10-digit | |||
isbn. If 10-digit isbn, add a maintenance category so a bot or awb script can replace |asin= with |isbn=. | |||
Error message if not 10 characters, if not isbn10, if mixed and first character is a digit. | |||
]] | |||
function amazon(id, domain) | |||
local err_cat = "" | |||
if not id:match("^[%d%u][%d%u][%d%u][%d%u][%d%u][%d%u][%d%u][%d%u][%d%u][%d%u]$") then | |||
err_cat = ' ' .. seterror ('bad_asin'); -- asin is not a mix of 10 uppercase alpha and numeric characters | |||
else | |||
if id:match("^%d%d%d%d%d%d%d%d%d%d$") then -- if 10-digit numeric | |||
if checkisbn( id ) then -- see if asin value is isbn10 | |||
table.insert( z.maintenance_cats, "CS1 maint: ASIN uses ISBN"); -- add to maint category | |||
elseif not is_set (err_cat) then | |||
err_cat = ' ' .. seterror ('bad_asin'); -- asin is not isbn10 | |||
end | |||
elseif not id:match("^%u[%d%u]+$") then | |||
err_cat = ' ' .. seterror ('bad_asin'); -- asin doesn't begin with uppercase alpha | |||
end | |||
end | |||
if not is_set(domain) then | |||
domain = "com"; | |||
elseif inArray (domain, {'jp', 'uk'}) then -- Japan, United Kingdom | |||
domain = "co." .. domain; | |||
elseif inArray (domain, {'au', 'br', 'mx'}) then -- Australia, Brazil, Mexico | elseif inArray (domain, {'au', 'br', 'mx'}) then -- Australia, Brazil, Mexico | ||
domain = "com." .. domain; | domain = "com." .. domain; | ||
Line 329: | Line 448: | ||
return externallinkid({link = handler.link, | return externallinkid({link = handler.link, | ||
label=handler.label , prefix="//www.amazon."..domain.."/dp/",id=id, | label=handler.label , prefix="//www.amazon."..domain.."/dp/",id=id, | ||
encode=handler.encode, separator = handler.separator}) | encode=handler.encode, separator = handler.separator}) .. err_cat; | ||
end | end | ||
Line 647: | Line 766: | ||
return text | return text | ||
end | end | ||
--[[--------------------------< M E S S A G E _ I D >---------------------------------------------------------- | |||
Validate and format a usenet message id. Simple error checking, looks for 'id-left@id-right' not enclosed in | |||
'<' and/or '>' angle brackets. | |||
]] | |||
function message_id (id) | |||
local handler = cfg.id_handlers['USENETID']; | |||
text = externallinkid({link = handler.link, label = handler.label, | |||
prefix=handler.prefix,id=id,separator=handler.separator, encode=handler.encode}) | |||
if not id:match('^.+@.+$') or not id:match('^[^<].*[^>]$')then -- doesn't have '@' or has one or first or last character is '< or '>' | |||
text = text .. ' ' .. seterror( 'bad_message_id' ) -- add an error message if the message id is invalid | |||
end | |||
return text | |||
end | |||
--[[ | --[[ | ||
Line 1,018: | Line 1,159: | ||
end | end | ||
if ( "scap" == format ) then -- apply smallcaps formatting when authorformat or editorformat set to scap | |||
if ( "scap" == format ) then result = | result = substitute (cfg.presentation['smallcaps'], result); | ||
end | end | ||
return result, count | return result, count | ||
Line 1,088: | Line 1,228: | ||
end | end | ||
-- Takes a table of IDs and turns it into a table of formatted ID outputs. | --[[--------------------------< B U I L D I D L I S T >-------------------------------------------------------- | ||
Takes a table of IDs and turns it into a table of formatted ID outputs. | |||
]] | |||
function buildidlist( id_list, options ) | function buildidlist( id_list, options ) | ||
local new_list, handler = {}; | local new_list, handler = {}; | ||
function fallback(k) return { __index = function(t,i) return cfg.id_handlers[k][i] end } end; | function fallback(k) return { __index = function(t,i) return cfg.id_handlers[k][i] end } end; | ||
Line 1,126: | Line 1,269: | ||
end | end | ||
table.insert( new_list, {handler.label, ISBN } ); | table.insert( new_list, {handler.label, ISBN } ); | ||
elseif k == 'USENETID' then | |||
table.insert( new_list, {handler.label, message_id( v ) } ); | |||
else | else | ||
error( cfg.messages['unknown_manual_ID'] ); | error( cfg.messages['unknown_manual_ID'] ); | ||
Line 1,185: | Line 1,330: | ||
for _, k in ipairs( error_list ) do | for _, k in ipairs( error_list ) do | ||
if error_str ~= "" then error_str = error_str .. cfg.messages['parameter-separator'] end | if error_str ~= "" then error_str = error_str .. cfg.messages['parameter-separator'] end | ||
error_str = error_str .. | error_str = error_str .. wrap_style ('parameter', k); | ||
end | end | ||
if #error_list > 1 then | if #error_list > 1 then | ||
Line 1,192: | Line 1,337: | ||
error_str = error_str .. cfg.messages['parameter-pair-separator']; | error_str = error_str .. cfg.messages['parameter-pair-separator']; | ||
end | end | ||
error_str = error_str .. | error_str = error_str .. wrap_style ('parameter', selected); | ||
table.insert( z.message_tail, { seterror( error_condition, {error_str}, true ) } ); | table.insert( z.message_tail, { seterror( error_condition, {error_str}, true ) } ); | ||
end | end | ||
Line 1,220: | Line 1,365: | ||
OCinSoutput.rft_val_fmt = "info:ofi/fmt:kev:mtx:book"; | OCinSoutput.rft_val_fmt = "info:ofi/fmt:kev:mtx:book"; | ||
OCinSoutput["rft.genre"] = "bookitem"; | OCinSoutput["rft.genre"] = "bookitem"; | ||
OCinSoutput["rft. | OCinSoutput["rft.atitle"] = data.Chapter; | ||
OCinSoutput["rft. | OCinSoutput["rft.btitle"] = data.Title; | ||
elseif is_set(data.Periodical) then | elseif is_set(data.Periodical) then | ||
OCinSoutput.rft_val_fmt = "info:ofi/fmt:kev:mtx:journal"; | OCinSoutput.rft_val_fmt = "info:ofi/fmt:kev:mtx:journal"; | ||
Line 1,334: | Line 1,479: | ||
the page is a mainspace page and the ISO639-1 code is not 'en'. Similarly, if the parameter is |language=Norwegian, it will be categorized in the same way. | the page is a mainspace page and the ISO639-1 code is not 'en'. Similarly, if the parameter is |language=Norwegian, it will be categorized in the same way. | ||
]] | ]] | ||
Line 1,358: | Line 1,502: | ||
if is_set (code) then | if is_set (code) then | ||
if 'no' == code then name = 'Norwegian' end; -- override wikimedia when code is 'no' | if 'no' == code then name = 'Norwegian' end; -- override wikimedia when code is 'no' | ||
if 0 == namespace and 'en' ~= code then -- is this page main / article space and English not the language? | |||
table.insert( z.properties_cats, 'CS1 ' .. name .. '-language sources (' .. code .. ')'); -- in main space and not English: categorize | |||
end | end | ||
return (" " .. | else | ||
table.insert (z.maintenance_cats, 'CS1 maint: Unrecognized language'); -- add maintenance category when |language= does not appear to be ISO 639-1 language | |||
end | |||
return (" " .. wrap_msg ('language', name)); -- wrap with '(in ...)' | |||
end | end | ||
Line 1,409: | Line 1,555: | ||
local TitleLink = A['TitleLink']; | local TitleLink = A['TitleLink']; | ||
local Chapter = A['Chapter']; | local Chapter = A['Chapter']; | ||
local ChapterLink = A['ChapterLink']; | local ChapterLink = A['ChapterLink']; -- deprecated | ||
local TransChapter = A['TransChapter']; | local TransChapter = A['TransChapter']; | ||
local TitleType = A['TitleType']; | local TitleType = A['TitleType']; | ||
Line 1,445: | Line 1,591: | ||
local Language = A['Language']; | local Language = A['Language']; | ||
local Format = A['Format']; | local Format = A['Format']; | ||
local ChapterFormat = A['ChapterFormat']; | |||
local Ref = A['Ref']; | local Ref = A['Ref']; | ||
local DoiBroken = A['DoiBroken']; | local DoiBroken = A['DoiBroken']; | ||
Line 1,453: | Line 1,600: | ||
local ID_list = extractids( args ); | local ID_list = extractids( args ); | ||
local Quote = A['Quote']; | local Quote = A['Quote']; | ||
local PostScript = A['PostScript']; | local PostScript = A['PostScript']; | ||
Line 1,477: | Line 1,617: | ||
local Callsign = A['Callsign']; | local Callsign = A['Callsign']; | ||
local City = A['City']; | local City = A['City']; | ||
local Program = A['Program']; | local Program = A['Program']; | ||
--local variables that are not cs1 parameters | --local variables that are not cs1 parameters | ||
local | local use_lowercase; -- controls capitalization of certain static text | ||
local this_page = mw.title.getCurrentTitle(); -- also used for COinS and for language | |||
local this_page = mw.title.getCurrentTitle(); -- | |||
local anchor_year; -- used in the CITEREF identifier | local anchor_year; -- used in the CITEREF identifier | ||
local COinS_date; -- used in the COinS metadata | local COinS_date; -- used in the COinS metadata | ||
Line 1,535: | Line 1,672: | ||
|trans_title maps to |trans_chapter when |title is re-mapped | |trans_title maps to |trans_chapter when |title is re-mapped | ||
|url maps to |chapterurl when |title is remapped | |||
All other combinations of |encyclopedia, |title, and |article are not modified | All other combinations of |encyclopedia, |title, and |article are not modified | ||
Line 1,544: | Line 1,682: | ||
Chapter = Title; -- |encyclopedia and |title are set so map |title to |article and |encyclopedia to |title | Chapter = Title; -- |encyclopedia and |title are set so map |title to |article and |encyclopedia to |title | ||
TransChapter = TransTitle; | TransChapter = TransTitle; | ||
ChapterURL = URL; | |||
Title = Periodical; | Title = Periodical; | ||
Periodical = ''; -- redundant so unset | Periodical = ''; -- redundant so unset | ||
TransTitle = ''; -- redundant so unset | TransTitle = ''; -- redundant so unset | ||
URL = ''; -- redundant so unset | |||
end | end | ||
else -- |title not set | else -- |title not set | ||
Line 1,568: | Line 1,708: | ||
end | end | ||
end | end | ||
use_lowercase = ( sepc ~= '.' ); -- used to control capitalization for certain static text | |||
-- check for special case where |separator=none | -- check for special case where |separator=none | ||
Line 1,606: | Line 1,747: | ||
end | end | ||
if is_set( | if is_set(Others) then | ||
if is_set(TitleType) then | if is_set(TitleType) then | ||
Others = ' ' .. TitleType .. ' with ' .. | Others = ' ' .. TitleType .. ' with ' .. Others; | ||
TitleType = ''; | TitleType = ''; | ||
else | else | ||
Others = ' ' .. 'Interview with ' .. | Others = ' ' .. 'Interview with ' .. Others; | ||
end | end | ||
else | else | ||
Line 1,671: | Line 1,809: | ||
-- end of {{cite episode}} stuff]] | -- end of {{cite episode}} stuff]] | ||
-- legacy: promote concatenation of | -- legacy: promote concatenation of |month=, and |year= to Date if Date not set; or, promote PublicationDate to Date if neither Date nor Year are set. | ||
if | if is_set(Date) then | ||
if is_set (Year) then | |||
table.insert( z.maintenance_cats, "CS1 maint: Date and year"); -- add to maint category | |||
end | |||
else | |||
Date = Year; -- promote Year to Date | Date = Year; -- promote Year to Date | ||
Year = nil; -- make nil so Year as empty string isn't used for CITEREF | Year = nil; -- make nil so Year as empty string isn't used for CITEREF | ||
Line 1,679: | Line 1,821: | ||
if is_set(Month) then | if is_set(Month) then | ||
Date = Month .. " " .. Date; | Date = Month .. " " .. Date; | ||
end | end | ||
elseif is_set(PublicationDate) then -- use PublicationDate when |date= and |year= are not set | elseif is_set(PublicationDate) then -- use PublicationDate when |date= and |year= are not set | ||
Line 1,735: | Line 1,875: | ||
end | end | ||
]] | ]] | ||
-- special case for cite newsgroup. Do this after COinS because we are modifying Publishername | -- special case for cite newsgroup. Do this after COinS because we are modifying Publishername to include som static text | ||
if 'newsgroup' == config.CitationClass then | if 'newsgroup' == config.CitationClass then | ||
if is_set (PublisherName) then | if is_set (PublisherName) then | ||
PublisherName = '[Newsgroup]: ' .. externallink( 'news:' .. PublisherName, PublisherName ); | PublisherName = '[[Newsgroup]]: ' .. externallink( 'news:' .. PublisherName, PublisherName ); | ||
end | end | ||
end | end | ||
Line 1,750: | Line 1,890: | ||
if not is_set(Authors) then | if not is_set(Authors) then | ||
local Maximum = tonumber( A['DisplayAuthors'] ); | local Maximum = tonumber( A['DisplayAuthors'] ); | ||
if is_set (Maximum) then | |||
if | if Maximum >= #a then -- if display-authors value greater than or equal to number of authors | ||
Maximum = | table.insert( z.maintenance_cats, "CS1 maint: display-authors"); -- add maintenance category because display-authors parameter may be removed | ||
end | |||
else | |||
Maximum = #a + 1; | Maximum = #a + 1; -- number of authors + 1 | ||
end | end | ||
local control = { | local control = { | ||
sep = A["AuthorSeparator"] .. " ", | sep = A["AuthorSeparator"] .. " ", | ||
Line 1,798: | Line 1,938: | ||
maximum = Maximum, | maximum = Maximum, | ||
lastauthoramp = LastAuthorAmp, | lastauthoramp = LastAuthorAmp, | ||
page_name = this_page.text -- get current page name so that we don't wikilink to it via | page_name = this_page.text -- get current page name so that we don't wikilink to it via editorlinkn | ||
}; | }; | ||
Line 1,815: | Line 1,955: | ||
Cartography = A['Cartography']; | Cartography = A['Cartography']; | ||
if is_set( Cartography ) then | if is_set( Cartography ) then | ||
Cartography = sepc .. " " .. | Cartography = sepc .. " " .. wrap_msg ('cartography', Cartography, use_lowercase); | ||
end | end | ||
Scale = A['Scale']; | Scale = A['Scale']; | ||
Line 1,823: | Line 1,963: | ||
end | end | ||
Format = is_set(Format) and " (" .. Format .. ")" or ""; | |||
if not is_set(URL) and | if not is_set(URL) and | ||
not is_set(ArchiveURL) and | not is_set(ArchiveURL) and | ||
not is_set(ConferenceURL) and | not is_set(ConferenceURL) and | ||
Line 1,835: | Line 1,976: | ||
-- Test if accessdate is given without giving a URL | -- Test if accessdate is given without giving a URL | ||
if is_set(AccessDate) then | if is_set(AccessDate) and not is_set(ChapterURL)then -- ChapterURL may be set when the others are not set; TODO: move this to a separate test? | ||
table.insert( z.message_tail, { seterror( 'accessdate_missing_url', {}, true ) } ); | table.insert( z.message_tail, { seterror( 'accessdate_missing_url', {}, true ) } ); | ||
AccessDate = ''; | AccessDate = ''; | ||
Line 1,842: | Line 1,983: | ||
-- Test if format is given without giving a URL | -- Test if format is given without giving a URL | ||
if is_set(Format) then | if is_set(Format) then | ||
Format = Format .. seterror( 'format_missing_url' ); | Format = Format .. seterror( 'format_missing_url', {'format', 'url'} ); | ||
end | end | ||
end | end | ||
-- Test if citation has no title | -- Test if citation has no title | ||
if not is_set(Title) and | if not is_set(Title) and | ||
Line 1,855: | Line 1,996: | ||
end | end | ||
local OriginalURL; | |||
local OriginalURL | DeadURL = DeadURL:lower(); -- used later when assembling archived text | ||
DeadURL = DeadURL:lower(); | |||
if is_set( ArchiveURL ) then | if is_set( ArchiveURL ) then | ||
if ( DeadURL | if is_set (URL) then | ||
OriginalURL = URL; -- save copy of original source URL | |||
if 'no' ~= DeadURL then -- if URL set then archive-url applies to it | |||
URL = ArchiveURL -- swap-in the archive's url | |||
URLorigin = A:ORIGIN('ArchiveURL') -- name of archive url parameter for error messages | |||
end | |||
elseif is_set (ChapterURL) then -- URL not set so if chapter-url is set apply archive url to it | |||
OriginalURL = ChapterURL; -- save copy of source chapter's url for archive text | |||
if 'no' ~= DeadURL then | |||
ChapterURL = ArchiveURL -- swap-in the archive's url | |||
URLorigin = A:ORIGIN('ArchiveURL') -- name of archive url parameter for error messages | |||
end | |||
end | end | ||
end | end | ||
if inArray(config.CitationClass, {"web","news","journal","pressrelease","conference","podcast", "newsgroup"}) or ('citation' == config.CitationClass and is_set (Periodical)) then | |||
if is_set (Chapter) or is_set (TransChapter) or is_set (ChapterURL)then -- chapter parameters not supported for these citation types | |||
table.insert( z.message_tail, { seterror( 'chapter_ignored', {}, true ) } ); -- add error message | |||
Chapter = ''; -- set to empty string to be safe with concatenation | |||
TransChapter = ''; | |||
ChapterURL = ''; | |||
end | |||
else -- otherwise, format chapter / article title | |||
Chapter = format_chapter_title (Chapter, TransChapter, ChapterURL, ChapterURLorigin); | |||
if is_set (Chapter) then | |||
ChapterFormat = is_set(ChapterFormat) and " (" .. ChapterFormat .. ")" or ""; | |||
if is_set(ChapterFormat) and not is_set (ChapterURL) then -- Test if |chapter-format= is given without giving a |chapter-url= | |||
ChapterFormat = ChapterFormat .. seterror( 'format_missing_url', {'chapter-format', 'chapter-url'} ); | |||
end | |||
Chapter = Chapter .. ChapterFormat .. sepc .. ' '; | |||
end | end | ||
end | end | ||
-- Format main title. | -- Format main title. | ||
if is_set(TitleLink) and is_set(Title) then | if is_set(TitleLink) and is_set(Title) then | ||
Line 1,916: | Line 2,038: | ||
end | end | ||
if inArray(config.CitationClass, {"web","news","journal","pressrelease","conference","podcast"}) then | if inArray(config.CitationClass, {"web","news","journal","pressrelease","conference","podcast", "newsgroup"}) or ('citation' == config.CitationClass and is_set (Periodical)) then | ||
Title = kern_quotes (Title); -- if necessary, separate title's leading and trailing quote marks from Module provided quote marks | Title = kern_quotes (Title); -- if necessary, separate title's leading and trailing quote marks from Module provided quote marks | ||
Title = | Title = wrap_style ('quoted-title', Title); | ||
Title = script_concatenate (Title, ScriptTitle); -- <bdi> tags, lang atribute, categorization, etc; must be done after title is wrapped | Title = script_concatenate (Title, ScriptTitle); -- <bdi> tags, lang atribute, categorization, etc; must be done after title is wrapped | ||
TransTitle = | TransTitle= wrap_style ('trans-quoted-title', TransTitle ); | ||
else | else | ||
Title = | Title = wrap_style ('italic-title', Title); | ||
Title = script_concatenate (Title, ScriptTitle); -- <bdi> tags, lang atribute, categorization, etc; must be done after title is wrapped | Title = script_concatenate (Title, ScriptTitle); -- <bdi> tags, lang atribute, categorization, etc; must be done after title is wrapped | ||
TransTitle = | TransTitle = wrap_style ('trans-italic-title', TransTitle); | ||
end | end | ||
Line 1,950: | Line 2,072: | ||
if is_set(Place) then | if is_set(Place) then | ||
Place = " " .. | Place = " " .. wrap_msg ('written', Place, use_lowercase) .. sepc .. " "; | ||
end | end | ||
Line 2,011: | Line 2,133: | ||
if first_set( Pages, Page, At ) ~= nil or sepc ~= '.' then | if first_set( Pages, Page, At ) ~= nil or sepc ~= '.' then | ||
if is_set( Section ) then | if is_set( Section ) then | ||
Section = ", " .. | Section = ", " .. wrap_msg ('section', Section, true); | ||
end | end | ||
if is_set( Inset ) then | if is_set( Inset ) then | ||
Inset = ", " .. | Inset = ", " .. wrap_msg ('inset', Inset, true); | ||
end | end | ||
else | else | ||
if is_set( Section ) then | if is_set( Section ) then | ||
Section = sepc .. " " .. | Section = sepc .. " " .. wrap_msg ('section', Section, use_lowercase); | ||
if is_set( Inset ) then | if is_set( Inset ) then | ||
Inset = ", " .. | Inset = ", " .. wrap_msg ('inset', Inset, true); | ||
end | end | ||
elseif is_set( Inset ) then | elseif is_set( Inset ) then | ||
Inset = sepc .. " " .. | Inset = sepc .. " " .. wrap_msg ('inset', Inset, use_lowercase); | ||
end | end | ||
end | end | ||
Line 2,051: | Line 2,173: | ||
TitleNote = is_set(TitleNote) and (sepc .. " " .. TitleNote) or ""; | TitleNote = is_set(TitleNote) and (sepc .. " " .. TitleNote) or ""; | ||
Edition = is_set(Edition) and (" " .. | Edition = is_set(Edition) and (" " .. wrap_msg ('edition', Edition)) or ""; | ||
Issue = is_set(Issue) and (" (" .. Issue .. ")") or ""; | Issue = is_set(Issue) and (" (" .. Issue .. ")") or ""; | ||
Series = is_set(Series) and (sepc .. " " .. Series) or ""; | Series = is_set(Series) and (sepc .. " " .. Series) or ""; | ||
Line 2,064: | Line 2,186: | ||
end | end | ||
------------------------------------ totally unrelated data | ------------------------------------ totally unrelated data | ||
if is_set(Via) then | if is_set(Via) then | ||
Via = " " .. | Via = " " .. wrap_msg ('via', Via); | ||
end | end | ||
--[[ | |||
Subscription implies paywall; Registration does not. If both are used in a citation, the subscription required link | |||
note is displayed. There are no error messages for this condition. | |||
]] | |||
if is_set(SubscriptionRequired) then | if is_set(SubscriptionRequired) then | ||
SubscriptionRequired = sepc .. " " .. cfg.messages['subscription']; -- | SubscriptionRequired = sepc .. " " .. cfg.messages['subscription']; -- subscription required message | ||
elseif is_set(RegistrationRequired) then | elseif is_set(RegistrationRequired) then | ||
SubscriptionRequired = sepc .. " " .. cfg.messages['registration']; -- | SubscriptionRequired = sepc .. " " .. cfg.messages['registration']; -- registration required message | ||
end | end | ||
if is_set(AccessDate) then | if is_set(AccessDate) then | ||
local retrv_text = " " .. cfg.messages['retrieved'] | local retrv_text = " " .. cfg.messages['retrieved'] | ||
if (sepc ~= ".") then retrv_text = retrv_text:lower() end | |||
AccessDate = ' | AccessDate = nowrap_date (AccessDate); -- wrap in nowrap span if date in appropriate format | ||
if (sepc ~= ".") then retrv_text = retrv_text:lower() end -- if 'citation', lower case | |||
AccessDate = substitute (retrv_text, AccessDate); -- add retrieved text | |||
-- neither of these work; don't know why; it seems that substitute() isn't being called | |||
AccessDate = substitute (cfg.presentation['accessdate'], {sepc, AccessDate}); -- allow editors to hide accessdates | |||
end | end | ||
Line 2,103: | Line 2,217: | ||
end | end | ||
ID_list = buildidlist( ID_list, {DoiBroken = DoiBroken, ASINTLD = ASINTLD, IgnoreISBN = IgnoreISBN, Embargo=Embargo} ); | ID_list = buildidlist( ID_list, {DoiBroken = DoiBroken, ASINTLD = ASINTLD, IgnoreISBN = IgnoreISBN, Embargo=Embargo} ); | ||
Line 2,114: | Line 2,227: | ||
Quote = Quote:sub(2,-2); | Quote = Quote:sub(2,-2); | ||
end | end | ||
Quote = sepc .." " .. | Quote = sepc .." " .. wrap_style ('quoted-text', Quote ); -- wrap in <q>...</q> tags | ||
PostScript = ""; | PostScript = ""; -- CS1 does not supply terminal punctuation when |quote= is set | ||
end | end | ||
Line 2,185: | Line 2,298: | ||
if is_set(PublicationDate) then | if is_set(PublicationDate) then | ||
if is_set(Publisher) then | if is_set(Publisher) then | ||
Publisher = Publisher .. ", " .. | Publisher = Publisher .. ", " .. wrap_msg ('published', PublicationDate); | ||
else | else | ||
Publisher = PublicationDate; | Publisher = PublicationDate; | ||
Line 2,195: | Line 2,308: | ||
else | else | ||
if is_set(PublicationDate) then | if is_set(PublicationDate) then | ||
PublicationDate = " (" .. | PublicationDate = " (" .. wrap_msg ('published', PublicationDate) .. ")"; | ||
end | end | ||
if is_set(PublisherName) then | if is_set(PublisherName) then | ||
Line 2,213: | Line 2,326: | ||
if is_set(Periodical) then | if is_set(Periodical) then | ||
if is_set(Title) or is_set(TitleNote) then | if is_set(Title) or is_set(TitleNote) then | ||
Periodical = sepc .. " " .. | Periodical = sepc .. " " .. wrap_style ('italic-title', Periodical) | ||
else | else | ||
Periodical = | Periodical = wrap_style ('italic-title', Periodical) | ||
end | end | ||
end | end |