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

Content deleted Content added
bug fix in language_parameter();
No edit summary
୧ କ ଧାଡ଼ି:
 
 
local cs1 ={};
Line ୧୦୯ ⟶ ୧୦୮:
There are several tests:
the first character of the whole domain name including subdomains must be a letter or a digit
internationalized domain name (ascii characters with .xn-- ASCII Compatible Encoding (ACE) prefix xn-- in the tld) see https://tools.ietf.org/html/rfc3490
single-letter/digit second-level domains in the .org TLD
q, x, and z SL domains in the .com TLD
୧୩୨ କ ଧାଡ଼ି:
end
-- Do most common case first
if domain:match ('%f[%a%d][%a%d][%a%d%-]+[%a%d]%.%a%a+$') then -- three or more character hostname.hostname or hostname.tld
return true;
elseif domain:match ('%f[%a%d][%a%d][%a%d%-]+[%a%d]%.xn%-%-[%a%d]+$') then -- internationalized domain name with ACE prefix
return true;
elseif domain:match ('%f[%a%d][%a%d]%.org$') then -- one character .org hostname
Line ୨୪୩ ⟶ ୨୪୫:
local orig;
 
if is_set (link) then -- don't bother if <param>-link doesn't have a value
if not link_param_ok (link) then -- check |<param>-link= markup
orig = lorig; -- identify the failing link parameter
elseif title:find ('%[%[') then -- check |title= for wikilink markup
orig = torig; -- identify the failing link|title= parameter
end
end
Line ୩୬୬ ⟶ ୩୬୮:
local function external_link( URL, label, source )
local error_str = "";
local domain;
local path;
if not is_set( label ) then
label = URL;
Line ୩୭୭ ⟶ ୩୮୨:
error_str = set_error( 'bad_url', {wrap_style ('parameter', source)}, false, " " ) .. error_str;
end
domain, path = URL:match ('^([/%.%-%+:%a%d]+)([/%?#].*)$'); -- split the url into scheme plus domain and path
if path then -- if there is a path portion
path = path:gsub ('[%[%]]', {['[']='%5b',[']']='%5d'}); -- replace '[' and ']' with their percent encoded values
URL=domain..path; -- and reassemble
end
return table.concat({ "[", URL, " ", safe_for_url( label ), "]", error_str });
end
 
 
--[[--------------------------< D E P R E C A T E D _ P A R A M E T E R >--------------------------------------
Line ୫୯୦ ⟶ ୬୦୩:
if position then
-- if 'nowiki' == capture or 'math' == capture or ('ref' == capture and 'quote' == param) then -- nowiki, math, or quote param and ref stripmarker (not an error condition)
if 'nowiki' == capture or 'math' == capture then -- nowiki, math stripmarker (not an error condition)
stripmarker = true; -- set a flag
elseif true == stripmarker and 'delete' == char then -- because stripmakers begin and end with the delete char, assume that we've found one end of a stripmarker
position = nil; -- unset
elseif 'apostrophe' == char then -- apostrophe template uses &zwj;, hair space and zero-width space
apostrophe = true;
elseif true == apostrophe and in_array (char, {'zero width joiner', 'zero width space', 'hair space'}) then
position = nil; -- unset
else
Line ୮୯୪ ⟶ ୯୦୨:
]]
 
local function list_people(control, people, etal, list_name) -- TODO: why is list_name here? not used in this function
local sep;
local namesep;
Line ୧,୦୨୦ ⟶ ୧,୦୨୮:
end
return name, etal; --
end
 
--[[--------------------------< N A M E _ H A S _ M U L T _ N A M E S >----------------------------------------
 
Evaluates the content of author and editor (surnames only) parameters for multiple names. Multiple names are
indicated if there is more than one comma and or semicolon. If found, the function adds the multiple name
(author or editor) maintenance category.
 
]]
 
local function name_has_mult_names (name, list_name)
local count, _;
if is_set (name) then
if name:match ('^%(%(.*%)%)$') then -- if wrapped in doubled parentheses, ignore
name = name:match ('^%(%((.*)%)%)$'); -- strip parens
else
_, count = name:gsub ('[;,]', ''); -- count the number of separator-like characters
if 1 < count then -- param could be |author= or |editor= so one separactor character is acceptable
add_maint_cat ('mult_names', list_name:lower()); -- more than one separator indicates multiple names so add a maint cat for this template
end
end
end
return name; -- and done
end
 
Line ୧,୦୫୬ ⟶ ୧,୦୮୮:
mask = select_one( args, cfg.aliases[list_name .. '-Mask'], 'redundant_parameters', i );
 
last, etal = name_has_etal (last, etal, false); -- find and remove variations on et al.
first, etal = name_has_etal (first, etal, false); -- find and remove variations on et al.
last = name_has_mult_names (last, err_msg_list_name); -- check for multiple names in last and its aliases
 
if first and not last then -- if there is a firstn without a matching lastn
table.insert( z.message_tail, { set_error( 'first_missing_last', {err_msg_list_name, i}, true ) } ); -- add this error message
Line ୧,୦୮୪ ⟶ ୧,୧୧୭:
--[[--------------------------< G E T _ I S O 6 3 9 _ C O D E >------------------------------------------------
 
Validates language names provided in |language= parameter if not an ISO639-1 or 639-2 code.
 
Returns the language name and associated ISO639two-1 or three-character code. Because case of the source may be incorrect or different from the case that Wikimedia
or different from the case that WikiMedia uses, the name comparisons are done in lower case and when a match is
found, the Wikimedia version (assumed to be correct) is returned along with the code. When there is no match, we
with the code. When there is no match, we return the original language name string.
 
mw.language.fetchLanguageNames(<local wiki language>, 'all') will return a list of languages that aren'tin partsome of ISO639-1. Names that aren't ISO639-1 but thatcases aremay includedinclude
extensions. For example, code 'cbk-zam' and its associated name 'Chavacano de Zamboanga' (MediaWiki does not support
in the list will be found if that name is provided in the |language= parameter. For example, if |language=Samaritan Aramaic, that name will be
code 'cbk' or name 'Chavacano'.
found with the associated code 'sam', not an ISO639-1 code. When names are found and the associated code is not two characters, this function
 
returns only the Wikimedia language name.
Names but that are included in the list will be found if that name is provided in the |language= parameter. For example,
if |language=Chavacano de Zamboanga, that name will be found with the associated code 'cbk-zam'. When names are found
and the associated code is not two or three characters, this function returns only the Wikimedia language name.
 
Adapted from code taken from Module:Check ISO 639-1.
Line ୧,୧୦୬ ⟶ ୧,୧୪୩:
for code, name in pairs(languages) do -- scan the list to see if we can find our language
if langlc == mw.ustring.lower(name) then
if 2 ~= code:len() and 3 ~= code:len() then -- ISO639two-1 or three-character codes only; extensions not supported
return name; -- so return the name but not the code
end
return name, code; -- found it, return name to ensure proper capitalization and the ISO639-1the code
end
end
return lang; -- not valid language; return language in original case and nil for ISO639-1the code
end
 
--[[--------------------------< L A N G U A G E _ P A R A M E T E R >------------------------------------------
 
GetGets language name from ISO639a provided two-1 codeor valuethree-character providedISO 639 code. If a code is validrecognized by MediaWiki,
use the returned name; if not, then use the value that was provided with the language parameter.
 
When |language= contains a recognized language (either code or name), the page is assigned to the category for
that code: Category:Norwegian-language sources (no). For valid three-character code languages, the page is assigned
to the single category for '639-2' codes: Category:CS1 ISO 639-2 language sources.
 
Languages that are the same as the local wiki are not categorized. MediaWiki does not recognize three-character
When |language= contains a valid ISO639-1 code, the page is assigned to the category for that code: Category:Norwegian-language sources (no) if
equivalents of two-character codes: code 'ar' is recognized bit code 'ara' is not.
the page is a mainspace page and the ISO639-1 code is not the local wiki's language code. Similarly, if the parameter is |language=Norwegian,
it will be categorized in the same way.
 
This function supports multiple languages in the form |language=nb, French, th where the language names or codes are
separated from each other by commas.
 
]]
 
local function language_parameter (lang)
local code; -- the ISO639two-1 twoor three-character language code
local name; -- the language name
local language_list = {}; -- table of language names to be rendered
Line ୧,୧୪୧ ⟶ ୧,୧୮୩:
for _, lang in ipairs (names_table) do -- reuse lang
 
if lang:match ('^%a%a%-') then -- strip ietf language tags from code; TODO: is there a need to support 3-char with tag?
lang = lang:match ('(%a%a)%-') -- keep only 639-1 code portion to lang; TODO: do something with 3166 alpha 2 country code?
end
if 2 == lang:len() or 3 == lang:len() then -- ISO639if two-1or languagethree-character code are 2 characters (fetchLanguageName also supports 3 character codes)
name = mw.language.fetchLanguageName( lang:lower(), this_wiki_code); -- get ISO 639-1 language name if Language|language= is a proper code
end
if is_set (name) then -- if Language|language= specified a valid ISO639-1 code
code = lang:lower(); -- save it
else
Line ୧,୧୫୪ ⟶ ୧,୧୯୬:
end
if is_set (code) then -- only 2- or 3-character codes
if 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', {name, code}) -- categorize it
add_prop_cat ('foreign_lang_source', {name, code}) -- categorize it
else -- or is a recognized language (but has a three-character code)
add_prop_cat ('foreign_lang_source_2', {code}) -- categorize it differently TODO: support mutliple three-character code categories per cs1|2 template
end
end
else
Line ୧,୬୦୬ ⟶ ୧,୬୫୨:
return '', '', '', ''; -- return empty strings
end
 
 
--[=[-------------------------< A R C H I V E _ U R L _ C H E C K >--------------------------------------------
 
Check archive.org urls to make sure they at least look like they are pointing at valid archives and not to the
save snapshot url. When the archive url is 'https://web.archive.org/save/' (or http://...) archive.org saves a snapshot
of the target page in the url. That is something that Wikipedia should not allow unwitting readers to do.
 
When the archive.org url does not have a complete timestamp, archive.org chooses a snapshot according to its own
algorithm or provides a 'search' result. [[WP:ELNO]] discourages links to search results.
 
This function looks at the value assigned to |archive-url= and returns empty strings for |archive-url= and
|archive-date= and an error message when:
|archive-url= holds an archive.org save command url
|archive-url= is an archive.org url that does not have a complete timestamp (YYYYMMDDhhmmss 14 digits) in the correct place
otherwise returns |archive-url= and |archive-date=
 
]=]
 
local function archive_url_check (url, date)
if url:match('//web\.archive\.org/') then -- for archive.org urls:
if url:match('//web\.archive\.org/save/') then -- if a save command url, we don't want to save target page
table.insert( z.message_tail, { set_error( 'archive_url', {'save command'}, true ) } ); -- add error message
return '', ''; -- return empty strings for archiveURL and ArchiveDate
elseif url:match('//web\.archive\.org/web/%d%d%d%d%d%d%d%d%d%d%d%d%d%d/') then -- if there is what looks like a correct timestamp
return url, date; -- return archiveURL and ArchiveDate
else -- malformed url
table.insert( z.message_tail, { set_error( 'archive_url', {'timestamp'}, true ) } ); -- add error message
return '', ''; -- return empty strings for archiveURL and ArchiveDate
end
end
return url, date; -- not an archive.org archive
end
 
 
--[[--------------------------< M I S S I N G _ P I P E _ C H E C K >------------------------------------------
 
Look at the contents of a parameter. If the content has a string of characters and digits followed by an equal
sign, compare the alphanumeric string to the list of cs1|2 parameters. If found, then the string is possibly a
parameter that is missing its pipe:
{{cite ... |title=Title access-date=2016-03-17}}
 
cs1|2 shares some parameter names with xml/html atributes: class=, title=, etc. To prevent false positives xml/html
tags are removed before the search.
 
If a missing pipe is detected, this function adds the missing pipe maintenance category.
 
]]
 
local function missing_pipe_check (value)
local capture;
value = value:gsub ('%b<>', ''); -- remove xml/html tags because attributes: class=, title=, etc
 
capture = value:match ('%s+(%a[%a%d]+)%s*=') or value:match ('^(%a[%a%d]+)%s*='); -- find and categorize parameters with possible missing pipes
if capture and validate (capture) then -- if the capture is a valid parameter name
add_maint_cat ('missing_pipe');
end
end
 
 
--[[--------------------------< C I T A T I O N 0 >------------------------------------------------------------
Line ୧,୭୧୭ ⟶ ୧,୮୨୨:
local Docket = A['Docket'];
local ArchiveFormat = A['ArchiveFormat'];
 
local ArchiveURL = A['ArchiveURL'];
local ArchiveDate;
local ArchiveURL;
 
ArchiveURL, ArchiveDate = archive_url_check (A['ArchiveURL'], A['ArchiveDate'])
-- local ArchiveDate = A['ArchiveDate'];
-- local ArchiveURL = A['ArchiveURL'];
-- if ArchiveURL:match('//web\.archive\.org/save/') then -- if an archive.org save command url, we don't want to save target page ...
-- ArchiveURL = ''; -- every time a reader clicks the link so
-- ArchiveDate = ''; -- unset these
-- table.insert( z.message_tail, { set_error( 'archive_save', {}, true ) } ); -- and add error message
-- end
local DeadURL = A['DeadURL']
if not is_valid_parameter_value (DeadURL, 'dead-url', cfg.keywords ['deadurl']) then -- set in config.defaults to 'yes'
DeadURL = ''; -- anything else, set to empty string
end
 
local URL = A['URL']
local URLorigin = A:ORIGIN('URL'); -- get name of parameter that holds URL
Line ୧,୭୬୫ ⟶ ୧,୮୮୭:
local Via = A['Via'];
local AccessDate = A['AccessDate'];
local ArchiveDate = A['ArchiveDate'];
local Agency = A['Agency'];
local DeadURL = A['DeadURL']
if not is_valid_parameter_value (DeadURL, 'dead-url', cfg.keywords ['deadurl']) then -- set in config.defaults to 'yes'
DeadURL = ''; -- anything else, set to empty string
end
 
local Language = A['Language'];
Line ୨,୧୩୧ ⟶ ୨,୨୪୮:
Date validation supporting code is in Module:Citation/CS1/Date_validation
]]
do -- create defined block to contain local variables error_message, anddate_parameters_list, mismatch
local error_message = '';
-- AirDate has been promoted to Date so not necessary to check it
anchor_year,local error_messagedate_parameters_list = dates({['access-date']=AccessDate, ['archive-date']=ArchiveDate, ['date']=Date, ['doi-broken-date']=DoiBroken,
['embargo']=Embargo, ['lay-date']=LayDate, ['publication-date']=PublicationDate, ['year']=Year}, COinS_date);
 
anchor_year, Embargo, error_message = dates(date_parameters_list, COinS_date);
 
if is_set (Year) and is_set (Date) then -- both |date= and |year= not normally needed;
Line ୨,୧୫୨ ⟶ ୨,୨୭୧:
table.insert( z.message_tail, { set_error( 'bad_date', {error_message}, true ) } ); -- add this error message
elseif is_set (DF) then
local date_parameters_list = {['access-date']=AccessDate, ['archive-date']=ArchiveDate, ['date']=Date, ['doi-broken-date']=DoiBroken,
['embargo']=Embargo, ['lay-date']=LayDate, ['publication-date']=PublicationDate};
if reformat_dates (date_parameters_list, DF, false) then -- reformat to DF format, use long month names if appropriate
AccessDate = date_parameters_list['access-date']; -- overwrite date holding parameters with reformatted values
ArchiveDate = date_parameters_list['archive-date']; -- TODO: move all dates into this table at the beginning and ...
Date = date_parameters_list['date']; -- ... use them from this table? no in-and-out like we're doing here
DoiBroken = date_parameters_list['doi-broken-date'];
Embargo = date_parameters_list['embargo'];
LayDate = date_parameters_list['lay-date'];
PublicationDate = date_parameters_list['publication-date'];
Line ୨,୨୭୩ ⟶ ୨,୩୮୮:
do -- do editor name list first because coauthors can modify control table
control.maximum , editor_etal = get_display_authors_editors (A['DisplayEditors'], #e, 'editors', editor_etal);
last_first_list, EditorCount = list_people(control, e, editor_etal, 'editor');
 
if is_set (Editors) then
Line ୨,୨୯୨ ⟶ ୨,୪୦୭:
do -- now do translators
control.maximum = #t; -- number of translators
Translators = list_people(control, t, false, 'translator'); -- et al not currently supported
end
do -- now do contributors
control.maximum = #c; -- number of contributors
Contributors = list_people(control, c, false, 'contributor'); -- et al not currently supported
end
do -- now do authors
Line ୨,୩୦୬ ⟶ ୨,୪୨୧:
end
last_first_list = list_people(control, a, author_etal, 'author');
 
if is_set (Authors) then
Line ୨,୩୪୨ ⟶ ୨,୪୫୭:
 
if not is_set(URL) then
if in_array(config.CitationClass, {"web","podcast", "mailinglist"}) then -- test|url= ifrequired for cite web or, cite podcast, |url=and is missing or emptycite mailinglist
table.insert( z.message_tail, { set_error( 'cite_web_url', {}, true ) } );
end
-- testdo ifwe have |accessdate is given= without givingeither |url= aor URL|chapter-url=?
if is_set(AccessDate) and not is_set(ChapterURL)then -- ChapterURL may be set when theURL others areis not set; TODO: move this to a separate test?
table.insert( z.message_tail, { set_error( 'accessdate_missing_url', {}, true ) } );
AccessDate = '';
Line ୨,୩୫୬ ⟶ ୨,୪୭୧:
DeadURL = DeadURL:lower(); -- used later when assembling archived text
if is_set( ArchiveURL ) then
if is_set (ChapterURL) then -- swapped -- URL not set so if chapter-url is set apply archive url to it
if is_set (URL) then
OriginalURL = URL; -- save copy of original source URL
OriginalURLorigin = URLorigin; -- name of url parameter for error messages
OriginalFormat = Format; -- and original |format=
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
Format = ArchiveFormat or ''; -- swap in archive's format
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
OriginalURLorigin = ChapterURLorigin; -- name of chapter-url parameter for error messages
Line ୨,୩୭୪ ⟶ ୨,୪୮୦:
ChapterFormat = ArchiveFormat or ''; -- swap in archive's format
end
elseif is_set (URL) then
end
OriginalURL = URL; -- save copy of original source URL
OriginalURLorigin = URLorigin; -- name of url parameter for error messages
OriginalFormat = Format; -- and original |format=
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
Format = ArchiveFormat or ''; -- swap in archive's format
end
end
end
 
Line ୨,୪୫୪ ⟶ ୨,୫୬୯:
if is_set(Title) then
if not is_set(TitleLink) and is_set(URL) then
Title = external_link( URL, Title, URLorigin ) .. TransError .. Format;
-- this experiment hidden 2016-04-10; see Help_talk:Citation_Style_1#Recycled_urls
URL = "";
-- local temp_title = external_link( URL, Title, URLorigin ) .. TransError .. Format; -- do this so we get error message even if url is usurped no archive
-- if in_array (DeadURL, {'unfit no archive', 'usurped no archive'}) then -- when url links to inappropriate location and there is no archive of original source available
-- local err_msg
-- if temp_title:match ('%[%S+%s+(.+)%](<.+)') then -- if there is an error message
-- Title, err_msg = temp_title:match ('%[%S+%s+(.+)%](<.+)'); -- strip off external link; TODO: find a better to do this
-- Title = Title .. (err_msg or '');
-- end
-- else
-- Title = temp_title;
-- end
 
URL = ''; -- unset these because no longer needed
Format = "";
else
Line ୩,୦୩୭ ⟶ ୩,୧୬୪:
end
end
missing_pipe_check (v); -- do we think that there is a parameter that is missing a pipe?
args[k] = v;
elseif args[k] ~= nil or (k == 'postscript') then