Open main menu

Changes

Module:Citation/CS1

1,030 bytes removed, 12:32, 11 January 2020
sync from sandbox;
if not added_prop_cats [key] then
added_prop_cats [key] = true; -- note that we've added this category
key = key:gsub ('(foreign_lang_source_?2?)%a%a%a?[%a%-]*', '%1'); -- strip lang code from keyname
table.insert( z.properties_cats, substitute (cfg.prop_cats [key], arguments)); -- make name then add to table
end
local lang=''; -- initialize to empty string
local name;
-- if script_value:match('^%l%l%s*:') then -- if first 3 non-space characters are script language prefix if script_value:match('^%l%l%l?%s*:') then -- if first 3 or 4 non-space characters are script language prefix-- lang = script_value:match('^(%l%l)%s*:%s*%S.*'); -- get the language prefix or nil if there is no script lang = script_value:match('^(%l%l%l?)%s*:%s*%S.*'); -- get the language prefix or nil if there is no script
if not is_set (lang) then
table.insert( z.message_tail, { set_error( 'script_parameter', {script_param, 'missing title part'}, true ) } ); -- prefix without 'title'; add error message
end
-- if we get this far we have prefix and script
name = cfg.lang_code_remap[lang] or mw.language.fetchLanguageName( lang, "en" cfg.this_wiki_code ); -- get language name so that we can use it to categorize
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+%s*:%s*', ''); -- strip prefix from script
-- is prefix one of these language codes?
if in_array (lang, cfg.script_lang_codes) then
str = str:gsub ('&[nm]dash;', {['–'] = '–', ['—'] = '—'}); -- replace — and – entities with their characters; semicolon mucks up the text.split
str = str:gsub ('-', '-'); -- replace html numeric entity with hyphen character
local out = {};
for _, item in ipairs (list) do -- for each item in the list
if mw.ustring.match (item, '^%w*[%.%-]?%w+%s*[%-–—]%s*%w*[%.%-]?%w+$') then -- if a hyphenated range or has endash or emdash separators
if item:match ('^%a+[%.%-]?%d+%s*%-%s*%a+[%.%-]?%d+$') or -- letterdigit hyphen letterdigit (optional separator between letter and digit) item:match ('^%d+[%.%-]?%a+%s*%-%s*%d+[%.%-]?%a+$') or -- digitletter hyphen digitletter (optional separator between digit and letter) item:match ('^%d+[%.%-]%d+%s*%-%s*%d+[%.%-]%d+$') or -- digit separator digit hyphen digit separator digit item:match ('^%d+%s*%-%s*%d+$') or -- digit hyphen digit item:match ('^%a+%s*%-%s*%a+$') then -- letter hyphen letter
item = item:gsub ('(%w*[%.%-]?%w+)%s*%-%s*(%w*[%.%-]?%w+)', '%1–%2'); -- replace hyphen, remove extraneous space characters
else
sep = cfg.presentation['sep_nl_vanc']; -- name-list separator between authors is a comma
namesep = cfg.presentation['sep_name_vanc']; -- last/first separator is a space
lastauthoramp = nil; -- unset because isn't used by Vancouver style
else
sep = cfg.presentation['sep_nl']; -- name-list separator between authors is a semicolon
local names_table = {}; -- table made from the value assigned to |language=
local this_wiki = mw.getContentLanguage(); -- get a language object for this wiki local this_wiki_code = this_wiki:getCode() -- get this wiki's language code local this_wiki_name = mw.language.fetchLanguageName(cfg.this_wiki_code, cfg.this_wiki_code); -- get this wiki's language name
names_table = mw.text.split (lang, '%s*,%s*'); -- names should be a comma separated list
if name then -- there was a remapped code so
if not lang:match ('^%a%a%a?%-x%-%a+$') then -- if not a private ietf tag lang = lang:gsub ('^(%a%a%a?)%-.*', '%1'); -- strip ietf tags from code end
else
if lang:match ('^%a%a%-') then -- strip ietf tags from code; TODO: is there a need to support 3-char with tag?
end
if 2 == lang:len() or 3 == lang:len() then -- if two-or three-character code
name = mw.language.fetchLanguageName (lang:lower(), cfg.this_wiki_code); -- get language name if |language= is a proper code
end
end
code = lang:lower(); -- save it
else
name, code = get_iso639_code (lang, cfg.this_wiki_code); -- attempt to get code from name (assign name here so that we are sure of proper capitalization)
end
name = cfg.lang_code_remap[code] or name; -- override wikimedia when they misuse language codes/names
if cfg.this_wiki_code ~= code then -- when the language is not the same as this wiki's language
if 2 == code:len() then -- and is a two-character code
add_prop_cat ('foreign_lang_source' .. code, {name, code}) ; -- categorize it; code appended to allow for multiple language categorization
else -- or is a recognized language (but has a three-character code)
add_prop_cat ('foreign_lang_source_2' .. code, {code}) ; -- categorize it differently TODO: support mutliple three-character code categories per cs1|2 template
end
elseif cfg.local_lang_cat_enable then -- when the language and this wiki's language are the same and categorization is enabled
add_prop_cat ('local_lang_source', {name, code}); -- categorize it
end
else
This function is used to validate a parameter's assigned value for those parameters that have only a limited number
of allowable values (yes, y, true, nolive, dead, etc). When the parameter value has not been assigned a value (missing or emptyin the source template) the function returns truethe value specified by ret_val. If the parameter value is one of the list of allowed values returnstruethe translated value; else, emits an error message and returns falsethe valuespecified by ret_val.
]]
local function is_valid_parameter_value (value, name, possible, ret_val)
if not is_set (value) then
return trueret_val; -- an empty parameter is ok
elseif in_array (value, possible) then
return truecfg.keywords_xlate[value]; -- return translation of parameter keyword
else
table.insert( z.message_tail, { set_error( 'invalid_param_val', {name, value}, true ) } ); -- not an allowed value so add error message
return falseret_val;
end
end
return wrap_msg ('issue', {sepc, issue}, lower);
end
end
 
if 'podcast' == cite_class and is_set (issue) then
return wrap_msg ('issue', {sepc, issue}, lower);
end
return url, date; -- preview mode so return archiveURL and ArchiveDate
end
end
 
 
--[[--------------------------< P L A C E _ C H E C K >--------------------------------------------------------
 
check |place=, |publication-place=, |location= to see if these params include digits. This function added because
many editors mis-use location to specify the in-source location (|page(s)= and |at= are supposed to do that)
 
returns the original parameter value without modification; added maint cat when parameter value contains digits
 
]]
 
local function place_check (param_val)
if not is_set (param_val) then -- parameter empty or omitted
return param_val; -- return that empty state
end
if mw.ustring.find (param_val, '%d') then -- not empty, are there digits in the parameter value
add_maint_cat ('location'); -- yep, add maint cat
end
return param_val; -- and done
end
-- define different field names for the same underlying things.
-- set default parameter values defined by |mode= parameter. local Mode = is_valid_parameter_value (A['Mode']; if not is_valid_parameter_value , A:ORIGIN('Mode, 'mode'), cfg.keywordskeywords_lists['mode']) then Mode = , ''); end
local author_etal;
local a = {}; -- authors list from |lastn= / |firstn= pairs or |vauthors=
local Authors;
  local NameListFormat = is_valid_parameter_value (A['NameListFormat'], A:ORIGIN('NameListFormat'), cfg.keywords_lists['name-list-format'], '');
local Collaboration = A['Collaboration'];
end
Contribution = nil; -- unset
end
 
if not is_valid_parameter_value (NameListFormat, 'name-list-format', cfg.keywords['name-list-format']) then -- only accepted value for this parameter is 'vanc'
NameListFormat = ''; -- anything else, set to empty string
end
ArchiveURL, ArchiveDate = archive_url_check (A['ArchiveURL'], A['ArchiveDate'])
local UrlStatus = is_valid_parameter_value (A['UrlStatus']; if 'url-status' == , A:ORIGIN ('UrlStatus') then -- interim: TODO: this line goes away if not is_valid_parameter_value (UrlStatus, 'url-status', cfg.keywords keywords_lists['url-status']) then -- set in config.defaults to 'dead' UrlStatus = ''; -- anything else, set to empty string end -- interim: TODO: this line goes away elseif is_set (A:ORIGIN ('UrlStatus')) then -- interim: while both |dead-url= and |url-status= allowed use separate keyword lists; TODO: remove this section if not is_valid_parameter_value (UrlStatus, A:ORIGIN ('UrlStatus'), cfg.keywords ['deadurl']) then -- interim: assume |dead-url=; use those keywords; TODO: this line goes away UrlStatus = ''; -- anything else, set to empty string; interim: TODO: this line goes away end -- interim: TODO: this line goes away end -- interim: TODO: this line goes away if in_array (UrlStatus, {'yes', 'true', 'y'}) then -- TODO: remove this whole thing when |dead-url=[yes|no] parameters removed from articles UrlStatus = 'dead'; elseif 'no' == UrlStatus then UrlStatus = 'live'; end
local URL = A['URL']
local URLorigin = A:ORIGIN('URL'); -- get name of parameter that holds URL
local Edition = A['Edition'];
local PublicationPlace = place_check (A['PublicationPlace'], A:ORIGIN('PublicationPlace')); local Place = place_check (A['Place'], A:ORIGIN('Place'));
local PublisherName = A['PublisherName'];
end
local RegistrationRequired UrlAccess = A['RegistrationRequired']; if not is_valid_parameter_value (RegistrationRequired, 'registration', cfg.keywords ['yes_true_y']) then RegistrationRequired=nil; end  local SubscriptionRequired = A['SubscriptionRequiredUrlAccess']; if not is_valid_parameter_value (SubscriptionRequired, 'subscription', cfg.keywords ['yes_true_y']) then SubscriptionRequired=nil; end  local UrlAccess = A[:ORIGIN('UrlAccess']; if not is_valid_parameter_value (UrlAccess, 'url-access'), cfg.keywords keywords_lists['url-access'], nil) then UrlAccess = nil; end
if not is_set(URL) and is_set(UrlAccess) then
UrlAccess = nil;
end
if is_set (UrlAccess) and is_set (SubscriptionRequired) then -- while not aliases, these are much the same so if both are set table.insert( z.message_tail, { set_error( 'redundant_parameters', {wrap_style ('parameter', 'url-access') .. ' and ' .. wrap_style ('parameter', 'subscription')}, true ) } ); -- add error message SubscriptionRequired = nil; -- unset; prefer |access= over |subscription= end if is_set (UrlAccess) and is_set (RegistrationRequired) then -- these are not the same but contradictory so if both are set table.insert( z.message_tail, { set_error( 'redundant_parameters', {wrap_style ('parameter', 'url-access') .. ' and ' .. wrap_style ('parameter', 'registration')}, true ) } ); -- add error message RegistrationRequired = nil; -- unset; prefer |access= over |registration= end  local ChapterUrlAccess = is_valid_parameter_value (A['ChapterUrlAccess']; if not is_valid_parameter_value (ChapterUrlAccess, A:ORIGIN('ChapterUrlAccess'), cfg.keywords keywords_lists['url-access'], nil) then -- same as url-access ChapterUrlAccess = nil; end
if not is_set(ChapterURL) and is_set(ChapterUrlAccess) then
ChapterUrlAccess = nil;
end
local MapUrlAccess = is_valid_parameter_value (A['MapUrlAccess']; if not is_valid_parameter_value , A:ORIGIN('MapUrlAccess, 'map-url-access'), cfg.keywords keywords_lists['url-access'], nil) then MapUrlAccess = nil; end
if not is_set(A['MapURL']) and is_set(MapUrlAccess) then
MapUrlAccess = nil;
local ID = A['ID'];
local ASINTLD = A['ASINTLD'];
local IgnoreISBN = is_valid_parameter_value (A['IgnoreISBN']; if not is_valid_parameter_value , A:ORIGIN('IgnoreISBN, 'ignore-isbn-error'), cfg.keywords keywords_lists['yes_true_y'], nil) then IgnoreISBN = nil; -- anything else, set to empty string end
local Embargo = A['Embargo'];
local Class = A['Class']; -- arxiv class identifier
local TranscriptURLorigin = A:ORIGIN('TranscriptURL'); -- get name of parameter that holds TranscriptURL
local LastAuthorAmp = is_valid_parameter_value (A['LastAuthorAmp']; if not is_valid_parameter_value , A:ORIGIN('LastAuthorAmp, 'last-author-amp'), cfg.keywords keywords_lists['yes_true_y'], nil) then LastAuthorAmp = nil; -- set to empty string end
local no_tracking_cats = is_valid_parameter_value (A['NoTracking']; if not is_valid_parameter_value , A:ORIGIN(no_tracking_cats, 'no-trackingNoTracking'), cfg.keywords keywords_lists['yes_true_y'], nil) then no_tracking_cats = nil; -- set to empty string end
--local variables that are not cs1 parameters
local COinS_date = {}; -- holds date info extracted from |date= for the COinS metadata by Module:Date verification
local DF = is_valid_parameter_value (A['DF']; -- date format set in cs1|2 template if not is_valid_parameter_value , A:ORIGIN('DF, 'df'), cfg.keywordskeywords_lists['date-formatdf']) then -- validate reformatting keyword DF = , ''); -- not valid, set to empty string end
if not is_set (DF) then
DF = cfg.global_df; -- local df if present overrides global df set by {{use xxx date}} template
end
Page, Pages, At, coins_pages = insource_loc_get (Page, Pages, At);
local NoPP = is_valid_parameter_value (A['NoPP'] if is_set , A:ORIGIN('NoPP') and is_valid_parameter_value (NoPP, 'nopp', cfg.keywords keywords_lists['yes_true_y'], nil) then NoPP = true; else NoPP = nil; -- unset, used as a flag later end
if not is_set(PublicationPlace) and is_set(Place) then -- both |publication-place= and |place= (|location=) allowed if different add_prop_cat ('location test'); -- add property cat to evaluate how often PublicationPlace and Place are used together if PublicationPlace == Place then Place = ''; -- unset; don't need both if they are the same end elseif not is_set (PublicationPlace) and is_set (Place) then -- when only |place= (|location=) is set ...
PublicationPlace = Place; -- promote |place= (|location=) to |publication-place
end
 -- if not is_set(PublicationPlace) and is_set(Place) then -- both |publication-place= and |place= (|location=) allowed if different-- PublicationPlace = Place; -- promote |place= (|location=) to |publication-place-- end--
if PublicationPlace == Place then Place = ''; end -- don't need both if they are the same
Chapter = Title; -- |encyclopedia and |title are set so map |title to |article and |encyclopedia to |title
ScriptChapter = ScriptTitle;
ScriptChapterOrigin = A:ORIGIN('titleScriptTitle';)
TransChapter = TransTitle;
ChapterURL = URL;
Chapter = A['Map'];
ChapterURL = A['MapURL'];
ChapterURLorigin = A:ORIGIN('MapURL');
TransChapter = A['TransMap'];
ScriptChapter = A['ScriptMap']
ScriptChapterOrigin = A:ORIGIN('ScriptMap')
 
ChapterUrlAccess = MapUrlAccess;
TransChapter = A['TransMap'];
ChapterURLorigin = A:ORIGIN('MapURL');
ChapterFormat = A['MapFormat'];
Cartography = A['Cartography'];
if is_set( Cartography ) then
Chapter = Title; -- promote title parameters to chapter
ScriptChapter = ScriptTitle;
-- ScriptChapterOrigin = 'title'; ScriptChapterOrigin = A:ORIGIN('titleScriptTitle');
ChapterLink = TitleLink; -- alias episodelink
TransChapter = TransTitle;
end
Periodical = ({['arxiv'] = 'arXiv', ['biorxiv'] = 'bioRxiv', ['citeseerx'] = 'CiteSeerX', ['ssrn'] = 'Social Science Research Network'})[config.CitationClass];
end
end
local OriginalURL, OriginalURLorigin, OriginalFormat, OriginalAccess;
-- DeadURL = DeadURL:lower(); -- used later when assembling archived text
UrlStatus = UrlStatus:lower(); -- used later when assembling archived text
if is_set( ArchiveURL ) then
OriginalURLorigin = ChapterURLorigin; -- name of chapter-url parameter for error messages
OriginalFormat = ChapterFormat; -- and original |chapter-format=
-- if 'no' ~= DeadURL then
if 'live' ~= UrlStatus then
ChapterURL = ArchiveURL -- swap-in the archive's url
OriginalFormat = Format; -- and original |format=
OriginalAccess = UrlAccess;
-- if 'no' ~= DeadURL then -- if URL set then archive-url applies to it
if 'live' ~= UrlStatus then -- if URL set then archive-url applies to it
URL = ArchiveURL -- swap-in the archive's url
local no_quotes = false; -- default assume that we will be quoting the chapter parameter value
if is_set (Contribution) and 0 < #c then -- if this is a contribution with contributor(s)
if in_array (Contribution:lower(), cfg.keywordskeywords_lists.contribution) then -- and a generic contribution title
no_quotes = true; -- then render it unquoted
end
------------------------------------ totally unrelated data
Via = is_set (Via) and wrap_msg ('via', Via) or '';
 
--[[
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
SubscriptionRequired = sepc .. " " .. cfg.messages['subscription']; -- subscription required message
elseif is_set (RegistrationRequired) then
SubscriptionRequired = sepc .. " " .. cfg.messages['registration']; -- registration required message
else
SubscriptionRequired = ''; -- either or both might be set to something other than yes true y
end
if is_set(AccessDate) then
local Archived
if is_set(ArchiveURL) then
local arch_text;
if not is_set(ArchiveDate) then
ArchiveDate = set_error('archive_missing_date');
end
if "live" == UrlStatus then
local arch_text = cfg.messages['archived'];
if sepc ~= "." then arch_text = arch_text:lower() end
Archived = sepc .. " " .. substitute( cfg.messages['archived-live'],
{ external_link( ArchiveURL, arch_text, A:ORIGIN('ArchiveURL'), nil ) .. ArchiveFormat, ArchiveDate } );
if not is_set(OriginalURL) then
Archived = Archived .. " " .. set_error('archive_missing_url');
end
elseif is_set(OriginalURL) then -- UrlStatus is empty, 'dead', 'unfit', 'usurped', 'bot: unknown'
local arch_text = cfg.messages['archived-dead'];
if sepc ~= "." then arch_text = arch_text:lower() end
if in_array (UrlStatus, {'unfit', 'usurped', 'bot: unknown'}) then
arch_text = cfg.messages['archived-unfit']; if sepc ~= "." then arch_text = arch_text:lower() end Archived = sepc .. " " .. 'Archived from the original on ' arch_text .. ArchiveDate; -- format already styled
if 'bot: unknown' == UrlStatus then
add_maint_cat ('bot:_unknown'); -- and add a category if not already added
end
else -- UrlStatus is empty, 'dead'
arch_text = cfg.messages['archived-dead'];
if sepc ~= "." then arch_text = arch_text:lower() end
Archived = sepc .. " " .. substitute( arch_text,
{ external_link( OriginalURL, cfg.messages['original'], OriginalURLorigin, OriginalAccess ) .. OriginalFormat, ArchiveDate } ); -- format already styled
end
else -- OriginalUrl not set local arch_text = cfg.messages['archived-missing'];
if sepc ~= "." then arch_text = arch_text:lower() end
Archived = sepc .. " " .. substitute( arch_text,
local idcommon;
if 'audio-visual' == config.CitationClass or 'episode' == config.CitationClass then -- special case for cite AV media & cite episode position transcript
idcommon = safe_join( { ID_list, URL, Archived, Transcript, AccessDate, Via, SubscriptionRequired, Lay, Quote }, sepc );
else
idcommon = safe_join( { ID_list, URL, Archived, AccessDate, Via, SubscriptionRequired, Lay, Quote }, sepc );
end
end
-- no_tracking_cats = no_tracking_cats:lower(); -- if in_array(no_tracking_cats, {"", "no", "false", "n"}) then if not no_tracking_cats then
for _, v in ipairs( z.error_categories ) do
table.insert (render, make_wikilink ('Category:' .. v));
else
error_text, error_state = set_error( 'parameter_ignored', {param}, true ); -- suggested param not supported by this template
v = ''; -- unset
end
end
end
end
 
return table.concat ({citation0( config, args), frame:extensionTag ('templatestyles', '', {src=styles})});
end