Изменения

Строка 16: Строка 16:  
local cfg = {}; -- table of configuration tables that are defined in Module:Citation/CS1/Configuration
 
local cfg = {}; -- table of configuration tables that are defined in Module:Citation/CS1/Configuration
 
local whitelist = {}; -- table of tables listing valid template parameter names; defined in Module:Citation/CS1/Whitelist
 
local whitelist = {}; -- table of tables listing valid template parameter names; defined in Module:Citation/CS1/Whitelist
 +
 +
local boxDate = require('Module:Calendar').bxDate; -- РУВИКИ: все даты делаем человекочитаемыми
      Строка 423: Строка 425:     
return base_url;
 
return base_url;
 +
end
 +
 +
--[[--------------------------< F O R M A T E _  D A T E >-----------------------------------------------------
 +
 +
Call a calendar module that turns all non-local language dates (including ISO dates) into local language dates.
 +
Used for archiving and review dates.
 +
 +
]]
 +
 +
local function formatDate(txtDateIn, strFormat, params)
 +
local txtDateOut, date, status = boxDate(txtDateIn, strFormat, params)
 +
if status.brk then
 +
return error(status.errorText)
 +
else
 +
return txtDateOut
 +
end
 
end
 
end
   Строка 664: Строка 682:  
periodical = ''; -- to be safe for concatenation
 
periodical = ''; -- to be safe for concatenation
 
else
 
else
periodical = utilities.wrap_style ('italic-title', periodical); -- style  
+
periodical = utilities.wrap_style ('italic-title', periodical); -- style
 
end
 
end
   Строка 1039: Строка 1057:  
end
 
end
 
end
 
end
if nil == mw.ustring.find (last, "^[A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143%-%s%']*$") or
+
if nil == mw.ustring.find (last, "^[A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143\225\184\128-\225\187\191%-%s%']*$") or
nil == mw.ustring.find (first, "^[A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143%-%s%'%.]*$") then
+
nil == mw.ustring.find (first, "^[A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143\225\184\128-\225\187\191%-%s%'%.]*$") then
 
add_vanc_error (cfg.err_msg_supl['non-Latin char'], position);
 
add_vanc_error (cfg.err_msg_supl['non-Latin char'], position);
 
return false; -- not a string of Latin characters; Vancouver requires Romanization
 
return false; -- not a string of Latin characters; Vancouver requires Romanization
Строка 1065: Строка 1083:  
]]
 
]]
   −
local function reduce_to_initials(first, position)
+
local function reduce_to_initials (first, position)
local name, suffix = mw.ustring.match(first, "^(%u+) ([%dJS][%drndth]+)$");
+
if first:find (',', 1, true) then
 +
return first; -- commas not allowed; abandon
 +
end
 +
 
 +
local name, suffix = mw.ustring.match (first, "^(%u+) ([%dJS][%drndth]+)$");
    
if not name then -- if not initials and a suffix
 
if not name then -- if not initials and a suffix
name = mw.ustring.match(first, "^(%u+)$"); -- is it just initials?
+
name = mw.ustring.match (first, "^(%u+)$"); -- is it just initials?
 
end
 
end
   Строка 1087: Строка 1109:  
end -- if here then name has 3 or more uppercase letters so treat them as a word
 
end -- if here then name has 3 or more uppercase letters so treat them as a word
   −
local initials, names = {}, {}; -- tables to hold name parts and initials
+
local initials_t, names_t = {}, {}; -- tables to hold name parts and initials
 
local i = 1; -- counter for number of initials
 
local i = 1; -- counter for number of initials
   −
names = mw.text.split (first, '[%s,]+'); -- split into a table of names and possible suffix
+
names_t = mw.text.split (first, '[%s%-]+'); -- split into a sequence of names and possible suffix
   −
while names[i] do -- loop through the table
+
while names_t[i] do -- loop through the sequence
if 1 < i and names[i]:match ('[%dJS][%drndth]+%.?$') then -- if not the first name, and looks like a suffix (may have trailing dot)
+
if 1 < i and names_t[i]:match ('[%dJS][%drndth]+%.?$') then -- if not the first name, and looks like a suffix (may have trailing dot)
names[i] = names[i]:gsub ('%.', ''); -- remove terminal dot if present
+
names_t[i] = names_t[i]:gsub ('%.', ''); -- remove terminal dot if present
if is_suffix (names[i]) then -- if a legitimate suffix
+
if is_suffix (names_t[i]) then -- if a legitimate suffix
table.insert (initials, ' ' .. names[i]); -- add a separator space, insert at end of initials table
+
table.insert (initials_t, ' ' .. names_t[i]); -- add a separator space, insert at end of initials sequence
 
break; -- and done because suffix must fall at the end of a name
 
break; -- and done because suffix must fall at the end of a name
 
end -- no error message if not a suffix; possibly because of Romanization
 
end -- no error message if not a suffix; possibly because of Romanization
 
end
 
end
 
if 3 > i then
 
if 3 > i then
table.insert (initials, mw.ustring.sub(names[i], 1, 1)); -- insert the initial at end of initials table
+
table.insert (initials_t, mw.ustring.sub (names_t[i], 1, 1)); -- insert the initial at end of initials sequence
 
end
 
end
 
i = i + 1; -- bump the counter
 
i = i + 1; -- bump the counter
 
end
 
end
 
 
return table.concat(initials) -- Vancouver format does not include spaces.
+
return table.concat (initials_t); -- Vancouver format does not include spaces.
 
end
 
end
   Строка 1252: Строка 1274:  
end
 
end
 
if proj then
 
if proj then
proj = ({['d'] = 'Wikidata', ['s'] = 'Wikisource', ['w'] = 'Wikipedia'})[proj]; -- :w (wikipedia) for linking from a non-wikipedia project
+
local proj_name = ({['d'] = 'Wikidata', ['s'] = 'Wikisource', ['w'] = 'Wikipedia'})[proj]; -- :w (wikipedia) for linking from a non-wikipedia project
if proj then  
+
if proj_name then  
one = one .. utilities.wrap_style ('interproj', proj); -- add resized leading space, brackets, static text, language name
+
one = one .. utilities.wrap_style ('interproj', proj_name); -- add resized leading space, brackets, static text, language name
 +
utilities.add_prop_cat ('interproj-linked-name', proj); -- categorize it; <proj> is sort key
 
tag = nil; -- unset; don't do both project and language
 
tag = nil; -- unset; don't do both project and language
 
end
 
end
Строка 1265: Строка 1288:  
if lang then -- error messaging done in extract_names() where we know parameter names
 
if lang then -- error messaging done in extract_names() where we know parameter names
 
one = one .. utilities.wrap_style ('interwiki', lang); -- add resized leading space, brackets, static text, language name
 
one = one .. utilities.wrap_style ('interwiki', lang); -- add resized leading space, brackets, static text, language name
 +
utilities.add_prop_cat ('interwiki-linked-name', tag); -- categorize it; <tag> is sort key
 
end
 
end
 
end
 
end
Строка 1392: Строка 1416:  
This function will only emit one error and one maint message for the current template.  Does not emit both error
 
This function will only emit one error and one maint message for the current template.  Does not emit both error
 
and maint messages/categories for the same parameter value.
 
and maint messages/categories for the same parameter value.
  −
returns nothing
      
]]
 
]]
Строка 1768: Строка 1790:     
for _, lang in ipairs (names_t) do -- reuse lang here because we don't yet know if lang is a language name or a language tag
 
for _, lang in ipairs (names_t) do -- reuse lang here because we don't yet know if lang is a language name or a language tag
 +
 +
local fromEnglishToCode = { -- костыль для РУВИКИ: замена распространённых англоназваний на коды, в следующей итерации использовать Module:Language.
 +
['Arabic'] = 'ar',
 +
['Azerbaijani'] = 'az',
 +
['Belarusian'] = 'be',
 +
['Bulgarian'] = 'bg',
 +
['Czech'] = 'cs',
 +
['Danish'] = 'da',
 +
['German'] = 'de',
 +
['Greek'] = 'el',
 +
['Spanish'] = 'es',
 +
['English'] = 'en',
 +
['Finnish'] = 'fi',
 +
['French'] = 'fr',
 +
['Hebrew'] = 'he',
 +
['Croatian'] = 'hr',
 +
['Hungarian'] = 'hu',
 +
['Armenian'] = 'hy',
 +
['Indonesian'] = 'id',
 +
['Italian'] = 'it',
 +
['Japanese'] = 'ja',
 +
['Korean'] = 'ko',
 +
['Latin'] = 'la',
 +
['Dutch'] = 'nl',
 +
['Norwegian'] = 'no',
 +
['Polish'] = 'pl',
 +
['Portuguese'] = 'pt',
 +
['Romanian'] = 'ro',
 +
['Russian'] = 'ru',
 +
['Slovenian'] = 'sl',
 +
['Serbian'] = 'sr',
 +
['Swedish'] = 'sv',
 +
['Thai'] = 'th',
 +
['Turkish'] = 'tr',
 +
['Ukrainian'] = 'uk',
 +
['Chinese'] = 'zh',
 +
}
 +
if fromEnglishToCode[lang] then
 +
lang = fromEnglishToCode[lang]
 +
end
 +
 
name, tag = name_tag_get (lang); -- attempt to get name/tag pair for <lang>; <name> has proper capitalization; <tag> is lowercase
 
name, tag = name_tag_get (lang); -- attempt to get name/tag pair for <lang>; <name> has proper capitalization; <tag> is lowercase
   Строка 1795: Строка 1858:  
return ''; -- if one language and that language is this wiki's return an empty string (no annotation)
 
return ''; -- if one language and that language is this wiki's return an empty string (no annotation)
 
end
 
end
return (" " .. wrap_msg ('language', name)); -- otherwise wrap with '(in ...)'
+
return (mw.getCurrentFrame():expandTemplate{ -- РУВИКИ: используем шаблон для отображения языка
 +
title= utilities.substitute (cfg.messages ['language'], tag)
 +
}); -- otherwise wrap with '(in ...)'
 
--[[ TODO: should only return blank or name rather than full list
 
--[[ TODO: should only return blank or name rather than full list
 
so we can clean up the bunched parenthetical elements Language, Type, Format
 
so we can clean up the bunched parenthetical elements Language, Type, Format
Строка 1847: Строка 1912:  
-- emit a maintenance message if user postscript is the default cs2 postscript
 
-- emit a maintenance message if user postscript is the default cs2 postscript
 
-- we catch the opposite case for cs1 in set_cs_style
 
-- we catch the opposite case for cs1 in set_cs_style
if 'cs2' == mode or 'citation' == cite_class then
+
if 'cs2' == mode or ('cs1' ~= mode and 'citation' == cite_class) then -- {{citation |title=Title |mode=cs1 |postscript=none}} should not emit maint message
 
utilities.set_message ('maint_postscript');
 
utilities.set_message ('maint_postscript');
 
end
 
end
Строка 1973: Строка 2038:  
--[[--------------------------< E X T R A _ T E X T _ I N _ V O L _ I S S _ C H E C K >------------------------
 
--[[--------------------------< E X T R A _ T E X T _ I N _ V O L _ I S S _ C H E C K >------------------------
   −
Adds error if |volume= or |issue= has what appears to be some form of redundant 'type' indicator.
+
Adds error if |volume= or |issue= has what appears to be some form of redundant 'type' indicator.  Applies to
 +
both; this function looks for issue text in both |issue= and |volume= and looks for volume-like text in |voluem=
 +
and |issue=.
    
For |volume=:
 
For |volume=:
Строка 1982: Строка 2049:  
For |issue=:
 
For |issue=:
 
'No.', 'I.', 'Iss.' (with or without the dot) abbreviations, or 'Issue' in the first characters of the
 
'No.', 'I.', 'Iss.' (with or without the dot) abbreviations, or 'Issue' in the first characters of the
parameter content (all case insensitive).
+
parameter content (all case insensitive); numero styling: 'n°' with degree sign U+00B0, and № precomposed
 +
numero sign U+2116.
 
 
 
Single character values ('v', 'i', 'n') allowed when not followed by separator character ('.', ':', '=', or
 
Single character values ('v', 'i', 'n') allowed when not followed by separator character ('.', ':', '=', or
Строка 2000: Строка 2068:  
end
 
end
 
 
local patterns = 'v' == selector and cfg.vol_iss_pg_patterns.vpatterns or cfg.vol_iss_pg_patterns.ipatterns;
  −
   
local handler = 'v' == selector and 'err_extra_text_volume' or 'err_extra_text_issue';
 
local handler = 'v' == selector and 'err_extra_text_volume' or 'err_extra_text_issue';
 
val = val:lower(); -- force parameter value to lower case
 
val = val:lower(); -- force parameter value to lower case
for _, pattern in ipairs (patterns) do -- spin through the selected sequence table of patterns
+
for _, pattern in ipairs (cfg.vol_iss_pg_patterns.vi_patterns_t) do -- spin through the sequence table of patterns
 
if val:match (pattern) then -- when a match, error so
 
if val:match (pattern) then -- when a match, error so
 
utilities.set_message (handler, name); -- add error message
 
utilities.set_message (handler, name); -- add error message
Строка 2465: Строка 2531:  
local path, timestamp, flag; -- portions of the archive.org URL
 
local path, timestamp, flag; -- portions of the archive.org URL
 
 
timestamp = url:match ('//archive.today/(%d%d%d%d%d%d%d%d%d%d%d%d%d%d)/'); -- get timestamp from archive.today urls
+
timestamp = url:match ('//archive.today/(%d%d%d%d%d%d%d%d%d%d%d%d%d%d)/') or -- get timestamp from archive.today urls
 +
url:match ('//archive.today/(%d%d%d%d%.%d%d%.%d%d%-%d%d%d%d%d%d)/'); -- this timestamp needs cleanup
 
if timestamp then -- if this was an archive.today url ...
 
if timestamp then -- if this was an archive.today url ...
return url, date, timestamp; -- return ArchiveURL, ArchiveDate, and timestamp from |archive-url=, and done
+
return url, date, timestamp:gsub ('[%.%-]', ''); -- return ArchiveURL, ArchiveDate, and timestamp (dots and dashes removed) from |archive-url=, and done -- return ArchiveURL, ArchiveDate, and timestamp from |archive-url=, and done
 
end
 
end
 
-- here for archive.org urls
 
-- here for archive.org urls
Строка 2551: Строка 2618:  
end
 
end
 
end
 
end
      
--[[--------------------------< D I S P L A Y _ N A M E S _ S E L E C T >--------------------------------------
 
--[[--------------------------< D I S P L A Y _ N A M E S _ S E L E C T >--------------------------------------
Строка 2596: Строка 2662:  
end
 
end
 
end
 
end
      
--[[--------------------------< C I T A T I O N 0 >------------------------------------------------------------
 
--[[--------------------------< C I T A T I O N 0 >------------------------------------------------------------
Строка 2639: Строка 2704:  
a, author_etal = parse_vauthors_veditors (args, A['Vauthors'], 'AuthorList'); -- fetch author list from |vauthors=, |author-linkn=, and |author-maskn=
 
a, author_etal = parse_vauthors_veditors (args, A['Vauthors'], 'AuthorList'); -- fetch author list from |vauthors=, |author-linkn=, and |author-maskn=
 
elseif 3 == selected then
 
elseif 3 == selected then
Authors = A['Authors']; -- use content of |people= or |credits=; |authors= is deprecated; TODO: constrain |people= and |credits= to cite av media, episode, serial?
+
Authors = A['Authors']; -- use content of |authors=
 
end
 
end
 
if utilities.is_set (Collaboration) then
 
if utilities.is_set (Collaboration) then
Строка 2713: Строка 2778:  
local TransPeriodical_origin =  A:ORIGIN ('TransPeriodical');
 
local TransPeriodical_origin =  A:ORIGIN ('TransPeriodical');
 
 
if (utilities.in_array (config.CitationClass, {'book', 'encyclopaedia'}) and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical) or utilities.is_set (TransPeriodical))) then
+
if (utilities.in_array (config.CitationClass, {'book', 'encyclopaedia'}) and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical) or utilities.is_set (TransPeriodical))) then
 
local param;
 
local param;
 
if utilities.is_set (Periodical) then -- get a parameter name from one of these periodical related meta-parameters
 
if utilities.is_set (Periodical) then -- get a parameter name from one of these periodical related meta-parameters
Строка 2873: Строка 2938:  
end
 
end
 
end
 
end
 +
 +
-- no_tracking_cats = "true"; -- выключаем всю категоризацию для РУВИКИ
 
-- check for extra |page=, |pages= or |at= parameters. (also sheet and sheets while we're at it)
 
-- check for extra |page=, |pages= or |at= parameters. (also sheet and sheets while we're at it)
 
utilities.select_one (args, {'page', 'p', 'pp', 'pages', 'at', 'sheet', 'sheets'}, 'err_redundant_parameters'); -- this is a dummy call simply to get the error message and category
 
utilities.select_one (args, {'page', 'p', 'pp', 'pages', 'at', 'sheet', 'sheets'}, 'err_redundant_parameters'); -- this is a dummy call simply to get the error message and category
Строка 2918: Строка 2985:     
local Encyclopedia = A['Encyclopedia']; -- used as a flag by this module and by ~/COinS
 
local Encyclopedia = A['Encyclopedia']; -- used as a flag by this module and by ~/COinS
 +
local ScriptEncyclopedia = A['ScriptEncyclopedia'];
 +
local TransEncyclopedia = A['TransEncyclopedia'];
   −
if utilities.is_set (Encyclopedia) then -- emit error message when Encyclopedia set but template is other than {{cite encyclopedia}} or {{citation}}
+
if utilities.is_set (Encyclopedia) or utilities.is_set (ScriptEncyclopedia) then -- emit error message when Encyclopedia set but template is other than {{cite encyclopedia}} or {{citation}}
 
if 'encyclopaedia' ~= config.CitationClass and 'citation' ~= config.CitationClass then
 
if 'encyclopaedia' ~= config.CitationClass and 'citation' ~= config.CitationClass then
utilities.set_message ('err_parameter_ignored', {A:ORIGIN ('Encyclopedia')});
+
if utilities.is_set (Encyclopedia) then
Encyclopedia = nil; -- unset because not supported by this template
+
utilities.set_message ('err_parameter_ignored', {A:ORIGIN ('Encyclopedia')});
 +
else
 +
utilities.set_message ('err_parameter_ignored', {A:ORIGIN ('ScriptEncyclopedia')});
 +
end
 +
Encyclopedia = nil; -- unset these because not supported by this template
 +
ScriptEncyclopedia = nil;
 +
TransEncyclopedia = nil;
 
end
 
end
 +
elseif utilities.is_set (TransEncyclopedia) then
 +
utilities.set_message ('err_trans_missing_title', {'encyclopedia'});
 
end
 
end
   Строка 2931: Строка 3008:  
end
 
end
   −
if utilities.is_set (Encyclopedia) then
+
if utilities.is_set (Encyclopedia) or utilities.is_set (ScriptEncyclopedia) then
 
Periodical = Encyclopedia; -- error or no, set Periodical to Encyclopedia for rendering; {{citation}} could (not legitimately) have both; use Encyclopedia
 
Periodical = Encyclopedia; -- error or no, set Periodical to Encyclopedia for rendering; {{citation}} could (not legitimately) have both; use Encyclopedia
 
Periodical_origin = A:ORIGIN ('Encyclopedia');
 
Periodical_origin = A:ORIGIN ('Encyclopedia');
 +
ScriptPeriodical = ScriptEncyclopedia;
 +
ScriptPeriodical_origin = A:ORIGIN ('ScriptEncyclopedia');
    
if utilities.is_set (Title) or utilities.is_set (ScriptTitle) then
 
if utilities.is_set (Title) or utilities.is_set (ScriptTitle) then
 
if not utilities.is_set (Chapter) then
 
if not utilities.is_set (Chapter) then
Chapter = Title; -- |encyclopedia= and |title= are set so map |title= to |article= and |encyclopedia= to |title= for rendering
+
Chapter = Title; -- |encyclopedia= and |title= are set so map |title= params to |article= params for rendering
 
ScriptChapter = ScriptTitle;
 
ScriptChapter = ScriptTitle;
 
ScriptChapter_origin = A:ORIGIN('ScriptTitle')
 
ScriptChapter_origin = A:ORIGIN('ScriptTitle')
Строка 2943: Строка 3022:  
ChapterURL = URL;
 
ChapterURL = URL;
 
ChapterURL_origin = URL_origin;
 
ChapterURL_origin = URL_origin;
   
ChapterUrlAccess = UrlAccess;
 
ChapterUrlAccess = UrlAccess;
 +
ChapterFormat = Format;
    
if not utilities.is_set (ChapterURL) and utilities.is_set (TitleLink) then
 
if not utilities.is_set (ChapterURL) and utilities.is_set (TitleLink) then
 
Chapter = utilities.make_wikilink (TitleLink, Chapter);
 
Chapter = utilities.make_wikilink (TitleLink, Chapter);
 
end
 
end
Title = Periodical;
+
Title = Periodical; -- now map |encyclopedia= params to |title= params for rendering
ChapterFormat = Format;
+
ScriptTitle = ScriptPeriodical or '';
 +
TransTitle = TransEncyclopedia or '';
 
Periodical = ''; -- redundant so unset
 
Periodical = ''; -- redundant so unset
TransTitle = '';
+
ScriptPeriodical = '';
 
URL = '';
 
URL = '';
 
Format = '';
 
Format = '';
 
TitleLink = '';
 
TitleLink = '';
ScriptTitle = '';
   
end
 
end
elseif utilities.is_set (Chapter) or utilities.is_set (ScriptChapter) then -- |title= not set
+
elseif utilities.is_set (Chapter) or utilities.is_set (ScriptChapter) then -- |title= not set
 
Title = Periodical; -- |encyclopedia= set and |article= set so map |encyclopedia= to |title= for rendering
 
Title = Periodical; -- |encyclopedia= set and |article= set so map |encyclopedia= to |title= for rendering
 +
ScriptTitle = ScriptPeriodical or '';
 +
TransTitle = TransEncyclopedia or '';
 
Periodical = ''; -- redundant so unset
 
Periodical = ''; -- redundant so unset
 +
ScriptPeriodical = '';
 
end
 
end
 
end
 
end
Строка 3135: Строка 3217:  
local PublicationDate = A['PublicationDate'];
 
local PublicationDate = A['PublicationDate'];
 
local Year = A['Year'];
 
local Year = A['Year'];
 +
 +
if utilities.is_set (Year) then
 +
validation.year_check (Year); -- returns nothing; emits maint message when |year= doesn't hold a 'year' value
 +
end
    
if not utilities.is_set (Date) then
 
if not utilities.is_set (Date) then
Строка 3194: Строка 3280:  
local error_list = {};
 
local error_list = {};
 
anchor_year, Embargo = validation.dates(date_parameters_list, COinS_date, error_list);
 
anchor_year, Embargo = validation.dates(date_parameters_list, COinS_date, error_list);
  −
-- start temporary Julian / Gregorian calendar uncertainty categorization
  −
if COinS_date.inter_cal_cat then
  −
utilities.add_prop_cat ('jul-greg-uncertainty');
  −
end
  −
-- end temporary Julian / Gregorian calendar uncertainty categorization
      
if utilities.is_set (Year) and utilities.is_set (Date) then -- both |date= and |year= not normally needed;  
 
if utilities.is_set (Year) and utilities.is_set (Date) then -- both |date= and |year= not normally needed;  
 
validation.year_date_check (Year, A:ORIGIN ('Year'), Date, A:ORIGIN ('Date'), error_list);
 
validation.year_date_check (Year, A:ORIGIN ('Year'), Date, A:ORIGIN ('Date'), error_list);
 
end
 
end
+
 
 
if 0 == #error_list then -- error free dates only; 0 when error_list is empty
 
if 0 == #error_list then -- error free dates only; 0 when error_list is empty
 
local modified = false; -- flag
 
local modified = false; -- flag
Строка 3484: Строка 3564:  
OriginalFormat = ChapterFormat; -- and original |chapter-format=
 
OriginalFormat = ChapterFormat; -- and original |chapter-format=
   −
if 'live' ~= UrlStatus then
+
if utilities.in_array (UrlStatus, {'unfit', 'deviated', 'dead', 'usurped', 'bot: unknown'}) then
 
ChapterURL = ArchiveURL -- swap-in the archive's URL
 
ChapterURL = ArchiveURL -- swap-in the archive's URL
 
ChapterURL_origin = A:ORIGIN('ArchiveURL') -- name of |archive-url= parameter for error messages
 
ChapterURL_origin = A:ORIGIN('ArchiveURL') -- name of |archive-url= parameter for error messages
Строка 3496: Строка 3576:  
OriginalAccess = UrlAccess;
 
OriginalAccess = UrlAccess;
   −
if 'live' ~= UrlStatus then -- if URL set then |archive-url= applies to it
+
if utilities.in_array (UrlStatus, {'unfit', 'deviated', 'dead', 'usurped', 'bot: unknown'}) then -- if URL set then |archive-url= applies to it
 
URL = ArchiveURL -- swap-in the archive's URL
 
URL = ArchiveURL -- swap-in the archive's URL
 
URL_origin = A:ORIGIN('ArchiveURL') -- name of archive URL parameter for error messages
 
URL_origin = A:ORIGIN('ArchiveURL') -- name of archive URL parameter for error messages
Строка 3584: Строка 3664:  
('map' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)))) then -- special case for cite map when the map is in a periodical treat as an article
 
('map' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)))) then -- special case for cite map when the map is in a periodical treat as an article
 
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 = utilities.wrap_style ('quoted-title', Title);
+
Title = utilities.wrap_style ('quoted-title', Title);
 
Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
 
Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
 
TransTitle = utilities.wrap_style ('trans-quoted-title', TransTitle );
 
TransTitle = utilities.wrap_style ('trans-quoted-title', TransTitle );
Строка 3731: Строка 3811:     
Series = utilities.is_set (Series) and wrap_msg ('series', {sepc, Series}) or ""; -- not the same as SeriesNum
 
Series = utilities.is_set (Series) and wrap_msg ('series', {sepc, Series}) or ""; -- not the same as SeriesNum
local Agency = A['Agency'];
+
local Agency = A['Agency'] or ''; -- |agency= is supported by {{cite magazine}}, {{cite news}}, {{cite press release}}, {{cite web}}, and certain {{citation}} templates
Agency = utilities.is_set (Agency) and wrap_msg ('agency', {sepc, Agency}) or "";
+
if utilities.is_set (Agency) then -- this testing done here because {{citation}} supports 'news' citations
 +
if utilities.in_array (config.CitationClass, {'magazine', 'news', 'pressrelease', 'web'}) or ('citation' == config.CitationClass and utilities.in_array (Periodical_origin, {"magazine", "newspaper", "work"})) then
 +
Agency = wrap_msg ('agency', {sepc, Agency}); -- format for rendering
 +
else
 +
Agency = ''; -- unset; not supported
 +
utilities.set_message ('err_parameter_ignored', {'agency'}); -- add error message
 +
end
 +
end
 +
 
 
Volume = format_volume_issue (Volume, Issue, ArticleNumber, config.CitationClass, Periodical_origin, sepc, use_lowercase);
 
Volume = format_volume_issue (Volume, Issue, ArticleNumber, config.CitationClass, Periodical_origin, sepc, use_lowercase);
    
if utilities.is_set (AccessDate) then
 
if utilities.is_set (AccessDate) then
 
local retrv_text = " " .. cfg.messages['retrieved']
 
local retrv_text = " " .. cfg.messages['retrieved']
 
+
local status, result = pcall(formatDate, AccessDate) -- РУВИКИ: человекочитаемые даты
AccessDate = nowrap_date (AccessDate); -- wrap in nowrap span if date in appropriate format
+
if status then
 +
AccessDate = string.format("<span class='date'>%s</span>", result)
 +
else
 +
AccessDate = string.format("<span class='error'>(Строка «%s» не является верной датой, пожалуйста, укажите дату в формате <code>ГГГГ-ММ-ДД</code>)</span>", AccessDate)
 +
end
 +
-- AccessDate = nowrap_date (AccessDate); -- wrap in nowrap span if date in appropriate format
 
if (sepc ~= ".") then retrv_text = retrv_text:lower() end -- if mode is cs2, lower case
 
if (sepc ~= ".") then retrv_text = retrv_text:lower() end -- if mode is cs2, lower case
 
AccessDate = utilities.substitute (retrv_text, AccessDate); -- add retrieved text
 
AccessDate = utilities.substitute (retrv_text, AccessDate); -- add retrieved text
Строка 3838: Строка 3931:  
if utilities.is_set (ArchiveURL) then
 
if utilities.is_set (ArchiveURL) then
 
local arch_text;
 
local arch_text;
if "live" == UrlStatus then
+
local status, result = pcall(formatDate, ArchiveDate) -- РУВИКИ: человекочитаемые даты
 +
if status then
 +
ArchiveDate = string.format("<span class='date'>%s</span>", result)
 +
else
 +
ArchiveDate = string.format("<span class='error'>(Строка «%s» не является верной датой, пожалуйста, укажите дату в формате <code>ГГГГ-ММ-ДД</code>)</span>", ArchiveDate)
 +
end
 +
if "live" == UrlStatus or "" == UrlStatus then
 
arch_text = cfg.messages['archived'];
 
arch_text = cfg.messages['archived'];
 
if sepc ~= "." then arch_text = arch_text:lower() end
 
if sepc ~= "." then arch_text = arch_text:lower() end
Строка 3880: Строка 3979:  
Archived = '';
 
Archived = '';
 
end
 
end
+
 
 
local TranscriptURL = A['TranscriptURL']
 
local TranscriptURL = A['TranscriptURL']
 
local TranscriptFormat = A['TranscriptFormat'];
 
local TranscriptFormat = A['TranscriptFormat'];
Строка 3903: Строка 4002:  
Publisher = sepc .. " " .. PublicationPlace .. ": " .. PublisherName .. PublicationDate;
 
Publisher = sepc .. " " .. PublicationPlace .. ": " .. PublisherName .. PublicationDate;
 
else
 
else
Publisher = sepc .. " " .. PublisherName .. PublicationDate;
+
Publisher = sepc .. " " .. PublisherName .. PublicationDate;
 
end
 
end
 
elseif utilities.is_set (PublicationPlace) then  
 
elseif utilities.is_set (PublicationPlace) then  
Строка 3952: Строка 4051:  
local tcommon2; -- used for book cite when |contributor= is set
 
local tcommon2; -- used for book cite when |contributor= is set
 
 
if utilities.in_array (config.CitationClass, {"journal", "citation"}) and utilities.is_set (Periodical) then
+
if utilities.in_array (config.CitationClass, {"book", "citation"}) and not utilities.is_set (Periodical) then -- special cases for book cites
if not (utilities.is_set (Authors) or utilities.is_set (Editors)) then
  −
Others = Others:gsub ('^' .. sepc .. ' ', ''); -- when no authors and no editors, strip leading sepc and space
  −
end
  −
if utilities.is_set (Others) then Others = safe_join ({Others, sepc .. " "}, sepc) end -- add terminal punctuation & space; check for dup sepc; TODO why do we need to do this here?
  −
tcommon = safe_join( {Others, Title, TitleNote, Conference, Periodical, Format, TitleType, Series, Language, Edition, Publisher, Agency, Volume}, sepc );
  −
elseif utilities.in_array (config.CitationClass, {"book", "citation"}) and not utilities.is_set (Periodical) then -- special cases for book cites
   
if utilities.is_set (Contributors) then -- when we are citing foreword, preface, introduction, etc.
 
if utilities.is_set (Contributors) then -- when we are citing foreword, preface, introduction, etc.
tcommon = safe_join( {Title, TitleNote}, sepc ); -- author and other stuff will come after this and before tcommon2
+
tcommon = safe_join ({Title, TitleNote}, sepc); -- author and other stuff will come after this and before tcommon2
tcommon2 = safe_join( {Conference, Periodical, Format, TitleType, Series, Language, Volume, Others, Edition, Publisher, Agency}, sepc );
+
tcommon2 = safe_join ({TitleType, Series, Language, Volume, Others, Edition, Publisher}, sepc);
 
else
 
else
tcommon = safe_join( {Title, TitleNote, Conference, Periodical, Format, TitleType, Series, Language, Volume, Others, Edition, Publisher, Agency}, sepc );
+
tcommon = safe_join ({Title, TitleNote, TitleType, Series, Language, Volume, Others, Edition, Publisher}, sepc);
 
end
 
end
    
elseif 'map' == config.CitationClass then -- special cases for cite map
 
elseif 'map' == config.CitationClass then -- special cases for cite map
 
if utilities.is_set (Chapter) then -- map in a book; TitleType is part of Chapter
 
if utilities.is_set (Chapter) then -- map in a book; TitleType is part of Chapter
tcommon = safe_join( {Title, Format, Edition, Scale, Series, Language, Cartography, Others, Publisher, Volume}, sepc );
+
tcommon = safe_join ({Title, Edition, Scale, Series, Language, Cartography, Others, Publisher, Volume}, sepc);
 
elseif utilities.is_set (Periodical) then -- map in a periodical
 
elseif utilities.is_set (Periodical) then -- map in a periodical
tcommon = safe_join( {Title, TitleType, Format, Periodical, Scale, Series, Language, Cartography, Others, Publisher, Volume}, sepc );
+
tcommon = safe_join ({Title, TitleType, Periodical, Scale, Series, Language, Cartography, Others, Publisher, Volume}, sepc);
 
else -- a sheet or stand-alone map
 
else -- a sheet or stand-alone map
tcommon = safe_join( {Title, TitleType, Format, Edition, Scale, Series, Language, Cartography, Others, Publisher}, sepc );
+
tcommon = safe_join ({Title, TitleType, Edition, Scale, Series, Language, Cartography, Others, Publisher}, sepc);
 
end
 
end
 
 
 
elseif 'episode' == config.CitationClass then -- special case for cite episode
 
elseif 'episode' == config.CitationClass then -- special case for cite episode
tcommon = safe_join( {Title, TitleNote, TitleType, Series, Language, Edition, Publisher}, sepc );
+
tcommon = safe_join ({Title, TitleNote, TitleType, Series, Language, Edition, Publisher}, sepc);
    
else -- all other CS1 templates
 
else -- all other CS1 templates
tcommon = safe_join( {Title, TitleNote, Conference, Periodical, Format, TitleType, Series, Language,  
+
tcommon = safe_join ({Title, TitleNote, Conference, Periodical, TitleType, Series, Language, Volume, Others, Edition, Publisher, Agency}, sepc);
Volume, Others, Edition, Publisher, Agency}, sepc );
   
end
 
end
 
 
Строка 4000: Строка 4092:  
local text;
 
local text;
 
local pgtext = Position .. Sheet .. Sheets .. Page .. Pages .. At;
 
local pgtext = Position .. Sheet .. Sheets .. Page .. Pages .. At;
 
+
 
local OrigDate = A['OrigDate'];
 
local OrigDate = A['OrigDate'];
 
OrigDate = utilities.is_set (OrigDate) and wrap_msg ('origdate', OrigDate) or '';
 
OrigDate = utilities.is_set (OrigDate) and wrap_msg ('origdate', OrigDate) or '';
Строка 4013: Строка 4105:  
end
 
end
 
end
 
end
end
+
end
 +
 
 
if utilities.is_set (Authors) then
 
if utilities.is_set (Authors) then
 
if (not utilities.is_set (Date)) then -- when date is set it's in parentheses; no Authors termination
 
if (not utilities.is_set (Date)) then -- when date is set it's in parentheses; no Authors termination
Строка 4070: Строка 4163:  
end
 
end
 
end
 
end
+
 
 
if utilities.is_set (PostScript) and PostScript ~= sepc then
 
if utilities.is_set (PostScript) and PostScript ~= sepc then
 
text = safe_join( {text, sepc}, sepc ); -- Deals with italics, spaces, etc.
 
text = safe_join( {text, sepc}, sepc ); -- Deals with italics, spaces, etc.
text = text:sub(1, -sepc:len() - 1);
+
if '.' == sepc then -- remove final seperator if present
end
+
text = text:gsub ('%' .. sepc .. '$', ''); -- dot must be escaped here
 +
else
 +
text = mw.ustring.gsub (text, sepc .. '$', ''); -- using ustring for non-dot sepc (likely a non-Latin character)
 +
end
 +
end
 
 
 
text = safe_join( {text, PostScript}, sepc );
 
text = safe_join( {text, PostScript}, sepc );
Строка 4084: Строка 4181:  
local Ref = is_valid_parameter_value (A['Ref'], A:ORIGIN('Ref'), cfg.keywords_lists['ref'], nil, true); -- nil when |ref=harv; A['Ref'] else
 
local Ref = is_valid_parameter_value (A['Ref'], A:ORIGIN('Ref'), cfg.keywords_lists['ref'], nil, true); -- nil when |ref=harv; A['Ref'] else
    +
-- Если указан параметр ref, то формируем ref-якорь по логике из рувики
 +
-- Если параметр не указан или ref=harv, то формируем якорь по енвики
 +
-- После зачистки всех ref=harv (~350), можно будет убрать код внутри utilities.is_set(Ref)
 
if 'none' ~= cfg.keywords_xlate[(Ref and Ref:lower()) or ''] then
 
if 'none' ~= cfg.keywords_xlate[(Ref and Ref:lower()) or ''] then
local namelist_t = {}; -- holds selected contributor, author, editor name list
+
local citeref_id = Ref
 
local year = first_set ({Year, anchor_year}, 2); -- Year first for legacy citations and for YMD dates that require disambiguation
 
local year = first_set ({Year, anchor_year}, 2); -- Year first for legacy citations and for YMD dates that require disambiguation
 
+
if not utilities.is_set(Ref) then
if #c > 0 then -- if there is a contributor list
+
local namelist_t = {}; -- holds selected contributor, author, editor name list
namelist_t = c; -- select it
+
elseif #a > 0 then -- or an author list
+
if #c > 0 then -- if there is a contributor list
namelist_t = a;
+
namelist_t = c; -- select it
elseif #e > 0 then -- or an editor list
+
elseif #a > 0 then -- or an author list
namelist_t = e;
+
namelist_t = a;
end
+
elseif #e > 0 then -- or an editor list
local citeref_id;
+
namelist_t = e;
if #namelist_t > 0 then -- if there are names in namelist_t
+
end
citeref_id = make_citeref_id (namelist_t, year); -- go make the CITEREF anchor
+
if #namelist_t > 0 then -- if there are names in namelist_t
if mw.uri.anchorEncode (citeref_id) == ((Ref and mw.uri.anchorEncode (Ref)) or '') then -- Ref may already be encoded (by {{sfnref}}) so citeref_id must be encoded before comparison
+
citeref_id = make_citeref_id (namelist_t, year); -- go make the CITEREF anchor
utilities.set_message ('maint_ref_duplicates_default');
+
if mw.uri.anchorEncode (citeref_id) == ((Ref and mw.uri.anchorEncode (Ref)) or '') then -- Ref may already be encoded (by {{sfnref}}) so citeref_id must be encoded before comparison
 +
utilities.set_message ('maint_ref_duplicates_default');
 +
end
 +
else
 +
citeref_id = ''; -- unset
 +
end
 +
elseif mw.ustring.sub(Ref, 0, 7) ~= 'CITEREF' then                      -- для рувики: иная генерация ref-якорей
 +
if mw.ustring.match(citeref_id, '%d%d%d%d') then
 +
citeref_id = 'CITEREF' .. citeref_id
 +
else
 +
local yearForRef = nil
 +
if year and mw.ustring.match(year, '^%d%d%d%d$') then
 +
yearForRef = mw.ustring.match(year, '^%d%d%d%d$')
 +
elseif Date and mw.ustring.match(Date, '%d%d%d%d') then
 +
yearForRef = mw.ustring.match(Date, '%d%d%d%d')
 +
end
 +
if yearForRef then
 +
citeref_id = 'CITEREF' .. citeref_id .. yearForRef
 +
else
 +
citeref_id = '' -- TODO: для рувики: выдавать ошибку?
 +
end
 
end
 
end
else
  −
citeref_id = ''; -- unset
   
end
 
end
options_t.id = Ref or citeref_id;
+
options_t.id = citeref_id or '';
 
end
 
end
   Строка 4184: Строка 4302:  
end
 
end
   −
for _, v in ipairs (z.prop_cats_t) do -- append properties categories
+
-- for _, v in ipairs (z.prop_cats_t) do -- append properties categories
table.insert (render_t, utilities.substitute (cfg.messages['cat wikilink'], v)); -- no sort keys
+
-- table.insert (render_t, utilities.substitute (cfg.messages['cat wikilink'], v)); -- no sort keys
end
+
-- end
 
end
 
end
   Строка 4226: Строка 4344:  
return nil;
 
return nil;
 
end
 
end
-- replace wnumerator digit(s) with # (|last25= becomes |last#=) (mw.ustring because non-Western 'local' digits)
+
-- replace enumerator digit(s) with # (|last25= becomes |last#=) (mw.ustring because non-Western 'local' digits)
 
enum_name = mw.ustring.gsub (name, '%d+$', '#'); -- where enumerator is last charaters in parameter name (these to protect |s2cid=)
 
enum_name = mw.ustring.gsub (name, '%d+$', '#'); -- where enumerator is last charaters in parameter name (these to protect |s2cid=)
 
enum_name = mw.ustring.gsub (enum_name, '%d+([%-l])', '#%1'); -- where enumerator is in the middle of the parameter name; |author#link= is the oddity
 
enum_name = mw.ustring.gsub (enum_name, '%d+([%-l])', '#%1'); -- where enumerator is in the middle of the parameter name; |author#link= is the oddity
Анонимный участник