"ମଡ୍ୟୁଲ:Citation/CS1" ପୃଷ୍ଠାର ସଂସ୍କରଣ‌ଗୁଡ଼ିକ ମଧ୍ୟରେ ତଫାତ

Content deleted Content added
remove per tper
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
lang = if script_value:match('^(%l%l)%l?%s*:%s*%S.*'); then -- getif thefirst language prefix3 or nil4 ifnon-space therecharacters is noare 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
Line ୫୪୧ ⟶ ୫୪୩:
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
Line ୯୨୨ ⟶ ୯୨୫:
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 = {};
Line ୯୨୮ ⟶ ୯୩୨:
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
Line ୧,୧୬୭ ⟶ ୧,୧୭୧:
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
Line ୧,୪୯୧ ⟶ ୧,୪୯୬:
local names_table = {}; -- table made from the value assigned to |language=
 
local this_wikithis_wiki_name = mw.getContentLanguagelanguage.fetchLanguageName(cfg.this_wiki_code, cfg.this_wiki_code); -- get athis wiki's language object for this wikiname
local this_wiki_code = this_wiki:getCode() -- get this wiki's language code
local this_wiki_name = mw.language.fetchLanguageName(this_wiki_code, this_wiki_code); -- get this wiki's language name
 
names_table = mw.text.split (lang, '%s*,%s*'); -- names should be a comma separated list
Line ୧,୫୦୧ ⟶ ୧,୫୦୪:
 
if name then -- there was a remapped code so
langif =not lang:gsubmatch ('^(%a%a%a?)%-.*', 'x%-%1a+$'); then -- stripif ietfnot tagsa fromprivate ietf codetag
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?
Line ୧,୫୦୭ ⟶ ୧,୫୧୨:
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
Line ୧,୫୧୪ ⟶ ୧,୫୧୯:
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
Line ୧,୫୨୦ ⟶ ୧,୫୨୫:
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
Line ୧,୯୦୭ ⟶ ୧,୯୧୪:
 
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 empty
or empty in the source template) the function returns truethe value specified by ret_val. If the parameter value is one of the list of allowed values returns
trueof the list of allowed values returns the translated value; else, emits an error message and returns false.the value
specified 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 cfg.keywords_xlate[value]; -- return translation of parameter keyword
return true;
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
Line ୧,୯୬୫ ⟶ ୧,୯୭୩:
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
 
Line ୨,୧୬୭ ⟶ ୨,୧୭୯:
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
 
Line ୨,୧୮୭ ⟶ ୨,୨୨୧:
-- define different field names for the same underlying things.
 
local Mode = is_valid_parameter_value (A['Mode'], A:ORIGIN('Mode'), cfg.keywords_lists['mode'], '');
-- set default parameter values defined by |mode= parameter.
local Mode = A['Mode'];
if not is_valid_parameter_value (Mode, 'mode', cfg.keywords['mode']) then
Mode = '';
end
 
local author_etal;
local a = {}; -- authors list from |lastn= / |firstn= pairs or |vauthors=
local Authors;
 
local NameListFormat = A['NameListFormat'];
local NameListFormat = is_valid_parameter_value (A['NameListFormat'], A:ORIGIN('NameListFormat'), cfg.keywords_lists['name-list-format'], '');
local Collaboration = A['Collaboration'];
 
Line ୨,୨୬୮ ⟶ ୨,୨୯୯:
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
 
Line ୨,୩୧୦ ⟶ ୨,୩୩୭:
ArchiveURL, ArchiveDate = archive_url_check (A['ArchiveURL'], A['ArchiveDate'])
local UrlStatus = is_valid_parameter_value (A['UrlStatus'], A:ORIGIN('UrlStatus'), cfg.keywords_lists['url-status'], '');
 
if 'url-status' == A:ORIGIN ('UrlStatus') then -- interim: TODO: this line goes away
 
if not is_valid_parameter_value (UrlStatus, 'url-status', cfg.keywords ['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
Line ୨,୪୦୨ ⟶ ୨,୪୧୫:
 
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'];
Line ୨,୪୧୬ ⟶ ୨,୪୨୯:
end
 
local UrlAccess = is_valid_parameter_value (A['UrlAccess'], A:ORIGIN('UrlAccess'), cfg.keywords_lists['url-access'], nil);
local RegistrationRequired = A['RegistrationRequired'];
if not is_valid_parameter_value (RegistrationRequired, 'registration', cfg.keywords ['yes_true_y']) then
RegistrationRequired=nil;
end
 
local SubscriptionRequired = A['SubscriptionRequired'];
if not is_valid_parameter_value (SubscriptionRequired, 'subscription', cfg.keywords ['yes_true_y']) then
SubscriptionRequired=nil;
end
 
local UrlAccess = A['UrlAccess'];
if not is_valid_parameter_value (UrlAccess, 'url-access', cfg.keywords ['url-access']) then
UrlAccess = nil;
end
if not is_set(URL) and is_set(UrlAccess) then
UrlAccess = nil;
୨,୪୩୫ କ ଧାଡ଼ି:
end
local ChapterUrlAccess = is_valid_parameter_value (A['ChapterUrlAccess'], A:ORIGIN('ChapterUrlAccess'), cfg.keywords_lists['url-access'], nil);
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 = A['ChapterUrlAccess'];
if not is_valid_parameter_value (ChapterUrlAccess, A:ORIGIN('ChapterUrlAccess'), cfg.keywords ['url-access']) then -- same as url-access
ChapterUrlAccess = nil;
end
if not is_set(ChapterURL) and is_set(ChapterUrlAccess) then
ChapterUrlAccess = nil;
Line ୨,୪୫୩ ⟶ ୨,୪୪୧:
end
 
local MapUrlAccess = is_valid_parameter_value (A['MapUrlAccess'], A:ORIGIN('MapUrlAccess'), cfg.keywords_lists['url-access'], nil);
if not is_valid_parameter_value (MapUrlAccess, 'map-url-access', cfg.keywords ['url-access']) then
MapUrlAccess = nil;
end
if not is_set(A['MapURL']) and is_set(MapUrlAccess) then
MapUrlAccess = nil;
Line ୨,୪୭୨ ⟶ ୨,୪୫୭:
local ID = A['ID'];
local ASINTLD = A['ASINTLD'];
local IgnoreISBN = is_valid_parameter_value (A['IgnoreISBN'], A:ORIGIN('IgnoreISBN'), cfg.keywords_lists['yes_true_y'], nil);
if not is_valid_parameter_value (IgnoreISBN, 'ignore-isbn-error', cfg.keywords ['yes_true_y']) then
IgnoreISBN = nil; -- anything else, set to empty string
end
local Embargo = A['Embargo'];
local Class = A['Class']; -- arxiv class identifier
Line ୨,୪୯୫ ⟶ ୨,୪୭୭:
local TranscriptURLorigin = A:ORIGIN('TranscriptURL'); -- get name of parameter that holds TranscriptURL
 
local LastAuthorAmp = is_valid_parameter_value (A['LastAuthorAmp'], A:ORIGIN('LastAuthorAmp'), cfg.keywords_lists['yes_true_y'], nil);
if not is_valid_parameter_value (LastAuthorAmp, 'last-author-amp', cfg.keywords ['yes_true_y']) then
LastAuthorAmp = nil; -- set to empty string
end
 
local no_tracking_cats = is_valid_parameter_value (A['NoTracking'], A:ORIGIN('NoTracking'), cfg.keywords_lists['yes_true_y'], nil);
if not is_valid_parameter_value (no_tracking_cats, 'no-tracking', cfg.keywords ['yes_true_y']) then
no_tracking_cats = nil; -- set to empty string
end
 
--local variables that are not cs1 parameters
Line ୨,୫୧୧ ⟶ ୨,୪୮୭:
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'], A:ORIGIN('DF'), cfg.keywords_lists['df'], '');
local DF = A['DF']; -- date format set in cs1|2 template
if not is_valid_parameter_value (DF, 'df', cfg.keywords['date-format']) 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
DF = cfg.global_df;
end
 
Line ୨,୫୪୫ ⟶ ୨,୫୧୮:
Page, Pages, At, coins_pages = insource_loc_get (Page, Pages, At);
 
local NoPP = is_valid_parameter_value (A['NoPP'], A:ORIGIN('NoPP'), cfg.keywords_lists['yes_true_y'], nil);
if is_set (NoPP) and is_valid_parameter_value (NoPP, 'nopp', cfg.keywords ['yes_true_y']) 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
Line ୨,୫୭୯ ⟶ ୨,୫୫୬:
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;
Line ୨,୬୫୦ ⟶ ୨,୬୨୭:
Chapter = A['Map'];
ChapterURL = A['MapURL'];
ChapterUrlAccess = MapUrlAccess;
TransChapter = A['TransMap'];
ChapterURLorigin = A:ORIGIN('MapURL');
TransChapter = A['TransMap'];
ScriptChapter = A['ScriptMap']
ScriptChapterOrigin = A:ORIGIN('ScriptMap')
 
ChapterUrlAccess = MapUrlAccess;
ChapterFormat = A['MapFormat'];
 
Cartography = A['Cartography'];
if is_set( Cartography ) then
Line ୨,୭୦୦ ⟶ ୨,୬୮୦:
Chapter = Title; -- promote title parameters to chapter
ScriptChapter = ScriptTitle;
-- ScriptChapterOrigin = 'title';
ScriptChapterOrigin = A:ORIGIN('ScriptTitle');
ChapterLink = TitleLink; -- alias episodelink
TransChapter = TransTitle;
Line ୨,୭୩୮ ⟶ ୨,୭୧୯:
end
 
Periodical = ({['arxiv'] = 'arXiv', ['biorxiv'] = 'bioRxiv', ['citeseerx'] = 'CiteSeerX', ['ssrn'] = 'Social Science Research Network'})[config.CitationClass];
end
end
Line ୩,୦୩୬ ⟶ ୩,୦୧୭:
 
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
Line ୩,୦୪୩ ⟶ ୩,୦୨୩:
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
Line ୩,୦୫୫ ⟶ ୩,୦୩୫:
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
Line ୩,୦୯୧ ⟶ ୩,୦୭୧:
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
Line ୩,୨୭୫ ⟶ ୩,୨୫୫:
------------------------------------ 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
Line ୩,୩୨୩ ⟶ ୩,୨୯୦:
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'];
Archived = sepc .. " " .. 'Archived from the original on ' .. ArchiveDate; -- format already styled
if sepc ~= "." then arch_text = arch_text:lower() end
Archived = sepc .. " " .. arch_text .. ArchiveDate; -- format already styled
if 'bot: unknown' == UrlStatus then
add_maint_cat ('bot:_unknown'); -- and add a category if not already added
Line ୩,୩୪୫ ⟶ ୩,୩୧୩:
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
else
local arch_text = cfg.messages['archived-missing'];
if sepc ~= "." then arch_text = arch_text:lower() end
Archived = sepc .. " " .. substitute( arch_text,
Line ୩,୪୬୭ ⟶ ୩,୪୩୭:
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
Line ୩,୬୨୪ ⟶ ୩,୫୯୪:
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));
Line ୩,୮୫୩ ⟶ ୩,୮୨୪:
else
error_text, error_state = set_error( 'parameter_ignored', {param}, true ); -- suggested param not supported by this template
v = ''; -- unset
end
end
Line ୩,୮୮୩ ⟶ ୩,୮୫୫:
end
end
 
return table.concat ({citation0( config, args), frame:extensionTag ('templatestyles', '', {src=styles})});
end