Module:Citation/CS1 and Module:Citation/CS1/sandbox: Difference between pages
Appearance
(Difference between pages)
Content deleted Content added
No edit summary | m Removed protection from "Module:Citation/CS1/sandbox" | ||
| Line 1: | Line 1: | ||
--[[ | |||
History of changes since last sync: 2025-08-30 | |||
2025-09-21: i18n fixes; see Help_talk:Citation_Style_1#i18n:_Translatable_texts_from_Module:Citation/CS1 | |||
]] | |||
require ('strict'); | require ('strict'); | ||
| Line 780: | Line 787: | ||
local err_msg; | local err_msg; | ||
if capture and not (cfg.invisible_defs.del == capture or cfg.invisible_defs.zwj == capture) then | if capture and not (cfg.invisible_defs.del == capture or cfg.invisible_defs.zwj == capture) then | ||
err_msg = | err_msg = utilities.substitute (cfg.messages.invisible_1, {capture, char_name});-- <capture> here is stripmarker name | ||
else | else | ||
err_msg = | err_msg = utilities.substitute (cfg.messages.invisible_2, char_name); | ||
end | end | ||
| Line 1,255: | Line 1,262: | ||
end | end | ||
if proj then | if proj then | ||
local proj_name = ({['d'] = | local proj_name = ({['d'] = cfg.messages.wikidata, ['s'] = cfg.messages.wikisource, ['w'] = cfg.messages.wikipedia})[proj]; -- :w (wikipedia) for linking from a non-wikipedia project | ||
if proj_name then | if proj_name then | ||
one = one .. utilities.wrap_style ('interproj', proj_name); -- 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 | ||
| Line 2,009: | Line 2,016: | ||
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'; | ||
local accept_val; | |||
val, accept_val = utilities.has_accept_as_written (val); | |||
--if accept_val then -- if uncomment this, |volume=((vol. 1)) suppresses error | |||
-- return; | |||
| ⚫ | |||
--val = mw.text.unstripNoWiki (val); -- if uncomment this, |volume=<nowiki>vol. 1</nowiki> shows error | |||
val = val:lower(); -- force parameter value to lower case | val = val:lower(); -- force parameter value to lower case | ||
for _, pattern in ipairs (cfg.vol_iss_pg_patterns.vi_patterns_t) do -- spin through the 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 | ||
| Line 2,183: | Line 2,198: | ||
(utilities.is_set (vxxxxors) and utilities.is_set (xxxxors)) or | (utilities.is_set (vxxxxors) and utilities.is_set (xxxxors)) or | ||
(true == lastfirst and utilities.is_set (xxxxors)) then | (true == lastfirst and utilities.is_set (xxxxors)) then | ||
local err_name; | --local err_name; | ||
if 'AuthorList' == list_name then -- figure out which name should be used in error message | --if 'AuthorList' == list_name then -- figure out which name should be used in error message | ||
err_name = 'author'; | --err_name = 'author'; | ||
else | --else | ||
err_name = 'editor'; | --err_name = 'editor'; | ||
end | --end | ||
utilities.set_message ('err_redundant_parameters', err_name .. '-name-list parameters'); -- add error message | --utilities.set_message ('err_redundant_parameters', err_name .. '-name-list parameters'); -- add error message | ||
utilities.set_message ('err_redundant_parameters', | |||
utilities.substitute (cfg.special_case_translation.name_list_params, | |||
('AuthorList' == list_name) and cfg.special_case_translation.author or cfg.special_case_translation.editor)); -- add error message | |||
end | end | ||
| Line 2,475: | Line 2,495: | ||
local err_msg = ''; -- start with the error message empty | local err_msg = ''; -- start with the error message empty | ||
local path, timestamp, flag; -- portions of the archive.org URL | local path, timestamp, flag; -- portions of the archive.org URL | ||
local function is_ts_date_valid (timestamp, origin_date) -- local function to validate archive url taimestamp date; time ignored | |||
local y, m, d = timestamp:match ('(%d%d%d%d)(%d%d)(%d%d)'); -- split into parts | |||
if y and validation.is_valid_date (y, m, d) and (tonumber (y) >= origin_date) then -- <origin_date> is 1996 for archive.org; 2012 for archive.today | |||
return true; | |||
| ⚫ | |||
end | |||
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 | 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 | 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 | if timestamp then -- if this is an archive.today url ... | ||
timestamp = timestamp:gsub ('[%.%-]', '');-- strip dots and dashes | |||
if not is_ts_date_valid (timestamp, 2012) then -- is ymd portion of timestamp a valid date? | |||
utilities.set_message ('err_archive_url', {cfg.err_msg_supl.timestamp}); -- no; set error message; | |||
| ⚫ | |||
return url, date; -- preview mode so return ArchiveURL, ArchiveDate; suppress timestamp because invalid | |||
else | |||
return '', ''; -- return empty strings for ArchiveURL and ArchiveDate | |||
end | |||
else | |||
return url, date, timestamp; -- return ArchiveURL, ArchiveDate, and timestamp (dots and dashes removed) from |archive-url=, and done | |||
end | |||
end | end | ||
-- here for archive.org urls | -- here for archive.org urls | ||
| Line 2,504: | Line 2,542: | ||
end | end | ||
end | end | ||
elseif not is_ts_date_valid (timestamp, 1996) then -- is ymd portion of timestamp a valid date? | |||
err_msg = cfg.err_msg_supl.timestamp; | |||
timestamp = nil; -- unset because invalid | |||
elseif utilities.is_set (path) and 'web/' ~= path then -- older archive URLs do not have the extra 'web/' path element | elseif utilities.is_set (path) and 'web/' ~= path then -- older archive URLs do not have the extra 'web/' path element | ||
err_msg = cfg.err_msg_supl.path; | err_msg = cfg.err_msg_supl.path; | ||
| Line 2,976: | Line 3,017: | ||
Volume = A['Volume']; | Volume = A['Volume']; | ||
end | end | ||
extra_text_in_vol_iss_check (Volume, A:ORIGIN ('Volume'), 'v'); | extra_text_in_vol_iss_check (Volume, A:ORIGIN ('Volume'), 'v'); | ||
local Issue; | local Issue; | ||
if 'citation' == config.CitationClass then | if 'citation' == config.CitationClass then | ||
if utilities.is_set (Periodical) and utilities.in_array (Periodical_origin, cfg.citation_issue_t) then -- {{citation}} may render |issue= when these parameters are used | if utilities.is_set (Periodical) and utilities.in_array (Periodical_origin, cfg.citation_issue_t) then -- {{citation}} may render |issue= when these parameters are used | ||
Issue = | Issue = A['Issue']; | ||
end | end | ||
elseif utilities.in_array (config.CitationClass, cfg.templates_using_issue) then -- conference & map books do not support issue; {{citation}} listed here because included in settings table | elseif utilities.in_array (config.CitationClass, cfg.templates_using_issue) then -- conference & map books do not support issue; {{citation}} listed here because included in settings table | ||
if not (utilities.in_array (config.CitationClass, {'conference', 'map', 'citation'}) and not (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical))) then | if not (utilities.in_array (config.CitationClass, {'conference', 'map', 'citation'}) and not (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical))) then | ||
Issue = | Issue = A['Issue']; | ||
end | end | ||
end | end | ||
| Line 2,995: | Line 3,036: | ||
end | end | ||
extra_text_in_vol_iss_check (Issue, A:ORIGIN ('Issue'), 'i'); | extra_text_in_vol_iss_check (Issue, A:ORIGIN ('Issue'), 'i'); | ||
Issue = utilities.hyphen_to_dash (Issue); | |||
local Page; | local Page; | ||
| Line 3,236: | Line 3,278: | ||
end | end | ||
local cs2_lower = function (text) -- if mode is cs2, use lower case | |||
| ⚫ | |||
return text:lower(); | |||
end | |||
return text; | |||
end | |||
local use_lowercase = ( sepc == ',' ); -- controls capitalization of certain static text | local use_lowercase = ( sepc == ',' ); -- controls capitalization of certain static text | ||
| Line 3,891: | Line 3,940: | ||
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'minutes') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'time')}); | utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'minutes') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'time')}); | ||
end | end | ||
Position = " " .. Minutes .. " " .. cfg.messages['minutes']; | --Position = " " .. Minutes .. " " .. cfg.messages['minutes']; | ||
Position = utilities.substitute (cfg.messages.minutes, Minutes); | |||
else | else | ||
if utilities.is_set (Time) then | if utilities.is_set (Time) then | ||
local TimeCaption = A['TimeCaption'] | local TimeCaption = A['TimeCaption'] | ||
if not utilities.is_set (TimeCaption) then | if not utilities.is_set (TimeCaption) then | ||
TimeCaption = cfg.messages['event']; | TimeCaption = cs2_lower(cfg.messages['event']); | ||
| ⚫ | |||
TimeCaption = TimeCaption:lower(); | |||
| ⚫ | |||
end | end | ||
Position = " " .. TimeCaption .. " " .. Time; | Position = " " .. TimeCaption .. " " .. Time; | ||
| Line 3,972: | Line 4,019: | ||
if utilities.is_set (AccessDate) then | if utilities.is_set (AccessDate) then | ||
local retrv_text = " " .. cfg.messages['retrieved'] | local retrv_text = " " .. cfg.messages['retrieved']; | ||
AccessDate = nowrap_date (AccessDate); -- wrap in nowrap span if date in appropriate format | AccessDate = nowrap_date (AccessDate); -- wrap in nowrap span if date in appropriate format | ||
retrv_text = cs2_lower(retrv_text);-- if mode is cs2, lower case | |||
AccessDate = utilities.substitute (retrv_text, AccessDate); -- add retrieved text | AccessDate = utilities.substitute (retrv_text, AccessDate); -- add retrieved text | ||
| Line 4,022: | Line 4,069: | ||
local arch_text; | local arch_text; | ||
if "live" == UrlStatus then | if "live" == UrlStatus then | ||
arch_text = cfg.messages['archived']; | |||
if sepc ~= "." then arch_text = arch_text:lower() end | |||
if utilities.is_set (ArchiveDate) then | if utilities.is_set (ArchiveDate) then | ||
Archived = sepc .. ' ' .. utilities.substitute ( cfg.messages['archived-live'], | Archived = sepc .. ' ' .. utilities.substitute ( cfg.messages['archived-live'], | ||
{external_link( ArchiveURL, | { external_link( ArchiveURL, cs2_lower(cfg.messages['archived']), A:ORIGIN('ArchiveURL'), nil) .. ArchiveFormat, ArchiveDate } ); | ||
else | else | ||
Archived = ''; | Archived = ''; | ||
| Line 4,036: | Line 4,081: | ||
elseif utilities.is_set (OriginalURL) then -- UrlStatus is empty, 'dead', 'unfit', 'usurped', 'bot: unknown' | elseif utilities.is_set (OriginalURL) then -- UrlStatus is empty, 'dead', 'unfit', 'usurped', 'bot: unknown' | ||
if utilities.in_array (UrlStatus, {'unfit', 'usurped', 'bot: unknown'}) then | if utilities.in_array (UrlStatus, {'unfit', 'usurped', 'bot: unknown'}) then | ||
Archived = sepc .. ' ' .. utilities.substitute ( cs2_lower(cfg.messages['archived-unfit']), ArchiveDate); | |||
if sepc ~= "." then arch_text = arch_text:lower() end | |||
Archived = sepc .. ' ' .. arch_text .. ArchiveDate; -- format already styled | |||
if 'bot: unknown' == UrlStatus then | if 'bot: unknown' == UrlStatus then | ||
utilities.set_message ('maint_bot_unknown'); -- and add a category if not already added | utilities.set_message ('maint_bot_unknown'); -- and add a category if not already added | ||
| Line 4,045: | Line 4,088: | ||
end | end | ||
else -- UrlStatus is empty, 'dead' | else -- UrlStatus is empty, 'dead' | ||
arch_text = cfg.messages['archived-dead']; | |||
if sepc ~= "." then arch_text = arch_text:lower() end | |||
if utilities.is_set (ArchiveDate) then | if utilities.is_set (ArchiveDate) then | ||
Archived = sepc .. | Archived = sepc .. ' ' .. utilities.substitute ( cs2_lower(cfg.messages['archived-dead']), | ||
{ external_link( OriginalURL, cfg.messages['original'], OriginalURL_origin, OriginalAccess ) .. OriginalFormat, ArchiveDate } ); | { external_link( OriginalURL, cfg.messages['original'], OriginalURL_origin, OriginalAccess ) .. OriginalFormat, ArchiveDate } ); | ||
else | else | ||
Archived = ''; -- unset for concatenation | Archived = ''; -- unset for concatenation | ||
| Line 4,199: | Line 4,240: | ||
if utilities.is_set (Chapter) and 0 == #c then | if utilities.is_set (Chapter) and 0 == #c then | ||
in_text = cfg.messages['in'] .. ' '; | in_text = cfg.messages['in'] .. ' '; | ||
| ⚫ | |||
| ⚫ | |||
| ⚫ | |||
| ⚫ | |||
end | end | ||
if EditorCount <= 1 then | if EditorCount <= 1 then | ||
| Line 4,212: | Line 4,251: | ||
if utilities.is_set (Contributors) then -- book cite and we're citing the intro, preface, etc. | if utilities.is_set (Contributors) then -- book cite and we're citing the intro, preface, etc. | ||
local by_text = sepc .. ' ' .. cfg.messages['by'] .. ' '; | local by_text = sepc .. ' ' .. cfg.messages['by'] .. ' '; | ||
by_text = cs2_lower(by_text);-- lowercase for cs2 | |||
Authors = by_text .. Authors; -- author follows title so tweak it here | Authors = by_text .. Authors; -- author follows title so tweak it here | ||
if utilities.is_set (Editors) and utilities.is_set (Date) then -- when Editors make sure that Authors gets terminated | if utilities.is_set (Editors) and utilities.is_set (Date) then -- when Editors make sure that Authors gets terminated | ||
| Line 4,307: | Line 4,346: | ||
end | end | ||
--local template_name = ('citation' == config.CitationClass) and 'citation' or 'cite ' .. (cfg.citation_class_map_t[config.CitationClass] or config.CitationClass); | |||
local template_name = cfg.citation_class_map_t[config.CitationClass]; | |||
local template_link = '[[Template:' .. template_name .. '|' .. template_name .. ']]'; | local template_link = '[[Template:' .. template_name .. '|' .. template_name .. ']]'; | ||
local msg_prefix = '<code class="cs1-code">{{' .. template_link .. '}}</code>: '; | local msg_prefix = '<code class="cs1-code">{{' .. template_link .. '}}</code>: '; | ||
| Line 4,649: | Line 4,689: | ||
elseif not utilities.is_set (v) then -- for empty parameters | elseif not utilities.is_set (v) then -- for empty parameters | ||
if not validate (k, config_t.CitationClass, true) then -- is this empty parameter a valid parameter | if not validate (k, config_t.CitationClass, true) then -- is this empty parameter a valid parameter | ||
k = ('' == k) and | k = ('' == k) and cfg.err_msg_supl.empty_str or k; -- when k is empty string (or was space(s) trimmed to empty string), replace with descriptive text | ||
table.insert (empty_unknowns, utilities.wrap_style ('parameter', k)); -- format for error message and add to the list | table.insert (empty_unknowns, utilities.wrap_style ('parameter', k)); -- format for error message and add to the list | ||
end | end | ||