Sətir 5: |
Sətir 5: |
| ]] | | ]] |
| | | |
− | local dates, year_date_check, reformat_dates, date_hyphen_to_dash, -- functions in Module:Citation/CS1/Date_validation | + | local dates, year_date_check, reformat_dates -- functions in Module:Citation/CS1/Date_validation |
− | date_name_xlate
| |
| | | |
| local is_set, in_array, substitute, error_comment, set_error, select_one, -- functions in Module:Citation/CS1/Utilities | | local is_set, in_array, substitute, error_comment, set_error, select_one, -- functions in Module:Citation/CS1/Utilities |
− | add_maint_cat, wrap_style, safe_for_italics, is_wikilink, make_wikilink; | + | add_maint_cat, wrap_style, safe_for_italics, remove_wiki_link; |
| | | |
| local z ={}; -- tables in Module:Citation/CS1/Utilities | | local z ={}; -- tables in Module:Citation/CS1/Utilities |
| | | |
− | local extract_ids, extract_id_access_levels, build_id_list, is_embargoed; -- functions in Module:Citation/CS1/Identifiers | + | local extract_ids, build_id_list, is_embargoed; -- functions in Module:Citation/CS1/Identifiers |
| | | |
| local make_coins_title, get_coins_pages, COinS; -- functions in Module:Citation/CS1/COinS | | local make_coins_title, get_coins_pages, COinS; -- functions in Module:Citation/CS1/COinS |
Sətir 19: |
Sətir 18: |
| 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 |
− |
| |
− |
| |
− | --[[--------------------------< P A G E S C O P E V A R I A B L E S >--------------------------------------
| |
− |
| |
− | delare variables here that have page-wide scope that are not brought in from other modules; thatare created here
| |
− | and used here
| |
− |
| |
− | ]]
| |
− |
| |
− | local added_deprecated_cat; -- boolean flag so that the category is added only once
| |
− | local added_prop_cats = {}; -- list of property categories that have been added to z.properties_cats
| |
− | local added_vanc_errs; -- boolean flag so we only emit one Vancouver error / category
| |
− |
| |
− | local Frame; -- holds the module's frame table
| |
− |
| |
| | | |
| --[[--------------------------< F I R S T _ S E T >------------------------------------------------------------ | | --[[--------------------------< F I R S T _ S E T >------------------------------------------------------------ |
Sətir 55: |
Sətir 39: |
| end | | end |
| end | | end |
− |
| |
| | | |
| --[[--------------------------< A D D _ P R O P _ C A T >-------------------------------------------------------- | | --[[--------------------------< A D D _ P R O P _ C A T >-------------------------------------------------------- |
| | | |
| Adds a category to z.properties_cats using names from the configuration file with additional text if any. | | Adds a category to z.properties_cats using names from the configuration file with additional text if any. |
− |
| |
− | foreign_lang_source and foreign_lang_source_2 keys have a language code appended to them so that multiple languages
| |
− | may be categorized but multiples of the same language are not categorized.
| |
− |
| |
− | added_prop_cats is a table declared in page scope variables above
| |
| | | |
| ]] | | ]] |
| | | |
| + | local added_prop_cats = {} -- list of property categories that have been added to z.properties_cats |
| local function add_prop_cat (key, arguments) | | local function add_prop_cat (key, arguments) |
− | --[[ отключено для рувики
| |
| if not added_prop_cats [key] then | | if not added_prop_cats [key] then |
| added_prop_cats [key] = true; -- note that we've added this category | | added_prop_cats [key] = true; -- note that we've added this category |
− | key = key:gsub ('(foreign_lang_source_?2?)%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 | | table.insert( z.properties_cats, substitute (cfg.prop_cats [key], arguments)); -- make name then add to table |
| end | | end |
− | ]]
| |
| end | | end |
− |
| |
| | | |
| --[[--------------------------< A D D _ V A N C _ E R R O R >---------------------------------------------------- | | --[[--------------------------< A D D _ V A N C _ E R R O R >---------------------------------------------------- |
Sətir 83: |
Sətir 58: |
| Adds a single Vancouver system error message to the template's output regardless of how many error actually exist. | | Adds a single Vancouver system error message to the template's output regardless of how many error actually exist. |
| To prevent duplication, added_vanc_errs is nil until an error message is emitted. | | To prevent duplication, added_vanc_errs is nil until an error message is emitted. |
− |
| |
− | added_vanc_errs is a boolean declared in page scope variables above
| |
| | | |
| ]] | | ]] |
| | | |
− | local function add_vanc_error (source) | + | local added_vanc_errs; -- flag so we only emit one Vancouver error / category |
| + | local function add_vanc_error () |
| if not added_vanc_errs then | | if not added_vanc_errs then |
| added_vanc_errs = true; -- note that we've added this category | | added_vanc_errs = true; -- note that we've added this category |
− | table.insert( z.message_tail, { set_error( 'vancouver', {source}, true ) } ); | + | table.insert( z.message_tail, { set_error( 'vancouver', {}, true ) } ); |
| end | | end |
| end | | end |
Sətir 135: |
Sətir 109: |
| the first character of the whole domain name including subdomains must be a letter or a digit | | 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 | | 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 and .cash TLDs | + | single-letter/digit second-level domains in the .org TLD |
| q, x, and z SL domains in the .com TLD | | q, x, and z SL domains in the .com TLD |
| i and q SL domains in the .net TLD | | i and q SL domains in the .net TLD |
Sətir 162: |
Sətir 136: |
| elseif domain:match ('%f[%a%d][%a%d][%a%d%-]+[%a%d]%.xn%-%-[%a%d]+$') then -- internationalized domain name with ACE prefix | | elseif domain:match ('%f[%a%d][%a%d][%a%d%-]+[%a%d]%.xn%-%-[%a%d]+$') then -- internationalized domain name with ACE prefix |
| return true; | | return true; |
− | elseif domain:match ('%f[%a%d][%a%d]%.cash$') then -- one character/digit .cash hostname
| + | elseif domain:match ('%f[%a%d][%a%d]%.org$') then -- one character .org hostname |
− | return true;
| |
− | elseif domain:match ('%f[%a%d][%a%d]%.org$') then -- one character/digit .org hostname | |
| return true; | | return true; |
| elseif domain:match ('%f[%a][qxz]%.com$') then -- assigned one character .com hostname (x.com times out 2015-12-10) | | elseif domain:match ('%f[%a][qxz]%.com$') then -- assigned one character .com hostname (x.com times out 2015-12-10) |
Sətir 260: |
Sətir 232: |
| return not is_url (scheme, domain); -- return true if value DOES NOT appear to be a valid url | | return not is_url (scheme, domain); -- return true if value DOES NOT appear to be a valid url |
| end | | end |
− |
| |
| | | |
| --[[--------------------------< L I N K _ T I T L E _ O K >--------------------------------------------------- | | --[[--------------------------< L I N K _ T I T L E _ O K >--------------------------------------------------- |
Sətir 388: |
Sətir 359: |
| ['\n'] = ' ' } ); | | ['\n'] = ' ' } ); |
| end | | end |
− |
| |
| | | |
| --[[--------------------------< E X T E R N A L _ L I N K >---------------------------------------------------- | | --[[--------------------------< E X T E R N A L _ L I N K >---------------------------------------------------- |
Sətir 396: |
Sətir 366: |
| ]] | | ]] |
| | | |
− | local function external_link( URL, label, source, access) | + | local function external_link( URL, label, source ) |
| local error_str = ""; | | local error_str = ""; |
| local domain; | | local domain; |
| local path; | | local path; |
− | local base_url;
| |
| | | |
| if not is_set( label ) then | | if not is_set( label ) then |
Sətir 417: |
Sətir 386: |
| if path then -- if there is a path portion | | if path then -- if there is a path portion |
| path = path:gsub ('[%[%]]', {['[']='%5b',[']']='%5d'}); -- replace '[' and ']' with their percent encoded values | | path = path:gsub ('[%[%]]', {['[']='%5b',[']']='%5d'}); -- replace '[' and ']' with their percent encoded values |
− | URL = table.concat ({domain, path}); -- and reassemble | + | URL=domain..path; -- and reassemble |
− | end
| |
− | | |
− | base_url = table.concat({ "[", URL, " ", safe_for_url (label), "]" }); -- assemble a wikimarkup url
| |
− |
| |
− | if is_set (access) then -- access level (subscription, registration, limited)
| |
− | base_url = substitute (cfg.presentation['ext-link-access-signal'], {cfg.presentation[access].class, cfg.presentation[access].title, base_url}); -- add the appropriate icon
| |
| end | | end |
| | | |
− | return table.concat ({base_url, error_str}); | + | return table.concat({ "[", URL, " ", safe_for_url( label ), "]", error_str }); |
| end | | end |
| | | |
Sətir 435: |
Sətir 398: |
| offending parameter name to the error message. Only one error message is emitted regardless of the number of deprecated | | offending parameter name to the error message. Only one error message is emitted regardless of the number of deprecated |
| parameters in the citation. | | parameters in the citation. |
− |
| |
− | added_deprecated_cat is a boolean declared in page scope variables above
| |
| | | |
| ]] | | ]] |
| | | |
| + | local page_in_deprecated_cat; -- sticky flag so that the category is added only once |
| local function deprecated_parameter(name) | | local function deprecated_parameter(name) |
− | if not added_deprecated_cat then | + | if not page_in_deprecated_cat then |
− | added_deprecated_cat = true; -- note that we've added this category | + | page_in_deprecated_cat = true; -- note that we've added this category |
| table.insert( z.message_tail, { set_error( 'deprecated_params', {name}, true ) } ); -- add error message | | table.insert( z.message_tail, { set_error( 'deprecated_params', {name}, true ) } ); -- add error message |
| end | | end |
| end | | end |
| | | |
| + | --[[--------------------------< K E R N _ Q U O T E S >-------------------------------------------------------- |
| | | |
− | --[=[-------------------------< K E R N _ Q U O T E S >--------------------------------------------------------
| + | Apply kerning to open the space between the quote mark provided by the Module and a leading or trailing quote mark contained in a |title= or |chapter= parameter's value. |
− | | |
− | Apply kerning to open the space between the quote mark provided by the Module and a leading or trailing quote | |
− | mark contained in a |title= or |chapter= parameter's value. | |
− | | |
| This function will positive kern either single or double quotes: | | This function will positive kern either single or double quotes: |
| "'Unkerned title with leading and trailing single quote marks'" | | "'Unkerned title with leading and trailing single quote marks'" |
| " 'Kerned title with leading and trailing single quote marks' " (in real life the kerning isn't as wide as this example) | | " 'Kerned title with leading and trailing single quote marks' " (in real life the kerning isn't as wide as this example) |
| Double single quotes (italic or bold wikimarkup) are not kerned. | | Double single quotes (italic or bold wikimarkup) are not kerned. |
− |
| |
− | Replaces unicode quotemarks in plain text or in the label portion of a [[L|D]] style wikilink with typewriter
| |
− | quote marks regardless of the need for kerning. Unicode quote marks are not replaced in simple [[D]] wikilinks.
| |
| | | |
| Call this function for chapter titles, for website titles, etc; not for book titles. | | Call this function for chapter titles, for website titles, etc; not for book titles. |
| | | |
− | ]=] | + | ]] |
| | | |
| local function kern_quotes (str) | | local function kern_quotes (str) |
| local cap=''; | | local cap=''; |
| local cap2=''; | | local cap2=''; |
− | local wl_type, label, link;
| |
− |
| |
− | wl_type, label, link = is_wikilink (str); -- wl_type is: 0, no wl (text in label variable); 1, [[D]]; 2, [[L|D]]
| |
| | | |
− | if 1 == wl_type then -- [[D]] simple wikilink with or without quote marks | + | cap, cap2 = str:match ("^([\"\'])([^\'].+)"); -- match leading double or single quote but not double single quotes |
− | if mw.ustring.match (str, '%[%[[\"“”\'‘’].+[\"“”\'‘’]%]%]') then -- leading and trailing quote marks
| + | if is_set (cap) then |
− | str = substitute (cfg.presentation['kern-wl-both'], str);
| + | str = substitute (cfg.presentation['kern-left'], {cap, cap2}); |
− | elseif mw.ustring.match (str, '%[%[[\"“”\'‘’].+%]%]') then -- leading quote marks
| + | end |
− | str = substitute (cfg.presentation['kern-wl-left'], str);
| |
− | elseif mw.ustring.match (str, '%[%[.+[\"“”\'‘’]%]%]') then -- trailing quote marks | |
− | str = substitute (cfg.presentation['kern-wl-right'], str);
| |
− | end
| |
| | | |
− | else -- plain text or [[L|D]]; text in label variable | + | cap, cap2 = str:match ("^(.+[^\'])([\"\'])$") |
− | label= mw.ustring.gsub (label, '[“”]', '\"'); -- replace “” (U+201C & U+201D) with " (typewriter double quote mark)
| + | if is_set (cap) then |
− | label= mw.ustring.gsub (label, '[‘’]', '\''); -- replace ‘’ (U+2018 & U+2019) with ' (typewriter single quote mark)
| + | str = substitute (cfg.presentation['kern-right'], {cap, cap2}); |
− | | |
− | cap, cap2 = mw.ustring.match (label, "^([\"\'])([^\'].+)"); -- match leading double or single quote but not doubled single quotes (italic markup)
| |
− | if is_set (cap) then
| |
− | label = substitute (cfg.presentation['kern-left'], {cap, cap2});
| |
− | end
| |
− |
| |
− | cap, cap2 = mw.ustring.match (label, "^(.+[^\'])([\"\'])$") -- match trailing double or single quote but not doubled single quotes (italic markup)
| |
− | if is_set (cap) then
| |
− | label = substitute (cfg.presentation['kern-right'], {cap, cap2});
| |
− | end
| |
− |
| |
− | if 2 == wl_type then
| |
− | str = make_wikilink (link, label); -- reassemble the wikilink
| |
− | else
| |
− | str = label;
| |
− | end
| |
| end | | end |
| return str; | | return str; |
| end | | end |
− |
| |
| | | |
| --[[--------------------------< F O R M A T _ S C R I P T _ V A L U E >---------------------------------------- | | --[[--------------------------< F O R M A T _ S C R I P T _ V A L U E >---------------------------------------- |
Sətir 539: |
Sətir 471: |
| end | | end |
| -- if we get this far we have prefix and script | | -- if we get this far we have prefix and script |
− | name = cfg.lang_code_remap[lang] or mw.language.fetchLanguageName( lang, "en" ); -- get language name so that we can use it to categorize | + | name = mw.language.fetchLanguageName( lang, "en" ); -- 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? | | 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%l%s*:%s*', ''); -- strip prefix from script |
| -- is prefix one of these language codes? | | -- is prefix one of these language codes? |
− | if in_array (lang, cfg.script_lang_codes) then | + | if in_array (lang, {'am', 'ar', 'be', 'bg', 'bs', 'dv', 'el', 'fa', 'he', 'hy', 'ja', 'ka', 'ko', 'ku', 'mk', 'ml', 'ps', 'ru', 'sd', 'sr', 'th', 'uk', 'ug', 'yi', 'zh'}) then |
| add_prop_cat ('script_with_name', {name, lang}) | | add_prop_cat ('script_with_name', {name, lang}) |
| else | | else |
Sətir 557: |
Sətir 489: |
| return script_value; | | return script_value; |
| end | | end |
− |
| |
| | | |
| --[[--------------------------< S C R I P T _ C O N C A T E N A T E >------------------------------------------ | | --[[--------------------------< S C R I P T _ C O N C A T E N A T E >------------------------------------------ |
Sətir 605: |
Sətir 536: |
| ]] | | ]] |
| | | |
− | local function format_chapter_title (scriptchapter, chapter, transchapter, chapterurl, chapter_url_source, no_quotes, access) | + | local function format_chapter_title (scriptchapter, chapter, transchapter, chapterurl, chapter_url_source, no_quotes) |
| local chapter_error = ''; | | local chapter_error = ''; |
| | | |
Sətir 612: |
Sətir 543: |
| else | | else |
| if false == no_quotes then | | if false == no_quotes then |
− | chapter = kern_quotes (chapter); -- if necessary, separate chapter title's leading and trailing quote marks from Module provided quote marks | + | chapter = kern_quotes (chapter); -- if necessary, separate chapter title's leading and trailing quote marks from Module provided quote marks |
| chapter = wrap_style ('quoted-title', chapter); | | chapter = wrap_style ('quoted-title', chapter); |
| end | | end |
Sətir 618: |
Sətir 549: |
| | | |
| chapter = script_concatenate (chapter, scriptchapter) -- <bdi> tags, lang atribute, categorization, etc; must be done after title is wrapped | | chapter = script_concatenate (chapter, scriptchapter) -- <bdi> tags, lang atribute, categorization, etc; must be done after title is wrapped |
− |
| |
− | if is_set (chapterurl) then
| |
− | chapter = external_link (chapterurl, chapter, chapter_url_source, access); -- adds bare_url_missing_title error if appropriate
| |
− | end
| |
| | | |
| if is_set (transchapter) then | | if is_set (transchapter) then |
Sətir 633: |
Sətir 560: |
| end | | end |
| | | |
− | -- if is_set (chapterurl) then
| + | if is_set (chapterurl) then |
− | -- chapter = external_link (chapterurl, chapter, chapter_url_source, access); -- adds bare_url_missing_title error if appropriate
| + | chapter = external_link (chapterurl, chapter, chapter_url_source); -- adds bare_url_missing_title error if appropriate |
− | -- end
| + | end |
| | | |
| return chapter .. chapter_error; | | return chapter .. chapter_error; |
| end | | end |
− |
| |
| | | |
| --[[--------------------------< H A S _ I N V I S I B L E _ C H A R S >---------------------------------------- | | --[[--------------------------< H A S _ I N V I S I B L E _ C H A R S >---------------------------------------- |
Sətir 675: |
Sətir 601: |
| local pattern=cfg.invisible_chars[i][2] -- the pattern used to find it | | local pattern=cfg.invisible_chars[i][2] -- the pattern used to find it |
| position, dummy, capture = mw.ustring.find (v, pattern) -- see if the parameter value contains characters that match the pattern | | position, dummy, capture = mw.ustring.find (v, pattern) -- see if the parameter value contains characters that match the pattern |
− |
| |
− | if position and (char == 'zero width joiner') then -- if we found a zero width joiner character
| |
− | if mw.ustring.find (v, cfg.indic_script) then -- its ok if one of the indic scripts
| |
− | position = nil; -- unset position
| |
− | end
| |
− | end
| |
| | | |
| if position then | | if position then |
− | if 'nowiki' == capture or 'math' == capture or -- nowiki and math stripmarkers (not an error condition) | + | if 'nowiki' == capture or 'math' == capture then -- nowiki, math stripmarker (not an error condition) |
− | ('templatestyles' == capture and in_array (param, {'id', 'quote'})) then -- templatestyles stripmarker allowed in these parameters | + | stripmarker = true; -- set a flag |
− | 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 | | 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 | | position = nil; -- unset |
Sətir 691: |
Sətir 610: |
| local err_msg; | | local err_msg; |
| if capture then | | if capture then |
− | err_msg = capture .. ' ' .. char; -- для рувики: TODO: не согласуется? | + | err_msg = capture .. ' ' .. char; |
| else | | else |
− | err_msg = 'Символ' .. ' ' .. char; -- для рувики | + | err_msg = char .. ' ' .. 'character'; |
| end | | end |
| | | |
Sətir 752: |
Sətir 671: |
| end, | | end, |
| }); | | }); |
| + | end |
| + | |
| + | --[[--------------------------< V A L I D A T E >-------------------------------------------------------------- |
| + | Looks for a parameter's name in the whitelist. |
| + | |
| + | Parameters in the whitelist can have three values: |
| + | true - active, supported parameters |
| + | false - deprecated, supported parameters |
| + | nil - unsupported parameters |
| + | |
| + | ]] |
| + | |
| + | local function validate( name ) |
| + | local name = tostring( name ); |
| + | local state = whitelist.basic_arguments[ name ]; |
| + | |
| + | -- Normal arguments |
| + | if true == state then return true; end -- valid actively supported parameter |
| + | if false == state then |
| + | deprecated_parameter (name); -- parameter is deprecated but still supported |
| + | return true; |
| + | end |
| + | |
| + | -- Arguments with numbers in them |
| + | name = name:gsub( "%d+", "#" ); -- replace digit(s) with # (last25 becomes last# |
| + | state = whitelist.numbered_arguments[ name ]; |
| + | if true == state then return true; end -- valid actively supported parameter |
| + | if false == state then |
| + | deprecated_parameter (name); -- parameter is deprecated but still supported |
| + | return true; |
| + | end |
| + | |
| + | return false; -- Not supported because not found or name is set to nil |
| end | | end |
| | | |
Sətir 778: |
Sətir 730: |
| return date; | | return date; |
| end | | end |
− |
| |
| | | |
| --[[--------------------------< S E T _ T I T L E T Y P E >---------------------------------------------------- | | --[[--------------------------< S E T _ T I T L E T Y P E >---------------------------------------------------- |
Sətir 801: |
Sətir 752: |
| --[[--------------------------< H Y P H E N _ T O _ D A S H >-------------------------------------------------- | | --[[--------------------------< H Y P H E N _ T O _ D A S H >-------------------------------------------------- |
| | | |
− | Converts a hyphen to a dash under certain conditions. The hyphen must separate like items; unlike items are | + | Converts a hyphen to a dash |
− | returned unmodified. These forms are modified:
| |
− | letter - letter (A - B)
| |
− | digit - digit (4-5)
| |
− | digit separator digit - digit separator digit (4.1-4.5 or 4-1-4-5)
| |
− | letterdigit - letterdigit (A1-A5) (an optional separator between letter and digit is supported – a.1-a.5 or a-1-a-5)
| |
− | digitletter - digitletter (5a - 5d) (an optional separator between letter and digit is supported – 5.a-5.d or 5-a-5-d)
| |
− | | |
− | any other forms are returned unmodified.
| |
− | | |
− | str may be a comma- or semicolon-separated list
| |
| | | |
| ]] | | ]] |
| | | |
| local function hyphen_to_dash( str ) | | local function hyphen_to_dash( str ) |
− | if not is_set (str) then | + | if not is_set(str) or str:match( "[%[%]{}<>]" ) ~= nil then |
| return str; | | return str; |
− | end | + | end |
− | | + | return str:gsub( '-', '–' ); |
− | str, count = str:gsub ('^%(%((.+)%)%)$', '%1'); -- remove accept-this-as-written markup when it wraps all of str
| |
− | if 0 ~= count then -- non-zero when markup removed; zero else
| |
− | return str; -- nothing to do, we're done
| |
− | end
| |
− |
| |
− | local out = {};
| |
− | local list = mw.text.split (str, '%s*[,;]%s*'); -- split str at comma or semicolon separators if there are any
| |
− | | |
− | 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 -- для рувики: всё наоборот
| |
− | item = mw.ustring.gsub (item, '%s*[–—]%s*', '—'); -- for endash or emdash separated ranges, replace em with en, remove extraneous white space
| |
− | end
| |
− | end
| |
− | item = item:gsub ('^%(%((.+)%)%)$', '%1'); -- remove the accept-this-as-written markup
| |
− | table.insert (out, item); -- add the (possibly modified) item to the output table
| |
− | end
| |
− | | |
− | return table.concat (out, ', '); -- concatenate the output table into a comma separated string
| |
| end | | end |
| | | |
Sətir 855: |
Sətir 771: |
| | | |
| local function safe_join( tbl, duplicate_char ) | | local function safe_join( tbl, duplicate_char ) |
− | local f = {}; -- create a function table appropriate to type of 'dupicate character' | + | --[[ |
− | if 1 == #duplicate_char then -- for single byte ascii characters use the string library functions
| + | Note: we use string functions here, rather than ustring functions. |
− | f.gsub=string.gsub
| + | |
− | f.match=string.match
| + | This has considerably faster performance and should work correctly as |
− | f.sub=string.sub
| + | long as the duplicate_char is strict ASCII. The strings |
− | else -- for multi-byte characters use the ustring library functions
| + | in tbl may be ASCII or UTF8. |
− | f.gsub=mw.ustring.gsub
| + | ]] |
− | f.match=mw.ustring.match
| + | |
− | f.sub=mw.ustring.sub
| |
− | end
| |
− | | |
| local str = ''; -- the output string | | local str = ''; -- the output string |
| local comp = ''; -- what does 'comp' mean? | | local comp = ''; -- what does 'comp' mean? |
Sətir 882: |
Sətir 795: |
| end | | end |
| -- typically duplicate_char is sepc | | -- typically duplicate_char is sepc |
− | if f.sub(comp, 1,1) == duplicate_char then -- is first character same as duplicate_char? why test first character? | + | if comp:sub(1,1) == duplicate_char then -- is first charactier same as duplicate_char? why test first character? |
− | -- Because individual string segments often (always?) begin with terminal punct for the | + | -- Because individual string segments often (always?) begin with terminal punct for th |
| -- preceding segment: 'First element' .. 'sepc next element' .. etc? | | -- preceding segment: 'First element' .. 'sepc next element' .. etc? |
| trim = false; | | trim = false; |
− | end_chr = f.sub(str, -1,-1); -- get the last character of the output string | + | end_chr = str:sub(-1,-1); -- get the last character of the output string |
| -- str = str .. "<HERE(enchr=" .. end_chr.. ")" -- debug stuff? | | -- str = str .. "<HERE(enchr=" .. end_chr.. ")" -- debug stuff? |
| if end_chr == duplicate_char then -- if same as separator | | if end_chr == duplicate_char then -- if same as separator |
− | str = f.sub(str, 1,-2); -- remove it | + | str = str:sub(1,-2); -- remove it |
| elseif end_chr == "'" then -- if it might be wikimarkup | | elseif end_chr == "'" then -- if it might be wikimarkup |
− | if f.sub(str, -3,-1) == duplicate_char .. "''" then -- if last three chars of str are sepc'' | + | if str:sub(-3,-1) == duplicate_char .. "''" then -- if last three chars of str are sepc'' |
− | str = f.sub(str, 1, -4) .. "''"; -- remove them and add back '' | + | str = str:sub(1, -4) .. "''"; -- remove them and add back '' |
− | elseif f.sub(str, -5,-1) == duplicate_char .. "]]''" then -- if last five chars of str are sepc]]'' | + | elseif str:sub(-5,-1) == duplicate_char .. "]]''" then -- if last five chars of str are sepc]]'' |
| trim = true; -- why? why do this and next differently from previous? | | trim = true; -- why? why do this and next differently from previous? |
− | elseif f.sub(str, -4,-1) == duplicate_char .. "]''" then -- if last four chars of str are sepc]'' | + | elseif str:sub(-4,-1) == duplicate_char .. "]''" then -- if last four chars of str are sepc]'' |
| trim = true; -- same question | | trim = true; -- same question |
| end | | end |
| elseif end_chr == "]" then -- if it might be wikimarkup | | elseif end_chr == "]" then -- if it might be wikimarkup |
− | if f.sub(str, -3,-1) == duplicate_char .. "]]" then -- if last three chars of str are sepc]] wikilink | + | if str:sub(-3,-1) == duplicate_char .. "]]" then -- if last three chars of str are sepc]] wikilink |
| trim = true; | | trim = true; |
− | elseif f.sub(str, -3,-1) == duplicate_char .. '"]' then -- if last three chars of str are sepc"] quoted external link | + | elseif str:sub(-2,-1) == duplicate_char .. "]" then -- if last two chars of str are sepc] external link |
| trim = true; | | trim = true; |
− | elseif f.sub(str, -2,-1) == duplicate_char .. "]" then -- if last two chars of str are sepc] external link | + | elseif str:sub(-4,-1) == duplicate_char .. "'']" then -- normal case when |url=something & |title=Title. |
− | trim = true;
| |
− | elseif f.sub(str, -4,-1) == duplicate_char .. "'']" then -- normal case when |url=something & |title=Title.
| |
| trim = true; | | trim = true; |
| end | | end |
| elseif end_chr == " " then -- if last char of output string is a space | | elseif end_chr == " " then -- if last char of output string is a space |
− | if f.sub(str, -2,-1) == duplicate_char .. " " then -- if last two chars of str are <sepc><space> | + | if str:sub(-2,-1) == duplicate_char .. " " then -- if last two chars of str are <sepc><space> |
− | str = f.sub(str, 1,-3); -- remove them both | + | str = str:sub(1,-3); -- remove them both |
| end | | end |
| end | | end |
Sətir 917: |
Sətir 828: |
| if value ~= comp then -- value does not equal comp when value contains html markup | | if value ~= comp then -- value does not equal comp when value contains html markup |
| local dup2 = duplicate_char; | | local dup2 = duplicate_char; |
− | if f.match(dup2, "%A" ) then dup2 = "%" .. dup2; end -- if duplicate_char not a letter then escape it | + | if dup2:match( "%A" ) then dup2 = "%" .. dup2; end -- if duplicate_char not a letter then escape it |
| | | |
− | value = f.gsub(value, "(%b<>)" .. dup2, "%1", 1 ) -- remove duplicate_char if it follows html markup | + | value = value:gsub( "(%b<>)" .. dup2, "%1", 1 ) -- remove duplicate_char if it follows html markup |
| else | | else |
− | value = f.sub(value, 2, -1 ); -- remove duplicate_char when it is first character | + | value = value:sub( 2, -1 ); -- remove duplicate_char when it is first character |
| end | | end |
| end | | end |
Sətir 929: |
Sətir 840: |
| end | | end |
| return str; | | return str; |
− | end | + | end |
− | | |
− | | |
− | --[[--------------------------< I S _ S U F F I X >------------------------------------------------------------
| |
− | | |
− | returns true is suffix is properly formed Jr, Sr, or ordinal in the range 2–9. Puncutation not allowed.
| |
− | | |
− | ]]
| |
− | | |
− | local function is_suffix (suffix)
| |
− | if in_array (suffix, {'Jr', 'Sr', '2nd', '3rd'}) or suffix:match ('^%dth$') then
| |
− | return true;
| |
− | end
| |
− | return false;
| |
− | end
| |
− | | |
| | | |
| --[[--------------------------< I S _ G O O D _ V A N C _ N A M E >-------------------------------------------- | | --[[--------------------------< I S _ G O O D _ V A N C _ N A M E >-------------------------------------------- |
Sətir 962: |
Sətir 858: |
| |firstn= also allowed to contain hyphens, spaces, apostrophes, and periods | | |firstn= also allowed to contain hyphens, spaces, apostrophes, and periods |
| | | |
− | This original test:
| + | At the time of this writing, I had to write the 'if nil == mw.ustring.find ...' test ouside of the code editor and paste it here |
− | if nil == mw.ustring.find (last, "^[A-Za-zÀ-ÖØ-öø-ƿDŽ-ɏ%-%s%']*$") or nil == mw.ustring.find (first, "^[A-Za-zÀ-ÖØ-öø-ƿDŽ-ɏ%-%s%'%.]+[2-6%a]*$") then
| + | because the code editor gets confused between character insertion point and cursor position. |
− | was written ouside of the code editor and pasted here because the code editor gets confused between character insertion point and cursor position.
| |
− | The test has been rewritten to use decimal character escape sequence for the individual bytes of the unicode characters so that it is not necessary
| |
− | to use an external editor to maintain this code.
| |
− | | |
− | \195\128-\195\150 – À-Ö (U+00C0–U+00D6 – C0 controls)
| |
− | \195\152-\195\182 – Ø-ö (U+00D8-U+00F6 – C0 controls)
| |
− | \195\184-\198\191 – ø-ƿ (U+00F8-U+01BF – C0 controls, Latin extended A & B)
| |
− | \199\132-\201\143 – DŽ-ɏ (U+01C4-U+024F – Latin extended B)
| |
| | | |
| ]] | | ]] |
| | | |
| local function is_good_vanc_name (last, first) | | local function is_good_vanc_name (last, first) |
− | local first, suffix = first:match ('(.-),?%s*([%dJS][%drndth]+)%.?$') or first; -- if first has something that looks like a generational suffix, get it
| + | if nil == mw.ustring.find (last, "^[A-Za-zÀ-ÖØ-öø-ƿDŽ-ɏ%-%s%']*$") or nil == mw.ustring.find (first, "^[A-Za-zÀ-ÖØ-öø-ƿDŽ-ɏ%-%s%'%.]*$") then |
− | | + | add_vanc_error (); |
− | if is_set (suffix) then
| + | return false; -- not a string of latin characters; Vancouver required Romanization |
− | if not is_suffix (suffix) then
| |
− | add_vanc_error ('suffix');
| |
− | return false; -- not a name with an appropriate suffix
| |
− | 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 | |
− | 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
| |
− | add_vanc_error ('non-Latin character');
| |
− | return false; -- not a string of latin characters; Vancouver requires Romanization
| |
| end; | | end; |
| return true; | | return true; |
| end | | end |
− |
| |
| | | |
| --[[--------------------------< R E D U C E _ T O _ I N I T I A L S >------------------------------------------ | | --[[--------------------------< R E D U C E _ T O _ I N I T I A L S >------------------------------------------ |
Sətir 999: |
Sətir 877: |
| Names in |firstn= may be separated by spaces or hyphens, or for initials, a period. See http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35062/. | | Names in |firstn= may be separated by spaces or hyphens, or for initials, a period. See http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35062/. |
| | | |
− | Vancouver style requires family rank designations (Jr, II, III, etc) to be rendered as Jr, 2nd, 3rd, etc. See http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35085/. | + | Vancouver style requires family rank designations (Jr, II, III, etc) to be rendered as Jr, 2nd, 3rd, etc. This form is not |
− | This code only accepts and understands generational suffix in the Vancouver format because Roman numerals look like, and can be mistaken for, initials.
| + | currently supported by this code so correctly formed names like Smith JL 2nd are converted to Smith J2. See http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35085/. |
| | | |
| This function uses ustring functions because firstname initials may be any of the unicode Latin characters accepted by is_good_vanc_name (). | | This function uses ustring functions because firstname initials may be any of the unicode Latin characters accepted by is_good_vanc_name (). |
Sətir 1.007: |
Sətir 885: |
| | | |
| local function reduce_to_initials(first) | | local function reduce_to_initials(first) |
− | local name, suffix = mw.ustring.match(first, "^(%u+) ([%dJS][%drndth]+)$"); | + | if mw.ustring.match(first, "^%u%u$") then return first end; -- when first contains just two upper-case letters, nothing to do |
− | | + | local initials = {} |
− | if not name then -- if not initials and a suffix | + | local i = 0; -- counter for number of initials |
− | name = mw.ustring.match(first, "^(%u+)$"); -- is it just intials?
| + | for word in mw.ustring.gmatch(first, "[^%s%.%-]+") do -- names separated by spaces, hyphens, or periods |
| + | table.insert(initials, mw.ustring.sub(word,1,1)) -- Vancouver format does not include full stops. |
| + | i = i + 1; -- bump the counter |
| + | if 2 <= i then break; end -- only two initials allowed in Vancouver system; if 2, quit |
| end | | end |
| + | return table.concat(initials) -- Vancouver format does not include spaces. |
| + | end |
| | | |
− | if name then -- if first is initials with or without suffix
| + | --[[--------------------------< L I S T _ P E O P L E >------------------------------------------------------- |
− | if 3 > mw.ustring.len (name) then -- if one or two initials
| |
− | if suffix then -- if there is a suffix
| |
− | if is_suffix (suffix) then -- is it legitimate?
| |
− | return first; -- one or two initials and a valid suffix so nothing to do
| |
− | else
| |
− | add_vanc_error ('suffix'); -- one or two initials with invalid suffix so error message
| |
− | return first; -- and return first unmolested
| |
− | end
| |
− | else
| |
− | return first; -- one or two initials without suffix; nothing to do
| |
− | end
| |
− | end
| |
− | 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 i = 1; -- counter for number of initials
| |
− | | |
− | names = mw.text.split (first, '[%s,]+'); -- split into a table of names and possible suffix
| |
− | | |
− | while names[i] do -- loop through the table
| |
− | if 1 < i and names[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
| |
− | if is_suffix (names[i]) then -- if a legitimate suffix
| |
− | table.insert (initials, ' ' .. names[i]); -- add a separator space, insert at end of initials table
| |
− | 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
| |
− | if 3 > i then
| |
− | table.insert (initials, mw.ustring.sub(names[i],1,1)); -- insert the intial at end of initials table
| |
− | end
| |
− | i = i+1; -- bump the counter
| |
− | end
| |
− |
| |
− | return table.concat(initials) -- Vancouver format does not include spaces.
| |
− | end
| |
− | | |
− | | |
− | --[[--------------------------< L I S T _ P E O P L E >------------------------------------------------------- | |
| | | |
| Formats a list of people (e.g. authors / editors) | | Formats a list of people (e.g. authors / editors) |
Sətir 1.067: |
Sətir 911: |
| | | |
| if 'vanc' == format then -- Vancouver-like author/editor name styling? | | if 'vanc' == format then -- Vancouver-like author/editor name styling? |
− | sep = cfg.presentation['sep_nl_vanc']; -- name-list separator between authors is a comma | + | sep = ','; -- name-list separator between authors is a comma |
− | namesep = cfg.presentation['sep_name_vanc']; -- last/first separator is a space | + | namesep = ' '; -- last/first separator is a space |
| else | | else |
− | sep = cfg.presentation['sep_nl']; -- name-list separator between authors is a semicolon | + | sep = ';' -- name-list separator between authors is a semicolon |
− | namesep = cfg.presentation['sep_name']; -- last/first separator is <comma><space> | + | namesep = ', ' -- last/first separator is <comma><space> |
| end | | end |
| | | |
Sətir 1.096: |
Sətir 940: |
| one = person.last | | one = person.last |
| local first = person.first | | local first = person.first |
− | if is_set(first) then | + | if is_set(first) then |
| if ( "vanc" == format ) then -- if vancouver format | | if ( "vanc" == format ) then -- if vancouver format |
| one = one:gsub ('%.', ''); -- remove periods from surnames (http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35029/) | | one = one:gsub ('%.', ''); -- remove periods from surnames (http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35029/) |
− | if not person.corporate and is_good_vanc_name (one, first) then -- and name is all Latin characters; corporate authors not tested | + | if not person.corporate and is_good_vanc_name (one, first) then -- and name is all Latin characters; corporate authors not tested |
| first = reduce_to_initials(first) -- attempt to convert first name(s) to initials | | first = reduce_to_initials(first) -- attempt to convert first name(s) to initials |
| end | | end |
| end | | end |
− | one = one .. namesep .. first; | + | one = one .. namesep .. first |
| end | | end |
| if is_set(person.link) and person.link ~= control.page_name then | | if is_set(person.link) and person.link ~= control.page_name then |
− | one = make_wikilink (person.link, one); -- link author/editor if this page is not the author's/editor's page | + | one = "[[" .. person.link .. "|" .. one .. "]]" -- link author/editor if this page is not the author's/editor's page |
| end | | end |
| end | | end |
Sətir 1.129: |
Sətir 973: |
| return result, count | | return result, count |
| end | | end |
− |
| |
| | | |
| --[[--------------------------< A N C H O R _ I D >------------------------------------------------------------ | | --[[--------------------------< A N C H O R _ I D >------------------------------------------------------------ |
Sətir 1.187: |
Sətir 1.030: |
| end | | end |
| | | |
| + | --[[--------------------------< N A M E _ H A S _ M U L T _ N A M E S >---------------------------------------- |
| | | |
− | --[[--------------------------< N A M E _ H A S _ E D _ M A R K U P >------------------------------------------
| + | 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 |
− | Evaluates the content of author and editor parameters for extranious editor annotations: ed, ed., eds, (Ed.), etc. | + | (author or editor) maintenance category. |
− | These annotation do not belong in author parameters and are redundant in editor parameters. If found, the function
| |
− | adds the editor markup maintenance category. | |
| | | |
| ]] | | ]] |
| | | |
− | local function name_has_ed_markup (name, list_name) | + | local function name_has_mult_names (name, list_name) |
− | local _, pattern;
| + | local count, _; |
− | local patterns = { -- these patterns match annotations at end of name
| |
− | '%f[%(%[][%(%[]%s*[Ee][Dd][Ss]?%.?%s*[%)%]]?$', -- (ed) or (eds): leading '(', case insensitive 'ed', optional 's', '.' and/or ')'
| |
− | '[,%.%s]%f[e]eds?%.?$', -- ed or eds: without '('or ')'; case sensitive (ED could be initials Ed could be name)
| |
− | '%f[%(%[][%(%[]%s*[Ee][Dd][Ii][Tt][Oo][Rr][Ss]?%.?%s*[%)%]]?$', -- (editor) or (editors): leading '(', case insensitive, optional '.' and/or ')'
| |
− | '[,%.%s]%f[Ee][Ee][Dd][Ii][Tt][Oo][Rr][Ss]?%.?$', -- editor or editors: without '('or ')'; case insensitive
| |
− |
| |
− | -- these patterns match annotations at beginning of name
| |
− | '^eds?[%.,;]', -- ed. or eds.: lower case only, optional 's', requires '.'
| |
− | '^[%(%[]%s*[Ee][Dd][Ss]?%.?%s*[%)%]]', -- (ed) or (eds): also sqare brackets, case insensitive, optional 's', '.'
| |
− | '^[%(%[]?%s*[Ee][Dd][Ii][Tt][Oo][Rr][Ss]?%A', -- (editor or (editors: also sq brackets, case insensitive, optional brackets, 's'
| |
− | '^[%(%[]?%s*[Ee][Dd][Ii][Tt][Ee][Dd]%A', -- (edited: also sq brackets, case insensitive, optional brackets
| |
− | }
| |
− | | |
| if is_set (name) then | | if is_set (name) then |
− | for _, pattern in ipairs (patterns) do -- spin through patterns table and | + | if name:match ('^%(%(.*%)%)$') then -- if wrapped in doubled parentheses, ignore |
− | if name:match (pattern) then | + | name = name:match ('^%(%((.*)%)%)$'); -- strip parens |
− | add_maint_cat ('extra_text_names', cfg.special_case_translation [list_name]); -- add a maint cat for this template | + | else |
− | break;
| + | _, 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 | | end |
Sətir 1.222: |
Sətir 1.054: |
| end | | end |
| | | |
| + | --[[--------------------------< E X T R A C T _ N A M E S >---------------------------------------------------- |
| + | Gets name list from the input arguments |
| | | |
− | --[[--------------------------< N A M E _ H A S _ M U L T _ N A M E S >----------------------------------------
| + | Searches through args in sequential order to find |lastn= and |firstn= parameters (or their aliases), and their matching link and mask parameters. |
− | | + | Stops searching when both |lastn= and |firstn= are not found in args after two sequential attempts: found |last1=, |last2=, and |last3= but doesn't |
− | Evaluates the content of author and editor (surnames only) parameters for multiple names. Multiple names are
| + | find |last4= and |last5= then the search is done. |
− | 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
| |
− | _, count = name:gsub ('[;,]', ''); -- count the number of separator-like characters
| |
− |
| |
− | if 1 < count then -- param could be |author= or |editor= so one separator character is acceptable
| |
− | add_maint_cat ('mult_names', cfg.special_case_translation [list_name]); -- more than one separator indicates multiple names so add a maint cat for this template
| |
− | end
| |
− | end
| |
− | return name; -- and done
| |
− | end
| |
− | | |
− | | |
− | --[[--------------------------< N A M E _ C H E C K S >--------------------------------------------------------
| |
− | This function calls various name checking functions used to validate the content of the various name-holding
| |
− | parameters.
| |
− | | |
− | ]]
| |
− | | |
− | local function name_checks (last, first, list_name)
| |
− | if is_set (last) then
| |
− | if last:match ('^%(%(.*%)%)$') then -- if wrapped in doubled parentheses, accept as written
| |
− | last = last:match ('^%(%((.*)%)%)$'); -- strip parens
| |
− | else
| |
− | last = name_has_mult_names (last, list_name); -- check for multiple names in the parameter (last only)
| |
− | last = name_has_ed_markup (last, list_name); -- check for extraneous 'editor' annotation
| |
− | end
| |
− | end
| |
− | if is_set (first) then
| |
− | if first:match ('^%(%(.*%)%)$') then -- if wrapped in doubled parentheses, accept as written
| |
− | first = first:match ('^%(%((.*)%)%)$'); -- strip parens
| |
− | else
| |
− | first = name_has_ed_markup (first, list_name); -- check for extraneous 'editor' annotation
| |
− | end
| |
− | end
| |
− | return last, first; -- done
| |
− | end
| |
− | | |
− | | |
− | --[[--------------------------< E X T R A C T _ N A M E S >----------------------------------------------------
| |
− | Gets name list from the input arguments
| |
− | | |
− | Searches through args in sequential order to find |lastn= and |firstn= parameters (or their aliases), and their matching link and mask parameters. | |
− | Stops searching when both |lastn= and |firstn= are not found in args after two sequential attempts: found |last1=, |last2=, and |last3= but doesn't | |
− | find |last4= and |last5= then the search is done. | |
| | | |
| This function emits an error message when there is a |firstn= without a matching |lastn=. When there are 'holes' in the list of last names, |last1= and |last3= | | This function emits an error message when there is a |firstn= without a matching |lastn=. When there are 'holes' in the list of last names, |last1= and |last3= |
Sətir 1.306: |
Sətir 1.090: |
| last, etal = name_has_etal (last, etal, false); -- find and remove variations on et al. | | 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. | | first, etal = name_has_etal (first, etal, false); -- find and remove variations on et al. |
− | last, first= name_checks (last, first, list_name); -- multiple names, extraneous annotation, etc checks | + | 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 | | if first and not last then -- if there is a firstn without a matching lastn |
Sətir 1.330: |
Sətir 1.114: |
| return names, etal; -- all done, return our list of names | | return names, etal; -- all done, return our list of names |
| end | | end |
− |
| |
| | | |
| --[[--------------------------< G E T _ I S O 6 3 9 _ C O D E >------------------------------------------------ | | --[[--------------------------< G E T _ I S O 6 3 9 _ C O D E >------------------------------------------------ |
Sətir 1.341: |
Sətir 1.124: |
| return the original language name string. | | return the original language name string. |
| | | |
− | mw.language.fetchLanguageNames(<local wiki language>, 'all') returns a list of languages that in some cases may include | + | mw.language.fetchLanguageNames(<local wiki language>, 'all') return a list of languages that in some cases may include |
| extensions. For example, code 'cbk-zam' and its associated name 'Chavacano de Zamboanga' (MediaWiki does not support | | extensions. For example, code 'cbk-zam' and its associated name 'Chavacano de Zamboanga' (MediaWiki does not support |
− | code 'cbk' or name 'Chavacano'. Most (all?) of these languages are not used a 'language' codes per se, rather they | + | code 'cbk' or name 'Chavacano'. |
− | are used as sub-domain names: cbk-zam.wikipedia.org. These names can be found (for the time being) at
| |
− | https://phabricator.wikimedia.org/diffusion/ECLD/browse/master/LocalNames/LocalNamesEn.php
| |
| | | |
| Names but that are included in the list will be found if that name is provided in the |language= parameter. For example, | | Names but that are included in the list will be found if that name is provided in the |language= parameter. For example, |
Sətir 1.356: |
Sətir 1.137: |
| | | |
| local function get_iso639_code (lang, this_wiki_code) | | local function get_iso639_code (lang, this_wiki_code) |
− | if cfg.lang_name_remap[lang:lower()] then -- if there is a remapped name (because MediaWiki uses something that we don't think is correct)
| |
− | return cfg.lang_name_remap[lang:lower()][1], cfg.lang_name_remap[lang:lower()][2]; -- for this language 'name', return a possibly new name and appropriate code
| |
− | end
| |
− |
| |
| local languages = mw.language.fetchLanguageNames(this_wiki_code, 'all') -- get a list of language names known to Wikimedia | | local languages = mw.language.fetchLanguageNames(this_wiki_code, 'all') -- get a list of language names known to Wikimedia |
| -- ('all' is required for North Ndebele, South Ndebele, and Ojibwa) | | -- ('all' is required for North Ndebele, South Ndebele, and Ojibwa) |
Sətir 1.374: |
Sətir 1.151: |
| return lang; -- not valid language; return language in original case and nil for the code | | return lang; -- not valid language; return language in original case and nil for the code |
| end | | end |
− |
| |
| | | |
| --[[--------------------------< L A N G U A G E _ P A R A M E T E R >------------------------------------------ | | --[[--------------------------< L A N G U A G E _ P A R A M E T E R >------------------------------------------ |
Sətir 1.410: |
Sətir 1.186: |
| lang = lang:match ('(%a%a)%-') -- keep only 639-1 code portion to lang; TODO: do something with 3166 alpha 2 country code? | | lang = lang:match ('(%a%a)%-') -- keep only 639-1 code portion to lang; TODO: do something with 3166 alpha 2 country code? |
| end | | end |
− |
| |
− | -- костыль для рувики: замена распространённых англоназваний на коды
| |
− | local fromEnglishToCode = {
| |
− | ['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
| |
− |
| |
| if 2 == lang:len() or 3 == lang:len() then -- if two-or three-character code | | if 2 == lang:len() or 3 == lang:len() then -- if two-or three-character code |
− | -- для рувики: замена полного названия на сокращение вроде фр. или англ.
| + | name = mw.language.fetchLanguageName( lang:lower(), this_wiki_code); -- get language name if |language= is a proper code |
− | name = mw.getCurrentFrame():expandTemplate{ | |
− | title='lg',
| |
− | args={lang}
| |
− | }
| |
− | if name == '' then
| |
− | name = nil
| |
− | end
| |
− | if not is_set (name) then
| |
− | name = mw.language.fetchLanguageName( lang:lower(), this_wiki_code); -- get language name if |language= is a proper code
| |
− | end
| |
− |
| |
− | if not is_set (name) then
| |
− | name = cfg.lang_code_remap[lang]; -- not supported by MediaWiki; is it in remap?
| |
− | end
| |
| end | | end |
| | | |
Sətir 1.477: |
Sətir 1.197: |
| | | |
| if is_set (code) then -- only 2- or 3-character codes | | if is_set (code) then -- only 2- or 3-character codes |
− | name = cfg.lang_code_remap[code] or name; -- override wikimedia when they misuse language codes/names
| |
− |
| |
| if this_wiki_code ~= code then -- when the language is not the same as this wiki's language | | 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 | | if 2 == code:len() then -- and is a two-character code |
− | add_prop_cat ('foreign_lang_source' .. code, {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) | | 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 | + | add_prop_cat ('foreign_lang_source_2', {code}) -- categorize it differently TODO: support mutliple three-character code categories per cs1|2 template |
| end | | end |
| end | | end |
Sətir 1.505: |
Sətir 1.223: |
| end | | end |
| return (" " .. wrap_msg ('language', name)); -- otherwise wrap with '(in ...)' | | return (" " .. wrap_msg ('language', name)); -- otherwise wrap with '(in ...)' |
− | --[[ TODO: should only return blank or name rather than full list
| |
− | so we can clean up the bunched parenthetical elements Language, Type, Format
| |
− | ]]
| |
| end | | end |
− |
| |
| | | |
| --[[--------------------------< S E T _ C S 1 _ S T Y L E >---------------------------------------------------- | | --[[--------------------------< S E T _ C S 1 _ S T Y L E >---------------------------------------------------- |
| | | |
| Set style settings for CS1 citation templates. Returns separator and postscript settings | | Set style settings for CS1 citation templates. Returns separator and postscript settings |
− | At en.wiki, for cs1:
| |
− | ps gets: '.'
| |
− | sep gets: '.'
| |
| | | |
| ]] | | ]] |
Sətir 1.522: |
Sətir 1.233: |
| local function set_cs1_style (ps) | | local function set_cs1_style (ps) |
| if not is_set (ps) then -- unless explicitely set to something | | if not is_set (ps) then -- unless explicitely set to something |
− | ps = cfg.presentation['ps_cs1']; -- terminate the rendered citation | + | ps = '.'; -- terminate the rendered citation with a period |
| end | | end |
− | return cfg.presentation['sep_cs1'], ps; -- element separator | + | return '.', ps; -- separator is a full stop |
| end | | end |
− |
| |
| | | |
| --[[--------------------------< S E T _ C S 2 _ S T Y L E >---------------------------------------------------- | | --[[--------------------------< S E T _ C S 2 _ S T Y L E >---------------------------------------------------- |
| | | |
| Set style settings for CS2 citation templates. Returns separator, postscript, ref settings | | Set style settings for CS2 citation templates. Returns separator, postscript, ref settings |
− | At en.wiki, for cs2:
| |
− | ps gets: '' (empty string - no terminal punctuation)
| |
− | sep gets: ','
| |
| | | |
| ]] | | ]] |
Sətir 1.539: |
Sətir 1.246: |
| local function set_cs2_style (ps, ref) | | local function set_cs2_style (ps, ref) |
| if not is_set (ps) then -- if |postscript= has not been set, set cs2 default | | if not is_set (ps) then -- if |postscript= has not been set, set cs2 default |
− | ps = cfg.presentation['ps_cs2']; -- terminate the rendered citation | + | ps = ''; -- make sure it isn't nil |
| end | | end |
| if not is_set (ref) then -- if |ref= is not set | | if not is_set (ref) then -- if |ref= is not set |
| ref = "harv"; -- set default |ref=harv | | ref = "harv"; -- set default |ref=harv |
| end | | end |
− | return cfg.presentation['sep_cs2'], ps, ref; -- element separator | + | return ',', ps, ref; -- separator is a comma |
| end | | end |
− |
| |
| | | |
| --[[--------------------------< G E T _ S E T T I N G S _ F R O M _ C I T E _ C L A S S >---------------------- | | --[[--------------------------< G E T _ S E T T I N G S _ F R O M _ C I T E _ C L A S S >---------------------- |
Sətir 1.565: |
Sətir 1.271: |
| return sep, ps, ref -- return them all | | return sep, ps, ref -- return them all |
| end | | end |
− |
| |
| | | |
| --[[--------------------------< S E T _ S T Y L E >------------------------------------------------------------ | | --[[--------------------------< S E T _ S T Y L E >------------------------------------------------------------ |
Sətir 1.589: |
Sətir 1.294: |
| return sep, ps, ref | | return sep, ps, ref |
| end | | end |
− |
| |
| | | |
| --[=[-------------------------< I S _ P D F >------------------------------------------------------------------ | | --[=[-------------------------< I S _ P D F >------------------------------------------------------------------ |
Sətir 1.596: |
Sətir 1.300: |
| applying the pdf icon to external links. | | applying the pdf icon to external links. |
| | | |
− | returns true if file extension is one of the recognized extensions, else false | + | returns true if file extension is one of the recognized extension, else false |
| | | |
| ]=] | | ]=] |
| | | |
| local function is_pdf (url) | | local function is_pdf (url) |
− | return url:match ('%.pdf$') or url:match ('%.PDF$') or url:match ('%.pdf[%?#]') or url:match ('%.PDF[%?#]'); | + | return url:match ('%.pdf[%?#]?') or url:match ('%.PDF[%?#]?'); |
| end | | end |
− |
| |
| | | |
| --[[--------------------------< S T Y L E _ F O R M A T >------------------------------------------------------ | | --[[--------------------------< S T Y L E _ F O R M A T >------------------------------------------------------ |
Sətir 1.616: |
Sətir 1.319: |
| local function style_format (format, url, fmt_param, url_param) | | local function style_format (format, url, fmt_param, url_param) |
| if is_set (format) then | | if is_set (format) then |
− | format = wrap_style ('format', format); -- add leading space, parentheses, resize | + | format = wrap_style ('format', format); -- add leading space, parenthases, resize |
| if not is_set (url) then | | if not is_set (url) then |
| format = format .. set_error( 'format_missing_url', {fmt_param, url_param} ); -- add an error message | | format = format .. set_error( 'format_missing_url', {fmt_param, url_param} ); -- add an error message |
Sətir 1.627: |
Sətir 1.330: |
| return format; | | return format; |
| end | | end |
− |
| |
| | | |
| --[[--------------------------< G E T _ D I S P L A Y _ A U T H O R S _ E D I T O R S >------------------------ | | --[[--------------------------< G E T _ D I S P L A Y _ A U T H O R S _ E D I T O R S >------------------------ |
Sətir 1.660: |
Sətir 1.362: |
| max = tonumber (max); -- make it a number | | max = tonumber (max); -- make it a number |
| if max >= count then -- if |display-xxxxors= value greater than or equal to number of authors/editors | | if max >= count then -- if |display-xxxxors= value greater than or equal to number of authors/editors |
− | add_maint_cat ('disp_auth_ed', cfg.special_case_translation [list_name]); | + | add_maint_cat ('disp_auth_ed', list_name); |
| end | | end |
| else -- not a valid keyword or number | | else -- not a valid keyword or number |
Sətir 1.670: |
Sətir 1.372: |
| return max, etal; | | return max, etal; |
| end | | end |
− |
| |
| | | |
| --[[--------------------------< E X T R A _ T E X T _ I N _ P A G E _ C H E C K >------------------------------ | | --[[--------------------------< E X T R A _ T E X T _ I N _ P A G E _ C H E C K >------------------------------ |
Sətir 1.684: |
Sətir 1.385: |
| | | |
| local function extra_text_in_page_check (page) | | local function extra_text_in_page_check (page) |
| + | -- local good_pattern = '^P[^%.P%l]'; |
| local good_pattern = '^P[^%.Pp]'; -- ok to begin with uppercase P: P7 (pg 7 of section P) but not p123 (page 123) TODO: add Gg for PG or Pg? | | local good_pattern = '^P[^%.Pp]'; -- ok to begin with uppercase P: P7 (pg 7 of section P) but not p123 (page 123) TODO: add Gg for PG or Pg? |
| + | -- local bad_pattern = '^[Pp][Pp]'; |
| local bad_pattern = '^[Pp]?[Pp]%.?[ %d]'; | | local bad_pattern = '^[Pp]?[Pp]%.?[ %d]'; |
| | | |
Sətir 1.690: |
Sətir 1.393: |
| add_maint_cat ('extra_text'); | | add_maint_cat ('extra_text'); |
| end | | end |
| + | -- if Page:match ('^[Pp]?[Pp]%.?[ %d]') or Page:match ('^[Pp]ages?[ %d]') or |
| + | -- Pages:match ('^[Pp]?[Pp]%.?[ %d]') or Pages:match ('^[Pp]ages?[ %d]') then |
| + | -- add_maint_cat ('extra_text'); |
| + | -- end |
| end | | end |
| | | |
| | | |
− | --[=[-------------------------< G E T _ V _ N A M E _ T A B L E >---------------------------------------------- | + | --[[--------------------------< P A R S E _ V A U T H O R S _ V E D I T O R S >-------------------------------- |
| + | |
| + | This function extracts author / editor names from |vauthors= or |veditors= and finds matching |xxxxor-maskn= and |
| + | |xxxxor-linkn= in args. It then returns a table of assembled names just as extract_names() does. |
| + | |
| + | Author / editor names in |vauthors= or |veditors= must be in Vancouver system style. Corporate or institutional names |
| + | may sometimes be required and because such names will often fail the is_good_vanc_name() and other format compliance |
| + | tests, are wrapped in doubled paranethese ((corporate name)) to suppress the format tests. |
| | | |
− | split apart a |vauthors= or |veditors= parameter. This function allows for corporate names, wrapped in doubled
| + | This function sets the vancouver error when a reqired comma is missing and when there is a space between an author's initials. |
− | parentheses to also have commas; in the old version of the code, the doubled parnetheses were included in the
| |
− | rendered citation and in the metadata. Individual author names may be wikilinked
| |
| | | |
− | |vauthors=Jones AB, [[E. B. White|White EB]], ((Black, Brown, and Co.))
| + | TODO: check for names like Coon V JS (Coon JS 5th at PMID 25205766, John S. Coon V at doi:10.1093/humupd/dmu048)? |
| | | |
− | ]=] | + | ]] |
| | | |
− | local function get_v_name_table (vparam, output_table, output_link_table)
| + | local function parse_vauthors_veditors (args, vparam, list_name) |
− | local name_table = mw.text.split(vparam, "%s*,%s*"); -- names are separated by commas
| |
− | local wl_type, label, link; -- wl_type not used here; just a place holder
| |
− |
| |
− | local i = 1;
| |
− |
| |
− | while name_table[i] do
| |
− | if name_table[i]:match ('^%(%(.*[^%)][^%)]$') then -- first segment of corporate with one or more commas; this segment has the opening doubled parens
| |
− | local name = name_table[i];
| |
− | i=i+1; -- bump indexer to next segment
| |
− | while name_table[i] do
| |
− | name = name .. ', ' .. name_table[i]; -- concatenate with previous segments
| |
− | if name_table[i]:match ('^.*%)%)$') then -- if this table member has the closing doubled parens
| |
− | break; -- and done reassembling so
| |
− | end
| |
− | i=i+1; -- bump indexer
| |
− | end
| |
− | table.insert (output_table, name); -- and add corporate name to the output table
| |
− | table.insert (output_link_table, ''); -- no wikilink
| |
− | else
| |
− | wl_type, label, link = is_wikilink (name_table[i]); -- wl_type is: 0, no wl (text in label variable); 1, [[D]]; 2, [[L|D]]
| |
− | table.insert (output_table, label); -- add this name
| |
− | if 1 == wl_type then
| |
− | table.insert (output_link_table, label); -- simple wikilink [[D]]
| |
− | else
| |
− | table.insert (output_link_table, link); -- no wikilink or [[L|D]]; add this link if there is one, else empty string
| |
− | end
| |
− | end
| |
− | i = i+1;
| |
− | end
| |
− | return output_table;
| |
− | end
| |
− | | |
− | | |
− | --[[--------------------------< P A R S E _ V A U T H O R S _ V E D I T O R S >--------------------------------
| |
− | | |
− | This function extracts author / editor names from |vauthors= or |veditors= and finds matching |xxxxor-maskn= and
| |
− | |xxxxor-linkn= in args. It then returns a table of assembled names just as extract_names() does.
| |
− | | |
− | Author / editor names in |vauthors= or |veditors= must be in Vancouver system style. Corporate or institutional names
| |
− | may sometimes be required and because such names will often fail the is_good_vanc_name() and other format compliance
| |
− | tests, are wrapped in doubled paranethese ((corporate name)) to suppress the format tests.
| |
− | | |
− | Supports generational suffixes Jr, 2nd, 3rd, 4th–6th.
| |
− | | |
− | This function sets the vancouver error when a reqired comma is missing and when there is a space between an author's initials.
| |
− | | |
− | ]]
| |
− | | |
− | local function parse_vauthors_veditors (args, vparam, list_name) | |
| local names = {}; -- table of names assembled from |vauthors=, |author-maskn=, |author-linkn= | | local names = {}; -- table of names assembled from |vauthors=, |author-maskn=, |author-linkn= |
| local v_name_table = {}; | | local v_name_table = {}; |
− | local v_link_table = {}; -- when name is wikilinked, targets go in this table
| |
| local etal = false; -- return value set to true when we find some form of et al. vauthors parameter | | local etal = false; -- return value set to true when we find some form of et al. vauthors parameter |
− | local last, first, link, mask, suffix; | + | local last, first, link, mask; |
| local corporate = false; | | local corporate = false; |
| | | |
| vparam, etal = name_has_etal (vparam, etal, true); -- find and remove variations on et al. do not categorize (do it here because et al. might have a period) | | vparam, etal = name_has_etal (vparam, etal, true); -- find and remove variations on et al. do not categorize (do it here because et al. might have a period) |
− | v_name_table = get_v_name_table (vparam, v_name_table, v_link_table); -- names are separated by commas | + | if vparam:find ('%[%[') or vparam:find ('%]%]') then -- no wikilinking vauthors names |
| + | add_vanc_error (); |
| + | end |
| + | v_name_table = mw.text.split(vparam, "%s*,%s*") -- names are separated by commas |
| | | |
| for i, v_name in ipairs(v_name_table) do | | for i, v_name in ipairs(v_name_table) do |
− | if v_name:match ('^%(%(.+%)%)$') then -- corporate authors are wrapped in doubled parentheses to supress vanc formatting and error detection | + | if v_name:match ('^%(%(.+%)%)$') then -- corporate authors are wrapped in doubled parenthese to supress vanc formatting and error detection |
| first = ''; -- set to empty string for concatenation and because it may have been set for previous author/editor | | first = ''; -- set to empty string for concatenation and because it may have been set for previous author/editor |
− | last = v_name:match ('^%(%((.+)%)%)$') -- remove doubled parntheses | + | last = v_name:match ('^%(%((.+)%)%)$') |
− | corporate = true; -- flag used in list_people() | + | corporate = true; |
| elseif string.find(v_name, "%s") then | | elseif string.find(v_name, "%s") then |
− | if v_name:find('[;%.]') then -- look for commonly occurring punctuation characters;
| |
− | add_vanc_error ('punctuation');
| |
− | end
| |
| local lastfirstTable = {} | | local lastfirstTable = {} |
| lastfirstTable = mw.text.split(v_name, "%s") | | lastfirstTable = mw.text.split(v_name, "%s") |
| first = table.remove(lastfirstTable); -- removes and returns value of last element in table which should be author intials | | first = table.remove(lastfirstTable); -- removes and returns value of last element in table which should be author intials |
− | if is_suffix (first) then -- if a valid suffix
| + | last = table.concat(lastfirstTable, " ") -- returns a string that is the concatenation of all other names that are not initials |
− | suffix = first -- save it as a suffix and
| + | if mw.ustring.match (last, '%a+%s+%u+%s+%a+') or mw.ustring.match (v_name, ' %u %u$') then |
− | first = table.remove(lastfirstTable); -- get what should be the initials from the table
| + | add_vanc_error (); -- matches last II last; the case when a comma is missing or a space between two intiials |
− | end -- no suffix error message here because letter combination may be result of Romanization; check for digits?
| |
− | last = table.concat(lastfirstTable, " ") -- returns a string that is the concatenation of all other names that are not initials | |
− | if mw.ustring.match (last, '%a+%s+%u+%s+%a+') then | |
− | add_vanc_error ('missing comma'); -- matches last II last; the case when a comma is missing
| |
− | end
| |
− | if mw.ustring.match (v_name, ' %u %u$') then -- this test is in the wrong place TODO: move or replace with a more appropriate test
| |
− | add_vanc_error ('name'); -- matches a space between two intiials | |
| end | | end |
| else | | else |
Sətir 1.791: |
Sətir 1.446: |
| end | | end |
| | | |
− | if is_set (first) then | + | if is_set (first) and not mw.ustring.match (first, "^%u?%u$") then -- first shall contain one or two upper-case letters, nothing else |
− | if not mw.ustring.match (first, "^%u?%u$") then -- first shall contain one or two upper-case letters, nothing else
| + | add_vanc_error (); |
− | add_vanc_error ('initials'); -- too many initials; mixed case initials (which may be ok Romanization); hyphenated initials
| |
− | end
| |
− | is_good_vanc_name (last, first); -- check first and last before restoring the suffix which may have a non-Latin digit
| |
− | if is_set (suffix) then
| |
− | first = first .. ' ' .. suffix; -- if there was a suffix concatenate with the initials
| |
− | suffix = ''; -- unset so we don't add this suffix to all subsequent names
| |
− | end
| |
− | else
| |
− | if not corporate then
| |
− | is_good_vanc_name (last, '');
| |
− | end
| |
| end | | end |
− | | + | -- this from extract_names () |
− | link = select_one( args, cfg.aliases[list_name .. '-Link'], 'redundant_parameters', i ) or v_link_table[i]; | + | link = select_one( args, cfg.aliases[list_name .. '-Link'], 'redundant_parameters', i ); |
| mask = select_one( args, cfg.aliases[list_name .. '-Mask'], 'redundant_parameters', i ); | | mask = select_one( args, cfg.aliases[list_name .. '-Mask'], 'redundant_parameters', i ); |
| names[i] = {last = last, first = first, link = link, mask = mask, corporate=corporate}; -- add this assembled name to our names list | | names[i] = {last = last, first = first, link = link, mask = mask, corporate=corporate}; -- add this assembled name to our names list |
Sətir 1.812: |
Sətir 1.456: |
| return names, etal; -- all done, return our list of names | | return names, etal; -- all done, return our list of names |
| end | | end |
− |
| |
| | | |
| --[[--------------------------< S E L E C T _ A U T H O R _ E D I T O R _ S O U R C E >------------------------ | | --[[--------------------------< S E L E C T _ A U T H O R _ E D I T O R _ S O U R C E >------------------------ |
Sətir 1.834: |
Sətir 1.477: |
| local function select_author_editor_source (vxxxxors, xxxxors, args, list_name) | | local function select_author_editor_source (vxxxxors, xxxxors, args, list_name) |
| local lastfirst = false; | | local lastfirst = false; |
− | if select_one( args, cfg.aliases[list_name .. '-Last'], 'none', 1 ) or -- do this twice incase we have a |first1= without a |last1=; this ... | + | if select_one( args, cfg.aliases[list_name .. '-Last'], 'none', 1 ) or -- do this twice incase we have a first 1 without a last1 |
− | select_one( args, cfg.aliases[list_name .. '-First'], 'none', 1 ) or -- ... also catches the case where |first= is used with |vauthors=
| + | select_one( args, cfg.aliases[list_name .. '-Last'], 'none', 2 ) then |
− | select_one( args, cfg.aliases[list_name .. '-Last'], 'none', 2 ) or | |
− | select_one( args, cfg.aliases[list_name .. '-First'], 'none', 2 ) then
| |
| lastfirst=true; | | lastfirst=true; |
| end | | end |
Sətir 1.865: |
Sətir 1.506: |
| This function is used to validate a parameter's assigned value for those parameters that have only a limited number | | 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, no, etc). When the parameter value has not been assigned a value (missing or empty | | of allowable values (yes, y, true, no, etc). When the parameter value has not been assigned a value (missing or empty |
− | in the source template) the function returns true. If the parameter value is one of the list of allowed values returns | + | in the source template) the function refurns true. If the parameter value is one of the list of allowed values returns |
| true; else, emits an error message and returns false. | | true; else, emits an error message and returns false. |
| | | |
Sətir 1.892: |
Sətir 1.533: |
| | | |
| local function terminate_name_list (name_list, sepc) | | local function terminate_name_list (name_list, sepc) |
− | if (string.sub (name_list,-3,-1) == sepc .. '. ') then -- if already properly terminated | + | if (string.sub (name_list,-1,-1) == sepc) or (string.sub (name_list,-3,-1) == sepc .. ']]') then -- if last name in list ends with sepc char |
− | return name_list; -- just return the name list
| |
− | elseif (string.sub (name_list,-1,-1) == sepc) or (string.sub (name_list,-3,-1) == sepc .. ']]') then -- if last name in list ends with sepc char
| |
| return name_list .. " "; -- don't add another | | return name_list .. " "; -- don't add another |
| else | | else |
Sətir 1.923: |
Sətir 1.562: |
| end | | end |
| end | | end |
− | | + | |
| local vol = ''; | | local vol = ''; |
| | | |
Sətir 1.930: |
Sətir 1.569: |
| vol = substitute (cfg.messages['j-vol'], {sepc, volume}); | | vol = substitute (cfg.messages['j-vol'], {sepc, volume}); |
| else | | else |
− | vol = substitute (cfg.presentation['vol-bold'], {sepc, hyphen_to_dash(volume)}); | + | vol = wrap_style ('vol-bold', hyphen_to_dash(volume)); |
| end | | end |
| end | | end |
Sətir 1.939: |
Sətir 1.578: |
| end | | end |
| | | |
| + | |
| + | |
| + | |
| + | |
| + | |
| + | --[[-------------------------< N O R M A L I Z E _ P A G E _ L I S T >----------------------------------------- |
| + | |
| + | not currently used |
| + | |
| + | normalizes a comma, ampersand, and/or space separated list to be '<value>, <value>, ..., <value>' |
| + | returns list unchanged if there are no commas else strips whitespace and then reformats the list |
| + | |
| + | ]] |
| + | --[[ |
| + | local function normalize_page_list (list) |
| + | if not list:find ('[,& ]') then return list end -- if list is not delimited with commas, ampersands, or spaces; done |
| + | |
| + | list = mw.text.split (list, '[,&%s]+'); -- make a table of values |
| + | list = table.concat (list, ', '); -- and now make a normalized list |
| + | return list; |
| + | end |
| + | ]] |
| | | |
| --[[-------------------------< F O R M A T _ P A G E S _ S H E E T S >----------------------------------------- | | --[[-------------------------< F O R M A T _ P A G E S _ S H E E T S >----------------------------------------- |
Sətir 1.967: |
Sətir 1.628: |
| end | | end |
| | | |
− | local is_journal = 'journal' == cite_class or (in_array (cite_class, {'citation', 'map', 'interview'}) and 'journal' == origin); | + | local is_journal = 'journal' == cite_class or (in_array (cite_class, {'citation', 'map'}) and 'journal' == origin); |
− |
| + | |
| if is_set (page) then | | if is_set (page) then |
| if is_journal then | | if is_journal then |
Sətir 1.996: |
Sətir 1.657: |
| | | |
| Check archive.org urls to make sure they at least look like they are pointing at valid archives and not to the | | 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 or to calendar pages. When the archive url is 'https://web.archive.org/save/' (or http://...) | + | save snapshot url. When the archive url is 'https://web.archive.org/save/' (or http://...) archive.org saves a snapshot |
− | archive.org saves a snapshot of the target page in the url. That is something that Wikipedia should not allow | + | of the target page in the url. That is something that Wikipedia should not allow unwitting readers to do. |
− | unwitting readers to do. | |
| | | |
| When the archive.org url does not have a complete timestamp, archive.org chooses a snapshot according to its own | | When the archive.org url does not have a complete timestamp, archive.org chooses a snapshot according to its own |
− | algorithm or provides a calendar 'search' result. [[WP:ELNO]] discourages links to search results. | + | 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 | | 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-date= and an error message when: |
| |archive-url= holds an archive.org save command url | | |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 | + | |archive-url= is an archive.org url that does not have a complete timestamp (YYYYMMDDhhmmss 14 digits) in the correct place |
− | correct place
| |
| otherwise returns |archive-url= and |archive-date= | | otherwise returns |archive-url= and |archive-date= |
| | | |
Sətir 2.017: |
Sətir 1.676: |
| ('id_', 'js_', 'cs_', 'im_') but since archive.org ignores others following the same form (two letters and an underscore) | | ('id_', 'js_', 'cs_', 'im_') but since archive.org ignores others following the same form (two letters and an underscore) |
| we don't check for these specific flags but we do check the form. | | we don't check for these specific flags but we do check the form. |
− |
| |
− | This function supports a preview mode. When the article is rendered in preview mode, this funct may return a modified
| |
− | archive url:
| |
− | for save command errors, return undated wildcard (/*/)
| |
− | for timestamp errors when the timestamp has a wildcard, return the url unmodified
| |
− | for timestamp errors when the timestamp does not have a wildcard, return with timestamp limited to six digits plus wildcard (/yyyymm*/)
| |
| | | |
| ]=] | | ]=] |
Sətir 2.030: |
Sətir 1.683: |
| local path, timestamp, flag; -- portions of the archive.or url | | local path, timestamp, flag; -- portions of the archive.or url |
| | | |
− | if (not url:match('//web%.archive%.org/')) and (not url:match('//liveweb%.archive%.org/')) then -- also deprecated liveweb Wayback machine url | + | if not url:match('//web%.archive%.org/') then |
− | return url, date; -- not an archive.org archive, return ArchiveURL and ArchiveDate | + | return url, date; -- not an archive.org archive, return archiveURL and ArchiveDate |
| end | | end |
| | | |
| if url:match('//web%.archive%.org/save/') then -- if a save command url, we don't want to allow saving of the target page | | if url:match('//web%.archive%.org/save/') then -- if a save command url, we don't want to allow saving of the target page |
− | err_msg = 'save command'; | + | table.insert( z.message_tail, { set_error( 'archive_url', {'save command'}, true ) } ); -- add error message |
− | url = url:gsub ('(//web%.archive%.org)/save/', '%1/*/', 1); -- for preview mode: modify ArchiveURL | + | return '', ''; -- return empty strings for archiveURL and ArchiveDate |
− | elseif url:match('//liveweb%.archive%.org/') then | + | end |
− | err_msg = 'liveweb'; | + | |
| + | if url:match('//web%.archive%.org/web/%*/') or url:match('//web%.archive%.org/%*/') then -- wildcard with or without 'web/' path element |
| + | table.insert( z.message_tail, { set_error( 'archive_url', {'wildcard'}, true ) } ); -- add error message and |
| + | return '', ''; -- return empty strings for archiveURL and ArchiveDate |
| + | end |
| + | |
| + | path, timestamp, flag = url:match('//web%.archive%.org/([^%d]*)(%d+)([^/]*)/'); -- split out some of the url parts for evaluation |
| + | |
| + | if not is_set(timestamp) or 14 ~= timestamp:len() then -- path and flag optional, must have 14-digit timestamp here |
| + | err_msg = 'timestamp'; |
| + | elseif is_set(path) and 'web/' ~= path then -- older archive urls do not have the extra 'web/' path element |
| + | err_msg = 'path'; |
| + | elseif is_set (flag) and not is_set (path) then -- flag not allowed with the old form url (without the 'web/' path element) |
| + | err_msg = 'flag'; |
| + | elseif is_set (flag) and not flag:match ('%a%a_') then -- flag if present must be two alpha characters and underscore (requires 'web/' path element) |
| + | err_msg = 'flag'; |
| else | | else |
− | path, timestamp, flag = url:match('//web%.archive%.org/([^%d]*)(%d+)([^/]*)/'); -- split out some of the url parts for evaluation | + | return url, date; -- return archiveURL and ArchiveDate |
− |
| |
− | if not is_set(timestamp) or 14 ~= timestamp:len() then -- path and flag optional, must have 14-digit timestamp here
| |
− | err_msg = 'timestamp';
| |
− | if '*' ~= flag then
| |
− | url=url:gsub ('(//web%.archive%.org/[^%d]*%d?%d?%d?%d?%d?%d?)[^/]*', '%1*', 1) -- for preview, modify ts to be yearmo* max (0-6 digits plus splat)
| |
− | end
| |
− | elseif is_set(path) and 'web/' ~= path then -- older archive urls do not have the extra 'web/' path element
| |
− | err_msg = 'path';
| |
− | elseif is_set (flag) and not is_set (path) then -- flag not allowed with the old form url (without the 'web/' path element)
| |
− | err_msg = 'flag';
| |
− | elseif is_set (flag) and not flag:match ('%a%a_') then -- flag if present must be two alpha characters and underscore (requires 'web/' path element)
| |
− | err_msg = 'flag';
| |
− | else
| |
− | return url, date; -- return archiveURL and ArchiveDate
| |
− | end
| |
| end | | end |
− | -- if here, something not right so | + | -- if here something not right so |
| table.insert( z.message_tail, { set_error( 'archive_url', {err_msg}, true ) } ); -- add error message and | | table.insert( z.message_tail, { set_error( 'archive_url', {err_msg}, true ) } ); -- add error message and |
− | if is_set (Frame:preprocess('{{REVISIONID}}')) then | + | return '', ''; -- return empty strings for archiveURL and ArchiveDate |
− | return '', ''; -- return empty strings for archiveURL and ArchiveDate
| |
− | else
| |
− | return url, date; -- preview mode so return archiveURL and ArchiveDate
| |
− | end
| |
| end | | end |
| | | |
| | | |
− | --[[--------------------------< C I T A T I O N 0 >------------------------------------------------------------ | + | --[[--------------------------< M I S S I N G _ P I P E _ C H E C K >------------------------------------------ |
| | | |
− | This is the main function doing the majority of the citation formatting. | + | 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 >------------------------------------------------------------ |
| + | |
| + | This is the main function doing the majority of the citation formatting. |
| | | |
| ]] | | ]] |
Sətir 2.083: |
Sətir 1.757: |
| -- Pick out the relevant fields from the arguments. Different citation templates | | -- Pick out the relevant fields from the arguments. Different citation templates |
| -- define different field names for the same underlying things. | | -- define different field names for the same underlying things. |
− |
| |
− | -- 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 author_etal; |
| local a = {}; -- authors list from |lastn= / |firstn= pairs or |vauthors= | | local a = {}; -- authors list from |lastn= / |firstn= pairs or |vauthors= |
Sətir 2.105: |
Sətir 1.772: |
| elseif 3 == selected then | | elseif 3 == selected then |
| Authors = A['Authors']; -- use content of |authors= | | Authors = A['Authors']; -- use content of |authors= |
− | if 'authors' == A:ORIGIN('Authors') then -- but add a maint cat if the parameter is |authors=
| |
− | add_maint_cat ('authors'); -- because use of this parameter is discouraged; what to do about the aliases is a TODO:
| |
− | end
| |
| end | | end |
| if is_set (Collaboration) then | | if is_set (Collaboration) then |
Sətir 2.114: |
Sətir 1.778: |
| end | | end |
| | | |
− | local Coauthors = A['Coauthors']; -- для рувики (а вообще депрекированный) | + | local Coauthors = A['Coauthors']; |
| local Others = A['Others']; | | local Others = A['Others']; |
| | | |
Sətir 2.130: |
Sətir 1.794: |
| elseif 3 == selected then | | elseif 3 == selected then |
| Editors = A['Editors']; -- use content of |editors= | | Editors = A['Editors']; -- use content of |editors= |
− | add_maint_cat ('editors'); -- but add a maint cat because use of this parameter is discouraged
| |
| end | | end |
| end | | end |
Sətir 2.137: |
Sətir 1.800: |
| local Translators; -- assembled translators name list | | local Translators; -- assembled translators name list |
| t = extract_names (args, 'TranslatorList'); -- fetch translator list from |translatorn= / |translator-lastn=, -firstn=, -linkn=, -maskn= | | t = extract_names (args, 'TranslatorList'); -- fetch translator list from |translatorn= / |translator-lastn=, -firstn=, -linkn=, -maskn= |
− | | + | |
− | local interviewers_list = {}; | |
− | local Interviewers = A['Interviewers']
| |
− | if is_set (Interviewers) then -- add a maint cat if the |interviewers= is used
| |
− | add_maint_cat ('interviewers'); -- because use of this parameter is discouraged
| |
− | else
| |
− | interviewers_list = extract_names (args, 'InterviewerList'); -- else, process preferred interviewers parameters
| |
− | end
| |
− | | |
| local c = {}; -- contributors list from |contributor-lastn= / contributor-firstn= pairs | | local c = {}; -- contributors list from |contributor-lastn= / contributor-firstn= pairs |
| local Contributors; -- assembled contributors name list | | local Contributors; -- assembled contributors name list |
Sətir 2.202: |
Sətir 1.857: |
| ArchiveURL, ArchiveDate = archive_url_check (A['ArchiveURL'], A['ArchiveDate']) | | 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'] | | local DeadURL = A['DeadURL'] |
| if not is_valid_parameter_value (DeadURL, 'dead-url', cfg.keywords ['deadurl']) then -- set in config.defaults to 'yes' | | if not is_valid_parameter_value (DeadURL, 'dead-url', cfg.keywords ['deadurl']) then -- set in config.defaults to 'yes' |
Sətir 2.225: |
Sətir 1.887: |
| local At; | | local At; |
| | | |
− | if in_array (config.CitationClass, cfg.templates_using_volume) then | + | if in_array (config.CitationClass, cfg.templates_using_volume) and not ('conference' == config.CitationClass and not is_set (Periodical)) then |
| Volume = A['Volume']; | | Volume = A['Volume']; |
| end | | end |
− | -- conference & map books do not support issue
| |
| if in_array (config.CitationClass, cfg.templates_using_issue) and not (in_array (config.CitationClass, {'conference', 'map'}) and not is_set (Periodical))then | | if in_array (config.CitationClass, cfg.templates_using_issue) and not (in_array (config.CitationClass, {'conference', 'map'}) and not is_set (Periodical))then |
− | Issue = hyphen_to_dash (A['Issue']); | + | Issue = A['Issue']; |
| end | | end |
| local Position = ''; | | local Position = ''; |
| if not in_array (config.CitationClass, cfg.templates_not_using_page) then | | if not in_array (config.CitationClass, cfg.templates_not_using_page) then |
| Page = A['Page']; | | Page = A['Page']; |
− | Pages = hyphen_to_dash (A['Pages']); | + | Pages = hyphen_to_dash( A['Pages'] ); |
| At = A['At']; | | At = A['At']; |
| end | | end |
Sətir 2.248: |
Sətir 1.909: |
| RegistrationRequired=nil; | | RegistrationRequired=nil; |
| end | | end |
− |
| |
| local SubscriptionRequired = A['SubscriptionRequired']; | | local SubscriptionRequired = A['SubscriptionRequired']; |
| if not is_valid_parameter_value (SubscriptionRequired, 'subscription', cfg.keywords ['yes_true_y']) then | | if not is_valid_parameter_value (SubscriptionRequired, 'subscription', cfg.keywords ['yes_true_y']) then |
Sətir 2.254: |
Sətir 1.914: |
| end | | end |
| | | |
− | local UrlAccess = A['UrlAccess'];
| + | local Via = A['Via']; |
− | 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;
| |
− | table.insert( z.message_tail, { set_error( 'param_access_requires_param', {'url'}, true ) } );
| |
− | end
| |
− | | |
− | if is_set (UrlAccess) and is_set (SubscriptionRequired) then -- while not aliases, these are much the same so if both are set
| |
− | table.insert( z.message_tail, { set_error( 'redundant_parameters', {wrap_style ('parameter', 'url-access') .. ' and ' .. wrap_style ('parameter', 'subscription')}, true ) } ); -- add error message
| |
− | SubscriptionRequired = nil; -- unset; prefer |access= over |subscription=
| |
− | end
| |
− | if is_set (UrlAccess) and is_set (RegistrationRequired) then -- these are not the same but contradictory so if both are set
| |
− | table.insert( z.message_tail, { set_error( 'redundant_parameters', {wrap_style ('parameter', 'url-access') .. ' and ' .. wrap_style ('parameter', 'registration')}, true ) } ); -- add error message
| |
− | RegistrationRequired = nil; -- unset; prefer |access= over |registration=
| |
− | end
| |
− | | |
− | local ChapterUrlAccess = A['ChapterUrlAccess'];
| |
− | if not is_valid_parameter_value (ChapterUrlAccess, 'chapter-url-access', cfg.keywords ['url-access']) then -- same as url-access
| |
− | ChapterUrlAccess = nil;
| |
− | end
| |
− | if not is_set(ChapterURL) and is_set(ChapterUrlAccess) then
| |
− | ChapterUrlAccess = nil;
| |
− | table.insert( z.message_tail, { set_error( 'param_access_requires_param', {'chapter-url'}, true ) } );
| |
− | end
| |
− | | |
− | local Via = A['Via']; | |
| local AccessDate = A['AccessDate']; | | local AccessDate = A['AccessDate']; |
| local Agency = A['Agency']; | | local Agency = A['Agency']; |
Sətir 2.299: |
Sətir 1.932: |
| | | |
| local ID_list = extract_ids( args ); | | local ID_list = extract_ids( args ); |
− | local ID_access_levels = extract_id_access_levels( args, ID_list );
| |
| | | |
| local Quote = A['Quote']; | | local Quote = A['Quote']; |
Sətir 2.313: |
Sətir 1.945: |
| local LastAuthorAmp = A['LastAuthorAmp']; | | local LastAuthorAmp = A['LastAuthorAmp']; |
| if not is_valid_parameter_value (LastAuthorAmp, 'last-author-amp', cfg.keywords ['yes_true_y']) then | | if not is_valid_parameter_value (LastAuthorAmp, 'last-author-amp', cfg.keywords ['yes_true_y']) then |
− | LastAuthorAmp = nil; -- set to empty string | + | LastAuthorAmp = nil; -- set to empty string |
| end | | end |
− |
| |
| local no_tracking_cats = A['NoTracking']; | | local no_tracking_cats = A['NoTracking']; |
| if not is_valid_parameter_value (no_tracking_cats, 'no-tracking', cfg.keywords ['yes_true_y']) then | | if not is_valid_parameter_value (no_tracking_cats, 'no-tracking', cfg.keywords ['yes_true_y']) then |
Sətir 2.321: |
Sətir 1.952: |
| end | | end |
| | | |
− | --local variables that are not cs1 parameters | + | --these are used by cite interview |
| + | local Callsign = A['Callsign']; |
| + | local City = A['City']; |
| + | local Program = A['Program']; |
| + | |
| + | --local variables that are not cs1 parameters |
| local use_lowercase; -- controls capitalization of certain static text | | local use_lowercase; -- controls capitalization of certain static text |
| local this_page = mw.title.getCurrentTitle(); -- also used for COinS and for language | | local this_page = mw.title.getCurrentTitle(); -- also used for COinS and for language |
Sətir 2.332: |
Sətir 1.968: |
| end | | end |
| | | |
| + | -- set default parameter values defined by |mode= parameter. If |mode= is empty or omitted, use CitationClass to set these values |
| + | local Mode = A['Mode']; |
| + | if not is_valid_parameter_value (Mode, 'mode', cfg.keywords['mode']) then |
| + | Mode = ''; |
| + | end |
| local sepc; -- separator between citation elements for CS1 a period, for CS2, a comma | | local sepc; -- separator between citation elements for CS1 a period, for CS2, a comma |
| local PostScript; | | local PostScript; |
Sətir 2.338: |
Sətir 1.979: |
| use_lowercase = ( sepc == ',' ); -- used to control capitalization for certain static text | | use_lowercase = ( sepc == ',' ); -- used to control capitalization for certain static text |
| | | |
− | --check this page to see if it is in one of the namespaces that cs1 is not supposed to add to the error categories
| + | --check this page to see if it is in one of the namespaces that cs1 is not supposed to add to the error categories |
| if not is_set (no_tracking_cats) then -- ignore if we are already not going to categorize this page | | if not is_set (no_tracking_cats) then -- ignore if we are already not going to categorize this page |
| if in_array (this_page.nsText, cfg.uncategorized_namespaces) then | | if in_array (this_page.nsText, cfg.uncategorized_namespaces) then |
Sətir 2.351: |
Sətir 1.992: |
| end | | end |
| | | |
− | -- 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) |
| select_one( args, {'page', 'p', 'pp', 'pages', 'at', 'sheet', 'sheets'}, 'redundant_parameters' ); -- this is a dummy call simply to get the error message and category | | select_one( args, {'page', 'p', 'pp', 'pages', 'at', 'sheet', 'sheets'}, 'redundant_parameters' ); -- this is a dummy call simply to get the error message and category |
| | | |
Sətir 2.374: |
Sətir 2.015: |
| end | | end |
| | | |
− | -- both |publication-place= and |place= (|location=) allowed if different
| + | -- both |publication-place= and |place= (|location=) allowed if different |
| if not is_set(PublicationPlace) and is_set(Place) then | | if not is_set(PublicationPlace) and is_set(Place) then |
| PublicationPlace = Place; -- promote |place= (|location=) to |publication-place | | PublicationPlace = Place; -- promote |place= (|location=) to |publication-place |
Sətir 2.381: |
Sətir 2.022: |
| if PublicationPlace == Place then Place = ''; end -- don't need both if they are the same | | if PublicationPlace == Place then Place = ''; end -- don't need both if they are the same |
| | | |
− | --[[
| + | --[[ |
− | Parameter remapping for cite encyclopedia:
| + | Parameter remapping for cite encyclopedia: |
− | When the citation has these parameters:
| + | When the citation has these parameters: |
− | |encyclopedia and |title then map |title to |article and |encyclopedia to |title
| + | |encyclopedia and |title then map |title to |article and |encyclopedia to |title |
− | |encyclopedia and |article then map |encyclopedia to |title
| + | |encyclopedia and |article then map |encyclopedia to |title |
− | |encyclopedia then map |encyclopedia to |title
| + | |encyclopedia then map |encyclopedia to |title |
− | | + | |
− | |trans-title maps to |trans-chapter when |title is re-mapped
| + | |trans_title maps to |trans_chapter when |title is re-mapped |
− | |url maps to |chapterurl when |title is remapped
| + | |url maps to |chapterurl when |title is remapped |
− |
| + | |
− | All other combinations of |encyclopedia, |title, and |article are not modified
| + | All other combinations of |encyclopedia, |title, and |article are not modified |
− |
| + | |
− | ]]
| + | ]] |
| | | |
| local Encyclopedia = A['Encyclopedia']; | | local Encyclopedia = A['Encyclopedia']; |
Sətir 2.405: |
Sətir 2.046: |
| TransChapter = TransTitle; | | TransChapter = TransTitle; |
| ChapterURL = URL; | | ChapterURL = URL; |
− | ChapterUrlAccess = UrlAccess;
| |
− |
| |
| if not is_set (ChapterURL) and is_set (TitleLink) then | | if not is_set (ChapterURL) and is_set (TitleLink) then |
− | Chapter = make_wikilink (TitleLink, Chapter); | + | Chapter= '[[' .. TitleLink .. '|' .. Chapter .. ']]'; |
| end | | end |
| Title = Periodical; | | Title = Periodical; |
Sətir 2.426: |
Sətir 2.065: |
| end | | end |
| | | |
− | -- Special case for cite techreport.
| + | -- Special case for cite techreport. |
| if (config.CitationClass == "techreport") then -- special case for cite techreport | | if (config.CitationClass == "techreport") then -- special case for cite techreport |
− | if is_set(A['Number']) then -- cite techreport uses 'number', which other citations alias to 'issue' | + | if is_set(A['Number']) then -- cite techreport uses 'number', which other citations alias to 'issue' |
| if not is_set(ID) then -- can we use ID for the "number"? | | if not is_set(ID) then -- can we use ID for the "number"? |
− | ID = A['Number']; -- yes, use it | + | ID = A['Number']; -- yes, use it |
| else -- ID has a value so emit error message | | else -- ID has a value so emit error message |
| table.insert( z.message_tail, { set_error('redundant_parameters', {wrap_style ('parameter', 'id') .. ' and ' .. wrap_style ('parameter', 'number')}, true )}); | | table.insert( z.message_tail, { set_error('redundant_parameters', {wrap_style ('parameter', 'id') .. ' and ' .. wrap_style ('parameter', 'number')}, true )}); |
Sətir 2.437: |
Sətir 2.076: |
| end | | end |
| | | |
− | -- special case for cite mailing list | + | -- special case for cite interview |
− | if (config.CitationClass == "mailinglist") then | + | if (config.CitationClass == "interview") then |
− | Periodical = A ['MailingList']; | + | if is_set(Program) then |
− | elseif 'mailinglist' == A:ORIGIN('Periodical') then | + | ID = ' ' .. Program; |
− | Periodical = ''; -- unset because mailing list is only used for cite mailing list | + | end |
− | end | + | if is_set(Callsign) then |
| + | if is_set(ID) then |
| + | ID = ID .. sepc .. ' ' .. Callsign; |
| + | else |
| + | ID = ' ' .. Callsign; |
| + | end |
| + | end |
| + | if is_set(City) then |
| + | if is_set(ID) then |
| + | ID = ID .. sepc .. ' ' .. City; |
| + | else |
| + | ID = ' ' .. City; |
| + | end |
| + | end |
| + | |
| + | if is_set(Others) then |
| + | if is_set(TitleType) then |
| + | Others = ' ' .. TitleType .. ' with ' .. Others; |
| + | TitleType = ''; |
| + | else |
| + | Others = ' ' .. 'Interview with ' .. Others; |
| + | end |
| + | else |
| + | Others = '(Interview)'; |
| + | end |
| + | end |
| + | |
| + | -- special case for cite mailing list |
| + | if (config.CitationClass == "mailinglist") then |
| + | Periodical = A ['MailingList']; |
| + | elseif 'mailinglist' == A:ORIGIN('Periodical') then |
| + | Periodical = ''; -- unset because mailing list is only used for cite mailing list |
| + | end |
| | | |
− | -- Account for the oddity that is {{cite conference}}, before generation of COinS data.
| + | -- Account for the oddity that is {{cite conference}}, before generation of COinS data. |
| if 'conference' == config.CitationClass then | | if 'conference' == config.CitationClass then |
| if is_set(BookTitle) then | | if is_set(BookTitle) then |
Sətir 2.450: |
Sətir 2.121: |
| -- ChapterLink = TitleLink; -- |chapterlink= is deprecated | | -- ChapterLink = TitleLink; -- |chapterlink= is deprecated |
| ChapterURL = URL; | | ChapterURL = URL; |
− | ChapterUrlAccess = UrlAccess;
| |
| ChapterURLorigin = URLorigin; | | ChapterURLorigin = URLorigin; |
| URLorigin = ''; | | URLorigin = ''; |
Sətir 2.465: |
Sətir 2.135: |
| end | | end |
| | | |
− | -- для рувики: конкатенация |month к |date
| + | -- cite map oddities |
− | local Month = A['Month'];
| |
− | if is_set(Month) and is_set(Year) then
| |
− | Date = Month .. " " .. Year;
| |
− | Month = nil;
| |
− | Year = nil;
| |
− | end
| |
− | | |
− | -- cite map oddities
| |
| local Cartography = ""; | | local Cartography = ""; |
| local Scale = ""; | | local Scale = ""; |
Sətir 2.481: |
Sətir 2.143: |
| Chapter = A['Map']; | | Chapter = A['Map']; |
| ChapterURL = A['MapURL']; | | ChapterURL = A['MapURL']; |
− | ChapterUrlAccess = UrlAccess;
| |
| TransChapter = A['TransMap']; | | TransChapter = A['TransMap']; |
| ChapterURLorigin = A:ORIGIN('MapURL'); | | ChapterURLorigin = A:ORIGIN('MapURL'); |
Sətir 2.496: |
Sətir 2.157: |
| end | | end |
| | | |
− | -- Account for the oddities that are {{cite episode}} and {{cite serial}}, before generation of COinS data.
| + | -- Account for the oddities that are {{cite episode}} and {{cite serial}}, before generation of COinS data. |
| if 'episode' == config.CitationClass or 'serial' == config.CitationClass then | | if 'episode' == config.CitationClass or 'serial' == config.CitationClass then |
| local AirDate = A['AirDate']; | | local AirDate = A['AirDate']; |
Sətir 2.534: |
Sətir 2.195: |
| TransChapter = TransTitle; | | TransChapter = TransTitle; |
| ChapterURL = URL; | | ChapterURL = URL; |
− | ChapterUrlAccess = UrlAccess;
| |
| ChapterURLorigin = A:ORIGIN('URL'); | | ChapterURLorigin = A:ORIGIN('URL'); |
| | | |
Sətir 2.542: |
Sətir 2.202: |
| | | |
| if is_set (ChapterLink) and not is_set (ChapterURL) then -- link but not URL | | if is_set (ChapterLink) and not is_set (ChapterURL) then -- link but not URL |
− | Chapter = make_wikilink (ChapterLink, Chapter); | + | Chapter = '[[' .. ChapterLink .. '|' .. Chapter .. ']]'; -- ok to wikilink |
| elseif is_set (ChapterLink) and is_set (ChapterURL) then -- if both are set, URL links episode; | | elseif is_set (ChapterLink) and is_set (ChapterURL) then -- if both are set, URL links episode; |
− | Series = make_wikilink (ChapterLink, Series); | + | Series = '[[' .. ChapterLink .. '|' .. Series .. ']]'; -- series links with ChapterLink (episodelink -> TitleLink -> ChapterLink) ugly |
| end | | end |
| URL = ''; -- unset | | URL = ''; -- unset |
Sətir 2.554: |
Sətir 2.214: |
| Chapter = A['Episode']; -- TODO: make |episode= available to cite episode someday? | | Chapter = A['Episode']; -- TODO: make |episode= available to cite episode someday? |
| if is_set (Series) and is_set (SeriesLink) then | | if is_set (Series) and is_set (SeriesLink) then |
− | Series = make_wikilink (SeriesLink, Series); | + | Series = '[[' .. SeriesLink .. '|' .. Series .. ']]'; |
| end | | end |
| Series = wrap_style ('italic-title', Series); -- series is italicized | | Series = wrap_style ('italic-title', Series); -- series is italicized |
| end | | end |
| end | | end |
− | -- end of {{cite episode}} stuff
| + | -- end of {{cite episode}} stuff |
| | | |
− | -- Account for the oddities that are {{cite arxiv}}, {{cite biorxiv}}, {{cite citeseerx}}, before generation of COinS data.
| + | -- Account for the oddities that are {{cite arxiv}}, before generation of COinS data. |
− | do | + | if 'arxiv' == config.CitationClass then |
− | if in_array (config.CitationClass, {'arxiv', 'biorxiv', 'citeseerx'}) then
| + | if not is_set (ID_list['ARXIV']) then -- |arxiv= or |eprint= required for cite arxiv |
− | if not is_set (ID_list[config.CitationClass:upper()]) then -- |arxiv= or |eprint= required for cite arxiv; |biorxiv= & |citeseerx= required for their templates
| + | table.insert( z.message_tail, { set_error( 'arxiv_missing', {}, true ) } ); -- add error message |
− | table.insert( z.message_tail, { set_error( config.CitationClass .. '_missing', {}, true ) } ); -- add error message
| + | elseif is_set (Series) then -- series is an alias of version |
− | end
| + | ID_list['ARXIV'] = ID_list['ARXIV'] .. Series; -- concatenate version onto the end of the arxiv identifier |
− | | + | Series = ''; -- unset |
− | if 'arxiv' == config.CitationClass then
| + | deprecated_parameter ('version'); -- deprecated parameter but only for cite arxiv |
− | Periodical = 'arXiv'; -- set to arXiv for COinS; after that, must be set to empty string
| + | end |
− | end | + | |
| + | if first_set ({AccessDate, At, Chapter, Format, Page, Pages, Periodical, PublisherName, URL, -- a crude list of parameters that are not supported by cite arxiv |
| + | ID_list['ASIN'], ID_list['BIBCODE'], ID_list['DOI'], ID_list['ISBN'], ID_list['ISSN'], |
| + | ID_list['JFM'], ID_list['JSTOR'], ID_list['LCCN'], ID_list['MR'], ID_list['OCLC'], ID_list['OL'], |
| + | ID_list['OSTI'], ID_list['PMC'], ID_list['PMID'], ID_list['RFC'], ID_list['SSRN'], ID_list['USENETID'], ID_list['ZBL']},27) then |
| + | table.insert( z.message_tail, { set_error( 'arxiv_params_not_supported', {}, true ) } ); -- add error message |
| | | |
− | if 'biorxiv' == config.CitationClass then
| + | AccessDate= ''; -- set these to empty string; not supported in cite arXiv |
− | Periodical = 'bioRxiv'; -- set to bioRxiv for COinS; after that, must be set to empty string | + | PublisherName = ''; -- (if the article has been published, use cite journal, or other) |
− | end
| + | Chapter = ''; |
− | | + | URL = ''; |
− | if 'citeseerx' == config.CitationClass then
| + | Format = ''; |
− | Periodical = 'CiteSeerX'; -- set to CiteSeerX for COinS; after that, must be set to empty string | + | Page = ''; Pages = ''; At = ''; |
− | end
| |
| end | | end |
| + | Periodical = 'arXiv'; -- set to arXiv for COinS; after that, must be set to empty string |
| end | | end |
| | | |
− | -- handle type parameter for those CS1 citations that have default values
| + | -- handle type parameter for those CS1 citations that have default values |
− | if in_array(config.CitationClass, {"AV-media-notes", "interview", "mailinglist", "map", "podcast", "pressrelease", "report", "techreport", "thesis"}) then | + | if in_array(config.CitationClass, {"AV-media-notes", "DVD-notes", "mailinglist", "map", "podcast", "pressrelease", "report", "techreport", "thesis"}) then |
| TitleType = set_titletype (config.CitationClass, TitleType); | | TitleType = set_titletype (config.CitationClass, TitleType); |
| if is_set(Degree) and "Thesis" == TitleType then -- special case for cite thesis | | if is_set(Degree) and "Thesis" == TitleType then -- special case for cite thesis |
− | TitleType = Degree .. ' ' .. cfg.title_types ['thesis']:lower(); | + | TitleType = Degree .. " thesis"; |
| end | | end |
| end | | end |
| | | |
| if is_set(TitleType) then -- if type parameter is specified | | if is_set(TitleType) then -- if type parameter is specified |
− | TitleType = substitute( cfg.messages['type'], TitleType); -- display it in parentheses
| + | TitleType = substitute( cfg.messages['type'], TitleType); -- display it in parentheses |
− | -- TODO: Hack on TitleType to fix bunched parentheses problem
| |
| end | | end |
| | | |
− | -- legacy: promote PublicationDate to Date if neither Date nor Year are set.
| + | -- legacy: promote concatenation of |month=, and |year= to Date if Date not set; or, promote PublicationDate to Date if neither Date nor Year are set. |
− | local Date_origin; -- to hold the name of parameter promoted to Date; required for date error messaging
| |
− | | |
| if not is_set (Date) then | | if not is_set (Date) then |
| Date = Year; -- promote Year to Date | | Date = Year; -- promote Year to Date |
Sətir 2.604: |
Sətir 2.266: |
| Date = PublicationDate; -- promote PublicationDate to Date | | Date = PublicationDate; -- promote PublicationDate to Date |
| PublicationDate = ''; -- unset, no longer needed | | PublicationDate = ''; -- unset, no longer needed |
− | Date_origin = A:ORIGIN('PublicationDate'); -- save the name of the promoted parameter
| |
− | else
| |
− | Date_origin = A:ORIGIN('Year'); -- save the name of the promoted parameter
| |
| end | | end |
− | else
| |
− | Date_origin = A:ORIGIN('Date'); -- not a promotion; name required for error messaging
| |
| end | | end |
| | | |
| if PublicationDate == Date then PublicationDate = ''; end -- if PublicationDate is same as Date, don't display in rendered citation | | if PublicationDate == Date then PublicationDate = ''; end -- if PublicationDate is same as Date, don't display in rendered citation |
| | | |
− | --[[
| + | --[[ |
− | Go test all of the date-holding parameters for valid MOS:DATE format and make sure that dates are real dates. This must be done before we do COinS because here is where
| + | Go test all of the date-holding parameters for valid MOS:DATE format and make sure that dates are real dates. This must be done before we do COinS because here is where |
− | we get the date used in the metadata.
| + | we get the date used in the metadata. |
− |
| + | |
− | Date validation supporting code is in Module:Citation/CS1/Date_validation
| + | Date validation supporting code is in Module:Citation/CS1/Date_validation |
− | ]]
| + | ]] |
| do -- create defined block to contain local variables error_message, date_parameters_list, mismatch | | do -- create defined block to contain local variables error_message, date_parameters_list, mismatch |
| local error_message = ''; | | local error_message = ''; |
| -- AirDate has been promoted to Date so not necessary to check it | | -- AirDate has been promoted to Date so not necessary to check it |
− | local date_parameters_list = { | + | local date_parameters_list = {['access-date']=AccessDate, ['archive-date']=ArchiveDate, ['date']=Date, ['doi-broken-date']=DoiBroken, |
− | ['access-date'] = {val=AccessDate, name=A:ORIGIN ('AccessDate')},
| + | ['embargo']=Embargo, ['lay-date']=LayDate, ['publication-date']=PublicationDate, ['year']=Year}; |
− | ['archive-date'] = {val=ArchiveDate, name=A:ORIGIN ('ArchiveDate')},
| + | |
− | ['date'] = {val=Date, name=Date_origin},
| |
− | ['doi-broken-date'] = {val=DoiBroken, name=A:ORIGIN ('DoiBroken')},
| |
− | ['embargo'] = {val=Embargo, name=A:ORIGIN ('Embargo')},
| |
− | ['lay-date'] = {val=LayDate, name=A:ORIGIN ('LayDate')},
| |
− | ['publication-date'] ={val=PublicationDate, name=A:ORIGIN ('PublicationDate')},
| |
− | ['year'] = {val=Year, name=A:ORIGIN ('Year')},
| |
− | };
| |
| anchor_year, Embargo, error_message = dates(date_parameters_list, COinS_date); | | anchor_year, Embargo, error_message = dates(date_parameters_list, COinS_date); |
− |
| |
− | -- start temporary Julian / Gregorian calendar uncertainty categorization
| |
− | if COinS_date.inter_cal_cat then
| |
− | add_prop_cat ('jul_greg_uncertainty');
| |
− | end
| |
− | -- end temporary Julian / Gregorian calendar uncertainty categorization
| |
| | | |
| if is_set (Year) and is_set (Date) then -- both |date= and |year= not normally needed; | | if is_set (Year) and is_set (Date) then -- both |date= and |year= not normally needed; |
Sətir 2.652: |
Sətir 2.296: |
| end | | end |
| end | | end |
− |
| + | |
− | if not is_set(error_message) then -- error free dates only | + | if is_set(error_message) then |
− | local modified = false; -- flag | + | table.insert( z.message_tail, { set_error( 'bad_date', {error_message}, true ) } ); -- add this error message |
− |
| + | elseif is_set (DF) then |
− | if is_set (DF) then -- if we need to reformat dates
| + | if reformat_dates (date_parameters_list, DF, false) then -- reformat to DF format, use long month names if appropriate |
− | modified = reformat_dates (date_parameters_list, DF, false); -- reformat to DF format, use long month names if appropriate
| + | AccessDate = date_parameters_list['access-date']; -- overwrite date holding parameters with reformatted values |
− | end
| + | ArchiveDate = date_parameters_list['archive-date']; |
− | | + | Date = date_parameters_list['date']; |
− | if true == date_hyphen_to_dash (date_parameters_list) then -- convert hyphens to dashes where appropriate
| + | DoiBroken = date_parameters_list['doi-broken-date']; |
− | modified = true;
| + | LayDate = date_parameters_list['lay-date']; |
− | add_maint_cat ('date_format'); -- hyphens were converted so add maint category
| + | PublicationDate = date_parameters_list['publication-date']; |
− | end
| |
− |
| |
− | -- for those wikis that can and want to have English date names translated to the local language,
| |
− | -- uncomment these three lines. Not supported by en.wiki (for obvious reasons)
| |
− | -- set date_name_xlate() second argument to true to translate English digits to local digits (will translate ymd dates)
| |
− | -- if date_name_xlate (date_parameters_list, false) then
| |
− | -- modified = true;
| |
− | -- end
| |
− | | |
− | if modified then -- if the date_parameters_list values were modified
| |
− | AccessDate = date_parameters_list['access-date'].val; -- overwrite date holding parameters with modified values | |
− | ArchiveDate = date_parameters_list['archive-date'].val; | |
− | Date = date_parameters_list['date'].val; | |
− | DoiBroken = date_parameters_list['doi-broken-date'].val; | |
− | LayDate = date_parameters_list['lay-date'].val; | |
− | PublicationDate = date_parameters_list['publication-date'].val; | |
| end | | end |
− | else
| |
− | table.insert( z.message_tail, { set_error( 'bad_date', {error_message}, true ) } ); -- add this error message
| |
| end | | end |
| end -- end of do | | end -- end of do |
| | | |
− | -- Account for the oddity that is {{cite journal}} with |pmc= set and |url= not set. Do this after date check but before COInS.
| + | -- Account for the oddity that is {{cite journal}} with |pmc= set and |url= not set. Do this after date check but before COInS. |
− | -- Here we unset Embargo if PMC not embargoed (|embargo= not set in the citation) or if the embargo time has expired. Otherwise, holds embargo date
| + | -- Here we unset Embargo if PMC not embargoed (|embargo= not set in the citation) or if the embargo time has expired. Otherwise, holds embargo date |
− | Embargo = is_embargoed (Embargo); | + | Embargo = is_embargoed (Embargo); -- |
| | | |
| if config.CitationClass == "journal" and not is_set(URL) and is_set(ID_list['PMC']) then | | if config.CitationClass == "journal" and not is_set(URL) and is_set(ID_list['PMC']) then |
Sətir 2.693: |
Sətir 2.319: |
| URL=cfg.id_handlers['PMC'].prefix .. ID_list['PMC']; -- set url to be the same as the PMC external link if not embargoed | | URL=cfg.id_handlers['PMC'].prefix .. ID_list['PMC']; -- set url to be the same as the PMC external link if not embargoed |
| URLorigin = cfg.id_handlers['PMC'].parameters[1]; -- set URLorigin to parameter name for use in error message if citation is missing a |title= | | URLorigin = cfg.id_handlers['PMC'].parameters[1]; -- set URLorigin to parameter name for use in error message if citation is missing a |title= |
− | if is_set(AccessDate) then -- access date requires |url=; pmc created url is not |url=
| |
− | table.insert( z.message_tail, { set_error( 'accessdate_missing_url', {}, true ) } );
| |
− | AccessDate = ''; -- для рувики: TODO: убрать? -- unset
| |
− | end
| |
− |
| |
| end | | end |
| end | | end |
| | | |
− | -- At this point fields may be nil if they weren't specified in the template use. We can use that fact.
| + | -- At this point fields may be nil if they weren't specified in the template use. We can use that fact. |
| -- Test if citation has no title | | -- Test if citation has no title |
| if not is_set(Title) and | | if not is_set(Title) and |
Sətir 2.766: |
Sətir 2.387: |
| }, config.CitationClass); | | }, config.CitationClass); |
| | | |
− | -- Account for the oddities that are {{cite arxiv}}, {{cite biorxiv}}, and {{cite citeseerx}} AFTER generation of COinS data.
| + | -- Account for the oddities that are {{cite arxiv}}, AFTER generation of COinS data. |
− | if in_array (config.CitationClass, {'arxiv', 'biorxiv', 'citeseerx'}) then -- we have set rft.jtitle in COinS to arXiv, bioRxiv, or CiteSeerX now unset so it isn't displayed | + | if 'arxiv' == config.CitationClass then -- we have set rft.jtitle in COinS to arXiv, now unset so it isn't displayed |
− | Periodical = ''; -- periodical not allowed in these templates; if article has been published, use cite journal | + | Periodical = ''; -- periodical not allowed in cite arxiv; if article has been published, use cite journal |
| end | | end |
| | | |
− | -- special case for cite newsgroup. Do this after COinS because we are modifying Publishername to include some static text
| + | -- special case for cite newsgroup. Do this after COinS because we are modifying Publishername to include some static text |
| if 'newsgroup' == config.CitationClass then | | if 'newsgroup' == config.CitationClass then |
| if is_set (PublisherName) then | | if is_set (PublisherName) then |
− | PublisherName = substitute (cfg.messages['newsgroup'], external_link( 'news:' .. PublisherName, PublisherName, A:ORIGIN('PublisherName'), nil )); | + | PublisherName = substitute (cfg.messages['newsgroup'], external_link( 'news:' .. PublisherName, PublisherName, A:ORIGIN('PublisherName') )); |
| end | | end |
| end | | end |
Sətir 2.786: |
Sətir 2.407: |
| do | | do |
| local last_first_list; | | local last_first_list; |
| + | -- local maximum; |
| local control = { | | local control = { |
| format = NameListFormat, -- empty string or 'vanc' | | format = NameListFormat, -- empty string or 'vanc' |
| maximum = nil, -- as if display-authors or display-editors not set | | maximum = nil, -- as if display-authors or display-editors not set |
| lastauthoramp = LastAuthorAmp, | | lastauthoramp = LastAuthorAmp, |
− | page_name = this_page.text, -- get current page name so that we don't wikilink to it via editorlinkn | + | page_name = this_page.text -- get current page name so that we don't wikilink to it via editorlinkn |
− | mode = Mode
| |
| }; | | }; |
| | | |
− | do -- do editor name list first because the now unsupported coauthors used to modify control table | + | 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); | | control.maximum , editor_etal = get_display_authors_editors (A['DisplayEditors'], #e, 'editors', editor_etal); |
| last_first_list, EditorCount = list_people(control, e, editor_etal); | | last_first_list, EditorCount = list_people(control, e, editor_etal); |
Sətir 2.812: |
Sətir 2.433: |
| EditorCount = 2; -- spoof to display (eds.) annotation | | EditorCount = 2; -- spoof to display (eds.) annotation |
| end | | end |
− | end
| |
− | do -- now do interviewers
| |
− | control.maximum = #interviewers_list; -- number of interviewerss
| |
− | Interviewers = list_people(control, interviewers_list, false); -- et al not currently supported
| |
| end | | end |
| do -- now do translators | | do -- now do translators |
Sətir 2.828: |
Sətir 2.445: |
| control.maximum , author_etal = get_display_authors_editors (A['DisplayAuthors'], #a, 'authors', author_etal); | | control.maximum , author_etal = get_display_authors_editors (A['DisplayAuthors'], #a, 'authors', author_etal); |
| | | |
| + | if is_set(Coauthors) then -- if the coauthor field is also used, prevent ampersand and et al. formatting. |
| + | control.lastauthoramp = nil; |
| + | control.maximum = #a + 1; |
| + | end |
| + | |
| last_first_list = list_people(control, a, author_etal); | | last_first_list = list_people(control, a, author_etal); |
| | | |
Sətir 2.844: |
Sətir 2.466: |
| end | | end |
| | | |
| + | if not is_set(Authors) and is_set(Coauthors) then -- coauthors aren't displayed if one of authors=, authorn=, or lastn= isn't specified |
| + | table.insert( z.message_tail, { set_error('coauthors_missing_author', {}, true) } ); -- emit error message |
| + | end |
| end | | end |
| | | |
− | -- apply |[xx-]format= styling; at the end, these parameters hold correctly styled format annotation,
| + | -- apply |[xx-]format= styling; at the end, these parameters hold correctly styled format annotation, |
− | -- an error message if the associated url is not set, or an empty string for concatenation
| + | -- an error message if the associated url is not set, or an empty string for concatenation |
| ArchiveFormat = style_format (ArchiveFormat, ArchiveURL, 'archive-format', 'archive-url'); | | ArchiveFormat = style_format (ArchiveFormat, ArchiveURL, 'archive-format', 'archive-url'); |
| ConferenceFormat = style_format (ConferenceFormat, ConferenceURL, 'conference-format', 'conference-url'); | | ConferenceFormat = style_format (ConferenceFormat, ConferenceURL, 'conference-format', 'conference-url'); |
Sətir 2.854: |
Sətir 2.479: |
| TranscriptFormat = style_format (TranscriptFormat, TranscriptURL, 'transcript-format', 'transcripturl'); | | TranscriptFormat = style_format (TranscriptFormat, TranscriptURL, 'transcript-format', 'transcripturl'); |
| | | |
− | -- special case for chapter format so no error message or cat when chapter not supported
| + | -- special case for chapter format so no error message or cat when chapter not supported |
− | if not (in_array(config.CitationClass, {'web', 'news', 'journal', 'magazine', 'pressrelease', 'podcast', 'newsgroup', 'arxiv', 'biorxiv', 'citeseerx'}) or | + | if not (in_array(config.CitationClass, {'web','news','journal', 'magazine', 'pressrelease','podcast', 'newsgroup', 'arxiv'}) or |
| ('citation' == config.CitationClass and is_set (Periodical) and not is_set (Encyclopedia))) then | | ('citation' == config.CitationClass and is_set (Periodical) and not is_set (Encyclopedia))) then |
| ChapterFormat = style_format (ChapterFormat, ChapterURL, 'chapter-format', 'chapter-url'); | | ChapterFormat = style_format (ChapterFormat, ChapterURL, 'chapter-format', 'chapter-url'); |
Sətir 2.868: |
Sətir 2.493: |
| if is_set(AccessDate) and not is_set(ChapterURL)then -- ChapterURL may be set when URL is not set; | | if is_set(AccessDate) and not is_set(ChapterURL)then -- ChapterURL may be set when URL is not set; |
| table.insert( z.message_tail, { set_error( 'accessdate_missing_url', {}, true ) } ); | | table.insert( z.message_tail, { set_error( 'accessdate_missing_url', {}, true ) } ); |
− | -- AccessDate = ''; -- для рувики: убрано | + | AccessDate = ''; |
| end | | end |
| end | | end |
| | | |
− | local OriginalURL, OriginalURLorigin, OriginalFormat, OriginalAccess; | + | local OriginalURL, OriginalURLorigin, OriginalFormat; -- TODO: swap chapter and title here so that archive applies to most specific if both are set? |
| DeadURL = DeadURL:lower(); -- used later when assembling archived text | | DeadURL = DeadURL:lower(); -- used later when assembling archived text |
| if is_set( ArchiveURL ) then | | if is_set( ArchiveURL ) then |
− | if is_set (ChapterURL) then -- if chapter-url is set apply archive url to it | + | if is_set (ChapterURL) then -- swapped -- 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 | | OriginalURL = ChapterURL; -- save copy of source chapter's url for archive text |
| OriginalURLorigin = ChapterURLorigin; -- name of chapter-url parameter for error messages | | OriginalURLorigin = ChapterURLorigin; -- name of chapter-url parameter for error messages |
− | OriginalFormat = ChapterFormat; -- and original |chapter-format= | + | OriginalFormat = ChapterFormat; -- and original |format= |
| if 'no' ~= DeadURL then | | if 'no' ~= DeadURL then |
| ChapterURL = ArchiveURL -- swap-in the archive's url | | ChapterURL = ArchiveURL -- swap-in the archive's url |
| ChapterURLorigin = A:ORIGIN('ArchiveURL') -- name of archive-url parameter for error messages | | ChapterURLorigin = A:ORIGIN('ArchiveURL') -- name of archive-url parameter for error messages |
| ChapterFormat = ArchiveFormat or ''; -- swap in archive's format | | ChapterFormat = ArchiveFormat or ''; -- swap in archive's format |
− | ChapterUrlAccess = nil; -- restricted access levels do not make sense for archived urls
| |
| end | | end |
| elseif is_set (URL) then | | elseif is_set (URL) then |
| OriginalURL = URL; -- save copy of original source URL | | OriginalURL = URL; -- save copy of original source URL |
| OriginalURLorigin = URLorigin; -- name of url parameter for error messages | | OriginalURLorigin = URLorigin; -- name of url parameter for error messages |
− | OriginalFormat = Format; -- and original |format= | + | OriginalFormat = Format; -- and original |format= |
− | OriginalAccess = UrlAccess;
| |
| if 'no' ~= DeadURL then -- if URL set then archive-url applies to it | | if 'no' ~= DeadURL 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 |
| URLorigin = A:ORIGIN('ArchiveURL') -- name of archive url parameter for error messages | | URLorigin = A:ORIGIN('ArchiveURL') -- name of archive url parameter for error messages |
| Format = ArchiveFormat or ''; -- swap in archive's format | | Format = ArchiveFormat or ''; -- swap in archive's format |
− | UrlAccess = nil; -- restricted access levels do not make sense for archived urls
| |
| end | | end |
| end | | end |
| end | | end |
| | | |
− | if in_array(config.CitationClass, {'web','news','journal', 'magazine', 'pressrelease', 'podcast', 'newsgroup', 'arxiv', 'biorxiv', 'citeseerx'}) or -- if any of the 'periodical' cites except encyclopedia | + | if in_array(config.CitationClass, {'web','news','journal', 'magazine', 'pressrelease','podcast', 'newsgroup', 'arxiv'}) or -- if any of the 'periodical' cites except encyclopedia |
| ('citation' == config.CitationClass and is_set (Periodical) and not is_set (Encyclopedia)) then | | ('citation' == config.CitationClass and is_set (Periodical) and not is_set (Encyclopedia)) then |
| local chap_param; | | local chap_param; |
Sətir 2.930: |
Sətir 2.552: |
| end | | end |
| | | |
− | Chapter = format_chapter_title (ScriptChapter, Chapter, TransChapter, ChapterURL, ChapterURLorigin, no_quotes, ChapterUrlAccess); -- Contribution is also in Chapter | + | Chapter = format_chapter_title (ScriptChapter, Chapter, TransChapter, ChapterURL, ChapterURLorigin, no_quotes); -- Contribution is also in Chapter |
| if is_set (Chapter) then | | if is_set (Chapter) then |
| Chapter = Chapter .. ChapterFormat ; | | Chapter = Chapter .. ChapterFormat ; |
Sətir 2.943: |
Sətir 2.565: |
| | | |
| -- Format main title. | | -- Format main title. |
− | if is_set (ArchiveURL) and mw.ustring.match (mw.ustring.lower(Title), cfg.special_case_translation['archived_copy']) then -- if title is 'Archived copy' (place holder added by bots that can't find proper title)
| |
− | add_maint_cat ('archived_copy'); -- add maintenance category before we modify the content of Title
| |
− | end
| |
− |
| |
− | if Title:match ('^%(%(.*%)%)$') then -- if keep as written markup:
| |
− | Title= Title:gsub ('^%(%((.*)%)%)$', '%1') -- remove the markup
| |
− | else
| |
− | if '...' == Title:sub (-3) then -- if elipsis is the last three characters of |title=
| |
− | Title = Title:gsub ('(%.%.%.)%.+$', '%1'); -- limit the number of dots to three
| |
− | elseif not mw.ustring.find (Title, '%.%s*%a%.$') and -- end of title is not a 'dot-(optional space-)letter-dot' initialism ...
| |
− | not mw.ustring.find (Title, '%s+%a%.$') then -- ...and not a 'space-letter-dot' initial (''Allium canadense'' L.)
| |
− | Title = mw.ustring.gsub(Title, '%'..sepc..'$', ''); -- remove any trailing separator character; sepc and ms.ustring() here for languages that use multibyte separator characters
| |
− | end
| |
− | end
| |
− |
| |
| if is_set(TitleLink) and is_set(Title) then | | if is_set(TitleLink) and is_set(Title) then |
− | Title = make_wikilink (TitleLink, Title); | + | Title = "[[" .. TitleLink .. "|" .. Title .. "]]" |
| end | | end |
| | | |
− | if in_array(config.CitationClass, {'web', 'news', 'journal', 'magazine', 'pressrelease', 'podcast', 'newsgroup', 'mailinglist', 'interview', 'arxiv', 'biorxiv', 'citeseerx'}) or | + | if in_array(config.CitationClass, {'web','news','journal', 'magazine', 'pressrelease','podcast', 'newsgroup', 'mailinglist', 'arxiv'}) or |
| ('citation' == config.CitationClass and is_set (Periodical) and not is_set (Encyclopedia)) or | | ('citation' == config.CitationClass and is_set (Periodical) and not is_set (Encyclopedia)) or |
| ('map' == config.CitationClass and is_set (Periodical)) then -- special case for cite map when the map is in a periodical treat as an article | | ('map' == config.CitationClass and is_set (Periodical)) 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 = wrap_style ('quoted-title', Title); | | Title = wrap_style ('quoted-title', Title); |
| + | |
| Title = script_concatenate (Title, ScriptTitle); -- <bdi> tags, lang atribute, categorization, etc; must be done after title is wrapped | | Title = script_concatenate (Title, ScriptTitle); -- <bdi> tags, lang atribute, categorization, etc; must be done after title is wrapped |
| TransTitle= wrap_style ('trans-quoted-title', TransTitle ); | | TransTitle= wrap_style ('trans-quoted-title', TransTitle ); |
Sətir 2.986: |
Sətir 2.594: |
| end | | end |
| end | | end |
| + | |
| + | Title = Title .. TransTitle; |
| | | |
| if is_set(Title) then | | if is_set(Title) then |
| if not is_set(TitleLink) and is_set(URL) then | | if not is_set(TitleLink) and is_set(URL) then |
− |
| + | Title = external_link( URL, Title, URLorigin ) .. TransError .. Format; |
− | Title = external_link( URL, Title, URLorigin, UrlAccess ) .. TransTitle .. TransError .. Format; | + | -- this experiment hidden 2016-04-10; see Help_talk:Citation_Style_1#Recycled_urls |
| + | -- 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 | | URL = ''; -- unset these because no longer needed |
| Format = ""; | | Format = ""; |
| else | | else |
− | Title = Title .. TransTitle .. TransError; | + | Title = Title .. TransError; |
| end | | end |
− | else
| |
− | Title = TransTitle .. TransError;
| |
| end | | end |
| | | |
Sətir 3.006: |
Sətir 2.625: |
| if is_set (Conference) then | | if is_set (Conference) then |
| if is_set (ConferenceURL) then | | if is_set (ConferenceURL) then |
− | Conference = external_link( ConferenceURL, Conference, ConferenceURLorigin, nil ); | + | Conference = external_link( ConferenceURL, Conference, ConferenceURLorigin ); |
| end | | end |
| Conference = sepc .. " " .. Conference .. ConferenceFormat; | | Conference = sepc .. " " .. Conference .. ConferenceFormat; |
| elseif is_set(ConferenceURL) then | | elseif is_set(ConferenceURL) then |
− | Conference = sepc .. " " .. external_link( ConferenceURL, nil, ConferenceURLorigin, nil ); | + | Conference = sepc .. " " .. external_link( ConferenceURL, nil, ConferenceURLorigin ); |
| end | | end |
| | | |
Sətir 3.064: |
Sətir 2.683: |
| else | | else |
| Language=""; -- language not specified so make sure this is an empty string; | | Language=""; -- language not specified so make sure this is an empty string; |
− | --[[ TODO: need to extract the wrap_msg from language_parameter
| |
− | so that we can solve parentheses bunching problem with Format/Language/TitleType
| |
− | ]]
| |
| end | | end |
| | | |
Sətir 3.072: |
Sətir 2.688: |
| | | |
| if is_set (Translators) then | | if is_set (Translators) then |
− | Others = safe_join ({sepc .. ' ', wrap_msg ('translated', Translators, use_lowercase), Others}, sepc); | + | Others = sepc .. ' Translated by ' .. Translators .. Others; |
| end | | end |
− | if is_set (Interviewers) then
| + | |
− | Others = safe_join ({sepc .. ' ', wrap_msg ('interview', Interviewers, use_lowercase), Others}, sepc);
| |
− | end
| |
− |
| |
| TitleNote = is_set(TitleNote) and (sepc .. " " .. TitleNote) or ""; | | TitleNote = is_set(TitleNote) and (sepc .. " " .. TitleNote) or ""; |
| if is_set (Edition) then | | if is_set (Edition) then |
Sətir 3.089: |
Sətir 2.702: |
| | | |
| Series = is_set(Series) and (sepc .. " " .. Series) or ""; | | Series = is_set(Series) and (sepc .. " " .. Series) or ""; |
− | OrigYear = is_set(OrigYear) and (" [" .. OrigYear .. "]") or ""; -- TODO: presentation
| + | OrigYear = is_set(OrigYear) and (" [" .. OrigYear .. "]") or ""; |
− | | |
| Agency = is_set(Agency) and (sepc .. " " .. Agency) or ""; | | Agency = is_set(Agency) and (sepc .. " " .. Agency) or ""; |
| | | |
Sətir 3.100: |
Sətir 2.712: |
| end | | end |
| | | |
− | --[[
| + | --[[ |
− | Subscription implies paywall; Registration does not. If both are used in a citation, the subscription required link
| + | 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.
| + | note is displayed. There are no error messages for this condition. |
− |
| + | |
− | ]]
| + | ]] |
| if is_set (SubscriptionRequired) then | | if is_set (SubscriptionRequired) then |
| SubscriptionRequired = sepc .. " " .. cfg.messages['subscription']; -- subscription required message | | SubscriptionRequired = sepc .. " " .. cfg.messages['subscription']; -- subscription required message |
Sətir 3.117: |
Sətir 2.729: |
| | | |
| 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 |
− | 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 'citation', lower case |
| AccessDate = substitute (retrv_text, AccessDate); -- add retrieved text | | AccessDate = substitute (retrv_text, AccessDate); -- add retrieved text |
− | | + | -- neither of these work; don't know why; it seems that substitute() isn't being called |
| AccessDate = substitute (cfg.presentation['accessdate'], {sepc, AccessDate}); -- allow editors to hide accessdates | | AccessDate = substitute (cfg.presentation['accessdate'], {sepc, AccessDate}); -- allow editors to hide accessdates |
| end | | end |
Sətir 3.131: |
Sətir 2.743: |
| end | | end |
| | | |
− | ID_list = build_id_list( ID_list, {IdAccessLevels=ID_access_levels, DoiBroken = DoiBroken, ASINTLD = ASINTLD, IgnoreISBN = IgnoreISBN, Embargo=Embargo, Class = Class} ); | + | ID_list = build_id_list( ID_list, {DoiBroken = DoiBroken, ASINTLD = ASINTLD, IgnoreISBN = IgnoreISBN, Embargo=Embargo, Class = Class} ); |
| | | |
| if is_set(URL) then | | if is_set(URL) then |
− | URL = " " .. external_link( URL, nil, URLorigin, UrlAccess ); | + | URL = " " .. external_link( URL, nil, URLorigin ); |
| end | | end |
| | | |
Sətir 3.154: |
Sətir 2.766: |
| if sepc ~= "." then arch_text = arch_text:lower() end | | if sepc ~= "." then arch_text = arch_text:lower() end |
| Archived = sepc .. " " .. substitute( cfg.messages['archived-not-dead'], | | Archived = sepc .. " " .. substitute( cfg.messages['archived-not-dead'], |
− | { external_link( ArchiveURL, arch_text, A:ORIGIN('ArchiveURL'), nil ) .. ArchiveFormat, ArchiveDate } ); | + | { external_link( ArchiveURL, arch_text, A:ORIGIN('ArchiveURL') ) .. ArchiveFormat, ArchiveDate } ); |
| if not is_set(OriginalURL) then | | if not is_set(OriginalURL) then |
| Archived = Archived .. " " .. set_error('archive_missing_url'); | | Archived = Archived .. " " .. set_error('archive_missing_url'); |
Sətir 3.161: |
Sətir 2.773: |
| local arch_text = cfg.messages['archived-dead']; | | local arch_text = cfg.messages['archived-dead']; |
| if sepc ~= "." then arch_text = arch_text:lower() end | | if sepc ~= "." then arch_text = arch_text:lower() end |
− | if in_array (DeadURL, {'unfit', 'usurped', 'bot: unknown'}) then | + | if in_array (DeadURL, {'unfit', 'usurped'}) then |
| Archived = sepc .. " " .. 'Archived from the original on ' .. ArchiveDate; -- format already styled | | Archived = sepc .. " " .. 'Archived from the original on ' .. ArchiveDate; -- format already styled |
− | if 'bot: unknown' == DeadURL then
| |
− | add_maint_cat ('bot:_unknown'); -- and add a category if not already added
| |
− | else
| |
− | add_maint_cat ('unfit'); -- and add a category if not already added
| |
− | end
| |
| else -- DeadURL is empty, 'yes', 'true', or 'y' | | else -- DeadURL is empty, 'yes', 'true', or 'y' |
| Archived = sepc .. " " .. substitute( arch_text, | | Archived = sepc .. " " .. substitute( arch_text, |
− | { external_link( OriginalURL, cfg.messages['original'], OriginalURLorigin, OriginalAccess ) .. OriginalFormat, ArchiveDate } ); -- format already styled | + | { external_link( OriginalURL, cfg.messages['original'], OriginalURLorigin ) .. OriginalFormat, ArchiveDate } ); -- format already styled |
| end | | end |
| else | | else |
Sətir 3.193: |
Sətir 2.800: |
| end | | end |
| if sepc == '.' then | | if sepc == '.' then |
− | Lay = sepc .. " " .. external_link( LayURL, cfg.messages['lay summary'], A:ORIGIN('LayURL'), nil ) .. LayFormat .. LaySource .. LayDate | + | Lay = sepc .. " " .. external_link( LayURL, cfg.messages['lay summary'], A:ORIGIN('LayURL') ) .. LayFormat .. LaySource .. LayDate |
| else | | else |
− | Lay = sepc .. " " .. external_link( LayURL, cfg.messages['lay summary']:lower(), A:ORIGIN('LayURL'), nil ) .. LayFormat .. LaySource .. LayDate | + | Lay = sepc .. " " .. external_link( LayURL, cfg.messages['lay summary']:lower(), A:ORIGIN('LayURL') ) .. LayFormat .. LaySource .. LayDate |
| end | | end |
| elseif is_set (LayFormat) then -- Test if |lay-format= is given without giving a |lay-url= | | elseif is_set (LayFormat) then -- Test if |lay-format= is given without giving a |lay-url= |
Sətir 3.203: |
Sətir 2.810: |
| if is_set(Transcript) then | | if is_set(Transcript) then |
| if is_set(TranscriptURL) then | | if is_set(TranscriptURL) then |
− | Transcript = external_link( TranscriptURL, Transcript, TranscriptURLorigin, nil ); | + | Transcript = external_link( TranscriptURL, Transcript, TranscriptURLorigin ); |
| end | | end |
| Transcript = sepc .. ' ' .. Transcript .. TranscriptFormat; | | Transcript = sepc .. ' ' .. Transcript .. TranscriptFormat; |
| elseif is_set(TranscriptURL) then | | elseif is_set(TranscriptURL) then |
− | Transcript = external_link( TranscriptURL, nil, TranscriptURLorigin, nil ); | + | Transcript = external_link( TranscriptURL, nil, TranscriptURLorigin ); |
| end | | end |
| | | |
| local Publisher; | | local Publisher; |
− | if is_set(PublicationDate) then | + | if is_set(Periodical) and |
− | PublicationDate = wrap_msg ('published', PublicationDate); | + | not in_array(config.CitationClass, {"encyclopaedia","web","pressrelease","podcast"}) then |
− | end
| + | if is_set(PublisherName) then |
− | if is_set(PublisherName) then
| + | if is_set(PublicationPlace) then |
− | if is_set(PublicationPlace) then
| + | Publisher = PublicationPlace .. ": " .. PublisherName; |
− | Publisher = sepc .. " " .. PublicationPlace .. ": " .. PublisherName .. PublicationDate;
| + | else |
− | else
| + | Publisher = PublisherName; |
− | Publisher = sepc .. " " .. PublisherName .. PublicationDate;
| + | end |
− | end
| + | elseif is_set(PublicationPlace) then |
− | elseif is_set(PublicationPlace) then
| + | Publisher= PublicationPlace; |
− | Publisher= sepc .. " " .. PublicationPlace .. PublicationDate;
| + | else |
− | else
| + | Publisher = ""; |
− | Publisher = PublicationDate;
| + | end |
| + | if is_set(PublicationDate) then |
| + | if is_set(Publisher) then |
| + | Publisher = Publisher .. ", " .. wrap_msg ('published', PublicationDate); |
| + | else |
| + | Publisher = PublicationDate; |
| + | end |
| + | end |
| + | if is_set(Publisher) then |
| + | Publisher = " (" .. Publisher .. ")"; |
| + | end |
| + | else |
| + | if is_set(PublicationDate) then |
| + | PublicationDate = " (" .. wrap_msg ('published', PublicationDate) .. ")"; |
| + | end |
| + | if is_set(PublisherName) then |
| + | if is_set(PublicationPlace) then |
| + | Publisher = sepc .. " " .. PublicationPlace .. ": " .. PublisherName .. PublicationDate; |
| + | else |
| + | Publisher = sepc .. " " .. PublisherName .. PublicationDate; |
| + | end |
| + | elseif is_set(PublicationPlace) then |
| + | Publisher= sepc .. " " .. PublicationPlace .. PublicationDate; |
| + | else |
| + | Publisher = PublicationDate; |
| + | end |
| end | | end |
| | | |
Sətir 3.235: |
Sətir 2.867: |
| end | | end |
| | | |
− | --[[
| + | --[[ |
− | Handle the oddity that is cite speech. This code overrides whatever may be the value assigned to TitleNote (through |department=) and forces it to be " (Speech)" so that
| + | Handle the oddity that is cite speech. This code overrides whatever may be the value assigned to TitleNote (through |department=) and forces it to be " (Speech)" so that |
− | the annotation directly follows the |title= parameter value in the citation rather than the |event= parameter value (if provided).
| + | the annotation directly follows the |title= parameter value in the citation rather than the |event= parameter value (if provided). |
− | ]]
| + | ]] |
| if "speech" == config.CitationClass then -- cite speech only | | if "speech" == config.CitationClass then -- cite speech only |
| TitleNote = " (Speech)"; -- annotate the citation | | TitleNote = " (Speech)"; -- annotate the citation |
Sətir 3.256: |
Sətir 2.888: |
| | | |
| if in_array(config.CitationClass, {"journal","citation"}) and is_set(Periodical) then | | if in_array(config.CitationClass, {"journal","citation"}) and is_set(Periodical) then |
− | if 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? | + | if is_set(Others) then Others = Others .. sepc .. " " end |
− | tcommon = safe_join( {Others, Title, TitleNote, Conference, Periodical, Format, TitleType, Series, Language, Edition, Publisher, Agency, Volume}, sepc ); | + | tcommon = safe_join( {Others, Title, TitleNote, Conference, Periodical, Format, TitleType, Series, |
| + | Language, Edition, Publisher, Agency, Volume}, sepc ); |
| + | |
| elseif in_array(config.CitationClass, {"book","citation"}) and not is_set(Periodical) then -- special cases for book cites | | elseif in_array(config.CitationClass, {"book","citation"}) and not is_set(Periodical) then -- special cases for book cites |
| if is_set (Contributors) then -- when we are citing foreword, preface, introduction, etc | | if is_set (Contributors) then -- when we are citing foreword, preface, introduction, etc |
Sətir 3.277: |
Sətir 2.911: |
| 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, Transcript, Language, Edition, Publisher}, sepc ); | | tcommon = safe_join( {Title, TitleNote, TitleType, Series, Transcript, 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, Format, TitleType, Series, Language, |
Sətir 3.303: |
Sətir 2.936: |
| end | | end |
| end | | end |
− | end | + | end |
− | | |
| if is_set(Authors) then | | if is_set(Authors) then |
− | -- для рувики: конкатенация |coauthors к |authors (без остальной поддержки вроде убирания амперсанта и автоскрытия)
| |
| if is_set(Coauthors) then | | if is_set(Coauthors) then |
− | Authors = Authors .. "; " .. Coauthors; | + | if 'vanc' == NameListFormat then -- separate authors and coauthors with proper name-list-separator |
| + | Authors = Authors .. ', ' .. Coauthors; |
| + | else |
| + | Authors = Authors .. '; ' .. Coauthors; |
| + | end |
| end | | end |
− |
| + | if not is_set (Date) then -- when date is set it's in parentheses; no Authors termination |
− | if (not is_set (Date)) then -- when date is set it's in parentheses; no Authors termination | |
| Authors = terminate_name_list (Authors, sepc); -- when no date, terminate with 0 or 1 sepc and a space | | Authors = terminate_name_list (Authors, sepc); -- when no date, terminate with 0 or 1 sepc and a space |
| end | | end |
Sətir 3.319: |
Sətir 2.953: |
| if is_set(Chapter) and 0 == #c then | | if is_set(Chapter) and 0 == #c then |
| in_text = in_text .. cfg.messages['in'] .. " " | | in_text = in_text .. cfg.messages['in'] .. " " |
− | if (sepc ~= '.') then | + | if (sepc ~= '.') then in_text = in_text:lower() end -- lowercase for cs2 |
− | in_text = in_text:lower() -- lowercase for cs2
| |
− | end
| |
| else | | else |
| if EditorCount <= 1 then | | if EditorCount <= 1 then |
Sətir 3.335: |
Sətir 2.967: |
| if (sepc ~= '.') then by_text = by_text:lower() end -- lowercase for cs2 | | if (sepc ~= '.') then by_text = by_text:lower() end -- 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 is_set (Editors) and is_set (Date) then -- when Editors make sure that Authors gets terminated | + | if is_set (Editors) then -- when Editors make sure that Authors gets terminated |
| Authors = terminate_name_list (Authors, sepc); -- terminate with 0 or 1 sepc and a space | | Authors = terminate_name_list (Authors, sepc); -- terminate with 0 or 1 sepc and a space |
| end | | end |
− | if (not is_set (Date)) then -- when date is set it's in parentheses; no Contributors termination | + | if not is_set (Date) then -- when date is set it's in parentheses; no Contributors termination |
| Contributors = terminate_name_list (Contributors, sepc); -- terminate with 0 or 1 sepc and a space | | Contributors = terminate_name_list (Contributors, sepc); -- terminate with 0 or 1 sepc and a space |
| end | | end |
Sətir 3.361: |
Sətir 2.993: |
| text = safe_join( {Editors, Date, Chapter, Place, tcommon, pgtext, idcommon}, sepc ); | | text = safe_join( {Editors, Date, Chapter, Place, tcommon, pgtext, idcommon}, sepc ); |
| else | | else |
− | if in_array(config.CitationClass, {"journal","citation"}) and is_set(Periodical) then | + | if config.CitationClass=="journal" and is_set(Periodical) then |
| text = safe_join( {Chapter, Place, tcommon, pgtext, Date, idcommon}, sepc ); | | text = safe_join( {Chapter, Place, tcommon, pgtext, Date, idcommon}, sepc ); |
| else | | else |
Sətir 3.398: |
Sətir 3.030: |
| namelist = e; | | namelist = e; |
| end | | end |
− | if #namelist > 0 then -- if there are names in namelist | + | id = anchor_id (namelist, year); -- go make the CITEREF anchor |
− | id = anchor_id (namelist, year); -- go make the CITEREF anchor
| + | end |
− | else
| + | options.id = id; |
− | id = ''; -- unset
| |
− | end
| |
− | elseif Ref ~= '' and mw.ustring.sub(Ref, 0, 7) ~= 'CITEREF' then -- для рувики: иная генерация ref-якорей
| |
− | if mw.ustring.match(id, '%d%d%d%d') then
| |
− | id = '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
| |
− | id = 'CITEREF' .. id .. yearForRef
| |
− | else
| |
− | id = '' -- TODO: для рувики: выдавать ошибку?
| |
− | end
| |
− | end
| |
− | end | |
− | options.id = id; | |
| end | | end |
| | | |
− | if string.len(text:gsub("<span[^>/]*>(.-)</span>", "%1"):gsub("%b<>","")) <= 2 then -- remove <span> tags and other html-like markup; then get length of what remains | + | if string.len(text:gsub("<span[^>/]*>.-</span>", ""):gsub("%b<>","")) <= 2 then |
| z.error_categories = {}; | | z.error_categories = {}; |
| text = set_error('empty_citation'); | | text = set_error('empty_citation'); |
Sətir 3.429: |
Sətir 3.041: |
| end | | end |
| | | |
− | local render = {}; -- here we collect the final bits for concatenation into the rendered citation
| |
− |
| |
| if is_set(options.id) then -- here we wrap the rendered citation in <cite ...>...</cite> tags | | if is_set(options.id) then -- here we wrap the rendered citation in <cite ...>...</cite> tags |
− | table.insert (render, substitute (cfg.presentation['cite-id'], {mw.uri.anchorEncode(options.id), mw.text.nowiki(options.class), text})); -- when |ref= is set | + | text = substitute (cfg.presentation['cite-id'], {mw.uri.anchorEncode(options.id), mw.text.nowiki(options.class), text}); -- when |ref= is set |
| else | | else |
− | table.insert (render, substitute (cfg.presentation['cite'], {mw.text.nowiki(options.class), text})); -- all other cases | + | text = substitute (cfg.presentation['cite'], {mw.text.nowiki(options.class), text}); -- all other cases |
| end | | end |
| | | |
− | table.insert (render, substitute (cfg.presentation['ocins'], {OCinSoutput})); -- append metadata to the citation | + | text = text .. substitute (cfg.presentation['ocins'], {OCinSoutput}); -- append metadata to the citation |
− | | + | |
| if #z.message_tail ~= 0 then | | if #z.message_tail ~= 0 then |
− | table.insert (render, ' '); | + | text = text .. " "; |
| for i,v in ipairs( z.message_tail ) do | | for i,v in ipairs( z.message_tail ) do |
| if is_set(v[1]) then | | if is_set(v[1]) then |
| if i == #z.message_tail then | | if i == #z.message_tail then |
− | table.insert (render, error_comment( v[1], v[2] )); | + | text = text .. error_comment( v[1], v[2] ); |
| else | | else |
− | table.insert (render, error_comment( v[1] .. "; ", v[2] )); | + | text = text .. error_comment( v[1] .. "; ", v[2] ); |
| end | | end |
| end | | end |
Sətir 3.453: |
Sətir 3.063: |
| | | |
| if #z.maintenance_cats ~= 0 then | | if #z.maintenance_cats ~= 0 then |
− | table.insert (render, '<span class="citation-comment" style="display:none; color:#33aa33; margin-left:0.3em">'); | + | text = text .. '<span class="citation-comment" style="display:none; color:#33aa33">'; |
| for _, v in ipairs( z.maintenance_cats ) do -- append maintenance categories | | for _, v in ipairs( z.maintenance_cats ) do -- append maintenance categories |
− | table.insert (render, v); | + | text = text .. ' ' .. v .. ' ([[:Category:' .. v ..'|link]])'; |
− | table.insert (render, ' (');
| |
− | table.insert (render, make_wikilink (':Category:' .. v, 'link'));
| |
− | table.insert (render, ') ');
| |
| end | | end |
− | table.insert (render, '</span>'); | + | text = text .. '</span>'; -- maintenance mesages (realy just the names of the categories for now) |
| end | | end |
| | | |
Sətir 3.466: |
Sətir 3.073: |
| if in_array(no_tracking_cats, {"", "no", "false", "n"}) then | | if in_array(no_tracking_cats, {"", "no", "false", "n"}) then |
| for _, v in ipairs( z.error_categories ) do | | for _, v in ipairs( z.error_categories ) do |
− | table.insert (render, make_wikilink ('Category:' .. v)); | + | text = text .. '[[Category:' .. v ..']]'; |
| end | | end |
| for _, v in ipairs( z.maintenance_cats ) do -- append maintenance categories | | for _, v in ipairs( z.maintenance_cats ) do -- append maintenance categories |
− | table.insert (render, make_wikilink ('Category:' .. v)); | + | text = text .. '[[Category:' .. v ..']]'; |
− | end
| |
− | for _, v in ipairs( z.properties_cats ) do -- append properties categories
| |
− | table.insert (render, make_wikilink ('Category:' .. v));
| |
− | end
| |
− | end
| |
− | | |
− | return table.concat (render);
| |
− | end
| |
− | | |
− | | |
− | --[[--------------------------< V A L I D A T E >--------------------------------------------------------------
| |
− | | |
− | Looks for a parameter's name in one of several whitelists.
| |
− | | |
− | Parameters in the whitelist can have three values:
| |
− | true - active, supported parameters
| |
− | false - deprecated, supported parameters
| |
− | nil - unsupported parameters
| |
− |
| |
− | ]] | |
− | | |
− | local function validate (name, cite_class)
| |
− | local name = tostring (name);
| |
− | local state;
| |
− |
| |
− | if in_array (cite_class, {'arxiv', 'biorxiv', 'citeseerx'}) then -- limited parameter sets allowed for these templates
| |
− | state = whitelist.limited_basic_arguments[name];
| |
− | if true == state then return true; end -- valid actively supported parameter
| |
− | if false == state then
| |
− | deprecated_parameter (name); -- parameter is deprecated but still supported
| |
− | return true;
| |
| end | | end |
− | | + | for _, v in ipairs( z.properties_cats ) do -- append maintenance categories |
− | state = whitelist[cite_class .. '_basic_arguments'][name]; -- look in the parameter-list for the template identified by cite_class
| + | text = text .. '[[Category:' .. v ..']]'; |
− | | |
− | if true == state then return true; end -- valid actively supported parameter
| |
− | if false == state then
| |
− | deprecated_parameter (name); -- parameter is deprecated but still supported
| |
− | return true;
| |
| end | | end |
− | -- limited enumerated parameters list
| |
− | name = name:gsub("%d+", "#" ); -- replace digit(s) with # (last25 becomes last#) (mw.ustring because non-Western 'local' digits)
| |
− | state = whitelist.limited_numbered_arguments[name];
| |
− | if true == state then return true; end -- valid actively supported parameter
| |
− | if false == state then
| |
− | deprecated_parameter (name); -- parameter is deprecated but still supported
| |
− | return true;
| |
− | end
| |
− |
| |
− | return false; -- not supported because not found or name is set to nil
| |
− | end -- end limited parameter-set templates
| |
− |
| |
− | state = whitelist.basic_arguments[name]; -- all other templates; all normal parameters allowed
| |
− |
| |
− | if true == state then return true; end -- valid actively supported parameter
| |
− | if false == state then
| |
− | deprecated_parameter (name); -- parameter is deprecated but still supported
| |
− | return true;
| |
− | end
| |
− | -- all enumerated parameters allowed
| |
− | name = name:gsub("%d+", "#" ); -- replace digit(s) with # (last25 becomes last#) (mw.ustring because non-Western 'local' digits)
| |
− | state = whitelist.numbered_arguments[name];
| |
− |
| |
− | if true == state then return true; end -- valid actively supported parameter
| |
− | if false == state then
| |
− | deprecated_parameter (name); -- parameter is deprecated but still supported
| |
− | return true;
| |
| end | | end |
| | | |
− | return false; -- not supported because not found or name is set to nil | + | return text |
− | 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 | | end |
− |
| |
| | | |
| --[[--------------------------< C S 1 . C I T A T I O N >------------------------------------------------------ | | --[[--------------------------< C S 1 . C I T A T I O N >------------------------------------------------------ |
Sətir 3.575: |
Sətir 3.093: |
| | | |
| function cs1.citation(frame) | | function cs1.citation(frame) |
− | Frame = frame; -- save a copy incase we need to display an error message in preview mode
| |
| local pframe = frame:getParent() | | local pframe = frame:getParent() |
− | local validation, utilities, identifiers, metadata, styles; | + | local validation, utilities, identifiers, metadata; |
| | | |
| if nil ~= string.find (frame:getTitle(), 'sandbox', 1, true) then -- did the {{#invoke:}} use sandbox version? | | if nil ~= string.find (frame:getTitle(), 'sandbox', 1, true) then -- did the {{#invoke:}} use sandbox version? |
Sətir 3.586: |
Sətir 3.103: |
| identifiers = require ('Module:Citation/CS1/Identifiers/sandbox'); | | identifiers = require ('Module:Citation/CS1/Identifiers/sandbox'); |
| metadata = require ('Module:Citation/CS1/COinS/sandbox'); | | metadata = require ('Module:Citation/CS1/COinS/sandbox'); |
− | styles = 'Module:Citation/CS1/sandbox/styles.css';
| |
| | | |
| else -- otherwise | | else -- otherwise |
Sətir 3.595: |
Sətir 3.111: |
| identifiers = require ('Module:Citation/CS1/Identifiers'); | | identifiers = require ('Module:Citation/CS1/Identifiers'); |
| metadata = require ('Module:Citation/CS1/COinS'); | | metadata = require ('Module:Citation/CS1/COinS'); |
− | styles = 'Module:Citation/CS1/styles.css';
| |
− |
| |
| end | | end |
| | | |
| utilities.set_selected_modules (cfg); -- so that functions in Utilities can see the cfg tables | | utilities.set_selected_modules (cfg); -- so that functions in Utilities can see the cfg tables |
| identifiers.set_selected_modules (cfg, utilities); -- so that functions in Identifiers can see the selected cfg tables and selected Utilities module | | identifiers.set_selected_modules (cfg, utilities); -- so that functions in Identifiers can see the selected cfg tables and selected Utilities module |
− | validation.set_selected_modules (cfg, utilities); -- so that functions in Date validataion can see selected cfg tables and the selected Utilities module | + | validation.set_selected_modules (utilities); -- so that functions in Date validataion can see the selected Utilities module |
| metadata.set_selected_modules (cfg, utilities); -- so that functions in COinS can see the selected cfg tables and selected Utilities module | | metadata.set_selected_modules (cfg, utilities); -- so that functions in COinS can see the selected cfg tables and selected Utilities module |
| | | |
Sətir 3.607: |
Sətir 3.121: |
| year_date_check = validation.year_date_check; | | year_date_check = validation.year_date_check; |
| reformat_dates = validation.reformat_dates; | | reformat_dates = validation.reformat_dates; |
− | date_hyphen_to_dash = validation.date_hyphen_to_dash; | + | |
− | date_name_xlate = validation.date_name_xlate;
| |
− | | |
| is_set = utilities.is_set; -- imported functions from Module:Citation/CS1/Utilities | | is_set = utilities.is_set; -- imported functions from Module:Citation/CS1/Utilities |
| in_array = utilities.in_array; | | in_array = utilities.in_array; |
Sətir 3.616: |
Sətir 3.128: |
| set_error = utilities.set_error; | | set_error = utilities.set_error; |
| select_one = utilities.select_one; | | select_one = utilities.select_one; |
− | add_maint_cat = function () end; -- для рувики: вместо utilities.add_maint_cat; | + | add_maint_cat = utilities.add_maint_cat; |
| wrap_style = utilities.wrap_style; | | wrap_style = utilities.wrap_style; |
| safe_for_italics = utilities.safe_for_italics; | | safe_for_italics = utilities.safe_for_italics; |
− | is_wikilink = utilities.is_wikilink; | + | remove_wiki_link = utilities.remove_wiki_link; |
− | make_wikilink = utilities.make_wikilink;
| |
| | | |
| z = utilities.z; -- table of error and category tables in Module:Citation/CS1/Utilities | | z = utilities.z; -- table of error and category tables in Module:Citation/CS1/Utilities |
| | | |
− | extract_ids = identifiers.extract_ids; -- imported functions from Module:Citation/CS1/Identifiers | + | extract_ids = identifiers.extract_ids; -- imported functions from Module:Citation/CS1/Utilities |
| build_id_list = identifiers.build_id_list; | | build_id_list = identifiers.build_id_list; |
| is_embargoed = identifiers.is_embargoed; | | is_embargoed = identifiers.is_embargoed; |
− | extract_id_access_levels = identifiers.extract_id_access_levels;
| |
| | | |
| make_coins_title = metadata.make_coins_title; -- imported functions from Module:Citation/CS1/COinS | | make_coins_title = metadata.make_coins_title; -- imported functions from Module:Citation/CS1/COinS |
Sətir 3.633: |
Sətir 3.143: |
| COinS = metadata.COinS; | | COinS = metadata.COinS; |
| | | |
− | local args = {}; -- table where we store all of the template's arguments | + | |
− | local suggestions = {}; -- table where we store suggestions if we need to loadData them | + | local args = {}; |
| + | local suggestions = {}; |
| local error_text, error_state; | | local error_text, error_state; |
| | | |
− | local config = {}; -- table to store parameters from the module {{#invoke:}} | + | local config = {}; |
| for k, v in pairs( frame.args ) do | | for k, v in pairs( frame.args ) do |
| config[k] = v; | | config[k] = v; |
− | -- args[k] = v; -- debug tool that allows us to render a citation from module {{#invoke:}}
| + | args[k] = v; |
| end | | end |
| | | |
Sətir 3.646: |
Sətir 3.157: |
| for k, v in pairs( pframe.args ) do | | for k, v in pairs( pframe.args ) do |
| if v ~= '' then | | if v ~= '' then |
− | if ('string' == type (k)) then
| + | if not validate( k ) then |
− | k = mw.ustring.gsub (k, '%d', cfg.date_names.local_digits); -- for enumerated parameters, translate 'local' digits to Western 0-9
| |
− | end
| |
− | if not validate( k, config.CitationClass ) then | |
| error_text = ""; | | error_text = ""; |
| if type( k ) ~= 'string' then | | if type( k ) ~= 'string' then |
Sətir 3.656: |
Sətir 3.164: |
| error_text, error_state = set_error( 'text_ignored', {v}, true ); | | error_text, error_state = set_error( 'text_ignored', {v}, true ); |
| end | | end |
− | elseif validate( k:lower(), config.CitationClass ) then | + | elseif validate( k:lower() ) then |
− | error_text, error_state = set_error( 'parameter_ignored_suggest', {k, k:lower()}, true ); -- suggest the lowercase version of the parameter | + | error_text, error_state = set_error( 'parameter_ignored_suggest', {k, k:lower()}, true ); |
| else | | else |
| if nil == suggestions.suggestions then -- if this table is nil then we need to load it | | if nil == suggestions.suggestions then -- if this table is nil then we need to load it |
Sətir 3.669: |
Sətir 3.177: |
| capture = k:match (pattern); -- the whole match if no caputre in pattern else the capture if a match | | capture = k:match (pattern); -- the whole match if no caputre in pattern else the capture if a match |
| if capture then -- if the pattern matches | | if capture then -- if the pattern matches |
− | param = substitute (param, capture); -- add the capture to the suggested parameter (typically the enumerator) | + | param = substitute( param, capture ); -- add the capture to the suggested parameter (typically the enumerator) |
− | if validate (param, config.CitationClass) then -- validate the suggestion to make sure that the suggestion is supported by this template (necessary for limited parameter lists) | + | error_text, error_state = set_error( 'parameter_ignored_suggest', {k, param}, true ); -- set the error message |
− | error_text, error_state = set_error ('parameter_ignored_suggest', {k, param}, true); -- set the suggestion error message
| |
− | else
| |
− | error_text, error_state = set_error( 'parameter_ignored', {param}, true ); -- suggested param not supported by this template
| |
− | end
| |
| end | | end |
| end | | end |
Sətir 3.682: |
Sətir 3.186: |
| else | | else |
| error_text, error_state = set_error( 'parameter_ignored', {k}, true ); | | error_text, error_state = set_error( 'parameter_ignored', {k}, true ); |
− | v = ''; -- unset value assigned to unrecognized parameters (this for the limited parameter lists)
| |
| end | | end |
| end | | end |
Sətir 3.691: |
Sətir 3.194: |
| end | | end |
| missing_pipe_check (v); -- do we think that there is a parameter that is missing a pipe? | | missing_pipe_check (v); -- do we think that there is a parameter that is missing a pipe? |
− | -- TODO: is this the best place for this translation?
| + | |
| + | args[k] = v; |
| + | elseif args[k] ~= nil or (k == 'postscript') then |
| args[k] = v; | | args[k] = v; |
− | elseif args[k] ~= nil or (k == 'postscript') then -- here when v is empty string
| |
− | args[k] = v; -- why do we do this? we don't support 'empty' parameters
| |
| end | | end |
| end | | end |
Sətir 3.703: |
Sətir 3.206: |
| end | | end |
| end | | end |
− | return table.concat ({citation0( config, args), frame:extensionTag ('templatestyles', '', {src=styles})}); | + | return citation0( config, args) |
| end | | end |
| | | |
| return cs1; | | return cs1; |