模块:Lang:修订间差异
imported>TongcyDai ←建立内容为“--[=[ Lua support for the {{lang}} and {{lang-xx}} templates and replacement of various supporting templates. ]=] require('Module:No globals');…”的新页面 |
imported>Vozhuo 无编辑摘要 |
||
| 第1行: | 第1行: | ||
--[=[ | --[=[ | ||
Lua support for the {{lang}} | Lua support for the {{lang}}, {{lang-xx}}, and {{transl}} templates and replacement of various supporting templates. | ||
]=] | ]=] | ||
| 第39行: | 第39行: | ||
For the purposes of this function, Latn script is characters less control characters from these Unicode 10.0 Character Code Charts: | For the purposes of this function, Latn script is characters less control characters from these Unicode 10.0 Character Code Charts: | ||
[http://www.unicode.org/charts/PDF/U0000.pdf C0 Controls and Basic Latin] U+0020–U+007E (20 - 7E) | [http://www.unicode.org/charts/PDF/U0000.pdf C0 Controls and Basic Latin] U+0020–U+007E (20 - 7E) + see note about <poem>...</poem> support | ||
[http://www.unicode.org/charts/PDF/U0080.pdf C1 Controls and Latin-1 Supplement] U+00A0-U+00AC, U+00C0–U+00FF (C2 A0 - C2 AC, C3 80 - C3 BF: \194\160-\194\172) | [http://www.unicode.org/charts/PDF/U0080.pdf C1 Controls and Latin-1 Supplement] U+00A0-U+00AC, U+00C0–U+00FF (C2 A0 - C2 AC, C3 80 - C3 BF: \194\160-\194\172) | ||
[http://www.unicode.org/charts/PDF/U0100.pdf Latin Extended-A] U+0100–U+017F (C4 80 - C5 BF) | [http://www.unicode.org/charts/PDF/U0100.pdf Latin Extended-A] U+0100–U+017F (C4 80 - C5 BF) | ||
| 第54行: | 第54行: | ||
[http://www.unicode.org/charts/PDF/U0250.pdf IPA Extensions] U+0250-U+02AF (C9 90 - CA AF) | [http://www.unicode.org/charts/PDF/U0250.pdf IPA Extensions] U+0250-U+02AF (C9 90 - CA AF) | ||
[http://www.unicode.org/charts/PDF/U1D80.pdf Phonetic Extensions Supplement] U+1D80-U+1DBF (E1 B6 80 - E1 B6 BF) | [http://www.unicode.org/charts/PDF/U1D80.pdf Phonetic Extensions Supplement] U+1D80-U+1DBF (E1 B6 80 - E1 B6 BF) | ||
{{lang}} is used inside <poem>...</poem> tags for song lyrics, poetry, etc. <poem>...</poem> replaces newlines with | |||
poem stripmarkers. These have the form: | |||
?'"`UNIQ--poem-67--QINU`"'? | |||
where the '?' character is actually the delete character (U+007F, \127). Including the '\n' (U+0010) and 'del' (U+007F) | |||
characters in the latn character table allows {{lang}} to auto-italicize text within <poem>...</poem> tags. | |||
]] | ]] | ||
| 第61行: | 第67行: | ||
{ | { | ||
'[', -- this is a set so include opening bracket | '[', -- this is a set so include opening bracket | ||
'\32-\ | '\n\32-\127', -- C0 Controls and Basic Latin U+0020–U+007E (20 - 7E) + (U+0010 and U+007F <poem>...</poem> support) | ||
'\194\160-\194\172', -- C1 Controls and Latin-1 Supplement U+00A0-U+00AC (C2 A0 - C2 AC) | '\194\160-\194\172', -- C1 Controls and Latin-1 Supplement U+00A0-U+00AC (C2 A0 - C2 AC) | ||
'\195\128-\195\191', -- (skip shy) U+00C0–U+00FF (C3 80 - C3 BF) | '\195\128-\195\191', -- (skip shy) U+00C0–U+00FF (C3 80 - C3 BF) | ||
| 第71行: | 第77行: | ||
'\234\172\176-\234\173\175', -- Latin Extended-E U+AB30-U+AB6F (EA AC B0 - EA AD AF) | '\234\172\176-\234\173\175', -- Latin Extended-E U+AB30-U+AB6F (EA AC B0 - EA AD AF) | ||
'\239\172\128-\239\172\134', -- Alphabetic Presentaion Forms U+FB00-U+FB06 (EF AC 80 - EF AC 86) | '\239\172\128-\239\172\134', -- Alphabetic Presentaion Forms U+FB00-U+FB06 (EF AC 80 - EF AC 86) | ||
'\239\188\129-\239\188\188', -- Halfwidth and Fullwidth Forms U+FF01-U+FF3C (EF BC 81 EF BC BC) | '\239\188\129-\239\188\188', -- Halfwidth and Fullwidth Forms U+FF01-U+FF3C (EF BC 81 - EF BC BC) | ||
']', -- close the set | ']', -- close the set | ||
}); | }); | ||
| 第82行: | 第88行: | ||
--[[--------------------------< V A L I D A T E _ I T A L I C >------------------------------------------------ | --[[--------------------------< V A L I D A T E _ I T A L I C >------------------------------------------------ | ||
validates |italic= assigned values. | validates |italic= or |italics= assigned values. | ||
When |italic= is set and has an acceptible assigned value, return the matching css font-style property value or, | When |italic= is set and has an acceptible assigned value, return the matching css font-style property value or, | ||
for the special case 'default', return nil. | for the special case 'default', return nil. | ||
When |italic= is not set, or has an unacceptible assigned value, return nil. | When |italic= is not set, or has an unacceptible assigned value, return nil and a nil error message. | ||
When both |italic= and |italics= are set, returns nil and a 'conflicting' error message. | |||
The return value nil causes the calling lang or | The return value nil causes the calling lang, lang_xx, or transl function to set args.italic according to the template's | ||
defined default ('inherit' for {{lang}}, 'inherit' or 'italic' for {{lang-xx}} depending on | |||
the individual template's requirements) or to the value appropriate to |script=, if set. | the individual template's requirements, 'italic' for {{transl}}) or to the value appropriate to |script=, if set ({{lang}} | ||
and {{lang-xx}} only). | |||
Accepted values and the values that this function returns are are: | Accepted values and the values that this function returns are are: | ||
nil - when |italic= absent or not set; returns nil | nil - when |italic= absent or not set; returns nil | ||
default - for completeness, should rarely if ever be used; returns nil | default - for completeness, should rarely if ever be used; returns nil | ||
yes - force args.text to be rendered in italic font; returns 'italic' | yes - force args.text to be rendered in italic font; returns 'italic' | ||
no - force args.text to be rendered in normal font; returns 'normal' | no - force args.text to be rendered in normal font; returns 'normal' | ||
unset - disables font control so that font-style applied to text is dictated by | unset - disables font control so that font-style applied to text is dictated by markup inside or outside the template; returns 'inherit' | ||
]] | ]] | ||
local function validate_italic (italic) | local function validate_italic (italic, italics) | ||
local properties = {['yes'] = 'italic', ['no'] = 'normal', ['unset'] = 'inherit', ['default'] = nil}; | local properties = {['yes'] = 'italic', ['no'] = 'normal', ['unset'] = 'inherit', ['default'] = nil}; | ||
return properties[italic]; | if italic and italics then -- return nil and an error message if both are set | ||
return nil, 'conflicting: |italic= and |italics='; | |||
end | |||
return properties[italic or italics], nil; -- return an appropriate value and a nil error message | |||
end | end | ||
| 第222行: | 第235行: | ||
elseif source:match ('^%a%a%a?%-%a%a%-[%a%d][%a%d][%a%d][%a%d][%a%d]+$') then -- ll-RR-variant (where variant is 5-8 alnum characters) | elseif source:match ('^%a%a%a?%-%a%a%-[%a%d][%a%d][%a%d][%a%d][%a%d]+$') then -- ll-RR-variant (where variant is 5-8 alnum characters) | ||
code, region, variant = source:match ('^(%a%a%a?)%-(%a%a)%-([%a%d][%a%d][%a%d][%a%d][%a%d][%a%d]?[%a%d]?[%a%d]?)$'); | code, region, variant = source:match ('^(%a%a%a?)%-(%a%a)%-([%a%d][%a%d][%a%d][%a%d][%a%d][%a%d]?[%a%d]?[%a%d]?)$'); | ||
elseif source:match ('^%a%a%a?%-%d%d%d%-[%a%d][%a%d][%a%d][%a%d][%a%d]+$') then -- ll-DDD-variant (where region is 3 digits; variant is | elseif source:match ('^%a%a%a?%-%d%d%d%-[%a%d][%a%d][%a%d][%a%d][%a%d]+$') then -- ll-DDD-variant (where region is 3 digits; variant is 5-8 alnum characters) | ||
code, region, variant = source:match ('^(%a%a%a?)%-(%d%d%d)%-([%a%d][%a%d][%a%d][%a%d][%a%d][%a%d]?[%a%d]?[%a%d]?)$'); | code, region, variant = source:match ('^(%a%a%a?)%-(%d%d%d)%-([%a%d][%a%d][%a%d][%a%d][%a%d][%a%d]?[%a%d]?[%a%d]?)$'); | ||
| 第267行: | 第280行: | ||
if is_set (script) then | if is_set (script) then | ||
if is_set (args_script) then | if is_set (args_script) then | ||
return code, nil, nil, nil, nil, 'redundant script tag'; | return code, nil, nil, nil, nil, 'redundant script tag'; -- both code with script and |script= not allowed | ||
end | end | ||
else | else | ||
| 第302行: | 第315行: | ||
if is_set (variant) then | if is_set (variant) then | ||
if is_set (args_variant) then | if is_set (args_variant) then | ||
return code, nil, nil, nil, nil, 'redundant variant tag'; | return code, nil, nil, nil, nil, 'redundant variant tag'; -- both code with variant and |variant= not allowed | ||
end | end | ||
else | else | ||
| 第336行: | 第349行: | ||
--[[--------------------------< M A K E _ E R R O R _ M S G >-------------------------------------------------- | --[[--------------------------< M A K E _ E R R O R _ M S G >-------------------------------------------------- | ||
assembles an error message from message text, | assembles an error message from template name, message text, help link, and error category. | ||
]] | ]] | ||
local function make_error_msg (msg, args) | local function make_error_msg (msg, args, template) | ||
local out = {}; | local out = {}; | ||
local category; | |||
if 'transl' == template then | |||
category = 'transl'; | |||
else | |||
category = 'lang and lang-xx' | |||
end | |||
table.insert (out, table.concat ({'[', args.text or 'undefined', '] '})); -- for error messages output args.text if available | table.insert (out, table.concat ({'[', args.text or 'undefined', '] '})); -- for error messages output args.text if available | ||
table.insert (out, '<span style="font-size:100%" class="error">error: '); | table.insert (out, table.concat ({'<span style=\"font-size:100%; font-style:normal;\" class=\"error\">error: {{', template, '}}: '})); | ||
table.insert (out, msg); | table.insert (out, msg); | ||
table.insert (out, ' ([[:Category: | table.insert (out, table.concat ({' ([[:Category:', category, ' template errors|help]])'})); | ||
table.insert (out, '</span>'); | table.insert (out, '</span>'); | ||
if (0 == namespace) and not is_set (args.nocat) then -- only categorize in article space | if (0 == namespace) and not is_set (args.nocat) then -- only categorize in article space | ||
table.insert (out, '[[Category: | table.insert (out, table.concat ({'[[Category:', category, ' template errors]]'})); | ||
end | end | ||
| 第396行: | 第417行: | ||
local span = {}; | local span = {}; | ||
local style_added = ''; | local style_added = ''; | ||
if text:match ('^%*') then | |||
table.insert (span, '*'); -- move proto language text prefix outside of italic markup if any; use numeric entity because plan splat confuses MediaWiki | |||
text = text:gsub ('^%*', ''); -- remove the spat from the text | |||
end | |||
if 'italic' == style then | if 'italic' == style then | ||
| 第414行: | 第440行: | ||
if is_set (size) then -- when |size=<something> | if is_set (size) then -- when |size=<something> | ||
if style_added then | if is_set (style_added) then | ||
table.insert (span, table.concat ({' font-size:', size, ';'})); -- add when style attribute already inserted | table.insert (span, table.concat ({' font-size:', size, ';'})); -- add when style attribute already inserted | ||
else | else | ||
| 第438行: | 第464行: | ||
--[[ | --[=[-------------------------< M A K E _ C A T E G O R Y >---------------------------------------------------- | ||
For individual language, <language>, returns: | |||
[[Category:Articles containing <language>-language text]] | |||
for English: | |||
[[Category:Articles containing explicitly cited English-language text]] | |||
for artificial languages (code: art) | |||
[[Category:Articles containing constructed-language text]] | |||
]] | for ISO 639-2 collective languages (and for 639-1 bh): | ||
[[Category:Articles with text from the <language> languages collective]] | |||
]=] | |||
local function make_category (code, language_name, nocat) | local function make_category (code, language_name, nocat) | ||
| 第452行: | 第487行: | ||
end | end | ||
if language_name:find ('languages') then | |||
return table.concat ({'[[Category:Articles with text from the ', language_name, ' collective]]'}); | |||
end | |||
table.insert (cat, '[[Category:Articles containing '); | table.insert (cat, '[[Category:Articles containing '); | ||
if | if 'en' == code then | ||
table.insert (cat, 'explicitly cited English'); | table.insert (cat, 'explicitly cited English'); | ||
elseif 'art' == code then | elseif 'art' == code then | ||
| 第478行: | 第517行: | ||
To avoid confusion, in this module and the templates that use it, the transliteration script parameter is renamed | To avoid confusion, in this module and the templates that use it, the transliteration script parameter is renamed | ||
to be |translit-script= (in this function, tscript) | to be |translit-script= (in this function, tscript) | ||
This function is used by both lang_xx() and transl() | |||
lang_xx() always provides code, language_name, and translit; may provide tscript; never provides style | |||
transl() always provides language_name, translit, and one of code or tscript, never both; always provides style | |||
For {{transl}}, style only applies when a language code is provided | |||
]] | ]] | ||
local function make_translit (code, language_name, translit, std, tscript) | local function make_translit (code, language_name, translit, std, tscript, style) | ||
local title; | local title; | ||
local tout = {}; | local tout = {}; | ||
local title_table = lang_data.translit_title_table; -- table of transliteration standards and the language codes and scripts that apply to those standards | local title_table = lang_data.translit_title_table; -- table of transliteration standards and the language codes and scripts that apply to those standards | ||
table.insert (tout, "<i lang=\""); | if is_set (code) then -- when a language code is provided (always with {{lang-xx}} templates, not always with {{transl}}) | ||
if not style then -- nil for is the default italic style | |||
table.insert (tout, "<i lang=\""); -- so use <i> tag | |||
else | |||
table.insert (tout, table.concat ({'<span style=\"font-style:', style, '\" lang=\"'})); -- non-standard style, construct a span tag for it | |||
end | |||
table.insert (tout, code); | |||
table.insert (tout, "-Latn\" title=\""); -- transliterations are always Latin script | |||
else | |||
table.insert (tout, "<span title=\""); -- when no language code: no lang= attribute, not italic ({{transl}} only) | |||
end | |||
std = std and std:lower(); -- lower case for table indexing | |||
if not is_set (std) and not is_set (tscript) then -- when neither standard nor script specified | if not is_set (std) and not is_set (tscript) then -- when neither standard nor script specified | ||
table.insert (tout, language_name); -- write a generic tool tip | table.insert (tout, language_name); -- write a generic tool tip | ||
table.insert (tout, ' transliteration'); | if not language_name:find ('languages') then -- collective language names (plural 'languages' is part of the name) | ||
table.insert (tout, '-language') -- skip this text (individual and macro languages only) | |||
end | |||
table.insert (tout, ' transliteration'); -- finish the tool tip | |||
elseif is_set (std) and is_set (tscript) then -- when both are specified | elseif is_set (std) and is_set (tscript) then -- when both are specified | ||
if title_table[std][tscript] then | if title_table[std] then -- and if standard is legitimate | ||
if title_table[std][tscript] then -- and if script for that standard is legitimate | |||
table.insert (tout, table.concat ({title_table[std][tscript:lower()], ' (', lang_name_table.script[tscript][1], ' script) transliteration'})); -- add the appropriate text to the tool tip | |||
else | |||
table.insert (tout, title_table[std]['default']); -- use the default if script not in std table; TODO: maint cat? error message because script not found for this standard? | |||
end | |||
else | else | ||
return ''; -- | return ''; -- invalid standard, setup for error message | ||
end | end | ||
elseif is_set (std) then -- translit-script not set, use language code | elseif is_set (std) then -- translit-script not set, use language code | ||
if not title_table[std] then return ''; end -- invalid standard, | if not title_table[std] then return ''; end -- invalid standard, setup for error message | ||
if title_table[std][code] then | if title_table[std][code] then -- if language code is in the table (transl may not provide a language code) | ||
table.insert (tout, title_table[std][code]); | table.insert (tout, table.concat ({title_table[std][code:lower()], ' (', lang_name_table.lang[code][1], ' language) transliteration'})); -- add the appropriate text to the tool tip | ||
else -- code doesn't match | else -- code doesn't match | ||
table.insert (tout, title_table[std]['default']); -- so use the standard's default | table.insert (tout, title_table[std]['default']); -- so use the standard's default | ||
end | end | ||
else -- here if translit-script set but translit-std not set | else -- here if translit-script set but translit-std not set | ||
if title_table[' | if title_table['no_std'][tscript] then | ||
table.insert (tout, title_table[' | table.insert (tout, title_table['no_std'][tscript]); -- use translit-script if set | ||
elseif title_table[' | elseif title_table['no_std'][code] then | ||
table.insert (tout, title_table[' | table.insert (tout, title_table['no_std'][code]); -- use language code | ||
else | else | ||
table.insert (tout, language_name); | if is_set (tscript) then | ||
table.insert (tout, ' transliteration'); | table.insert (tout, table.concat ({language_name, '-script transliteration'})); -- write a script tool tip | ||
elseif is_set (code) then | |||
if not language_name:find ('languages') then -- collective language names (plural 'languages' is part of the name) | |||
table.insert (tout, '-language') -- skip this text (individual and macro languages only) | |||
end | |||
table.insert (tout, ' transliteration'); -- finish the tool tip | |||
else | |||
table.insert (tout, ' transliteration'); -- generic tool tip (can we ever get here?) | |||
end | |||
end | end | ||
end | end | ||
| 第519行: | 第590行: | ||
table.insert (tout, '">'); | table.insert (tout, '">'); | ||
table.insert (tout, translit); | table.insert (tout, translit); | ||
table.insert (tout, "</i>"); | if is_set (code) and not style then -- when a language code is provided (always with {{lang-xx}} templates, not always with {{transl}}) | ||
table.insert (tout, "</i>"); -- close the italic tag | |||
else | |||
table.insert (tout, "</span>"); -- no language code so close the span tag | |||
end | |||
return table.concat (tout); | return table.concat (tout); | ||
end | end | ||
--[[ | --[=[-------------------------< V A L I D A T E _ T E X T >--------------------------------------------------- | ||
This function checks the content of args.text and returns empty string if nothing is amiss else it returns an | This function checks the content of args.text and returns empty string if nothing is amiss else it returns an | ||
| 第532行: | 第607行: | ||
either as ''itself''' or as '''''bold italic'''''. | either as ''itself''' or as '''''bold italic'''''. | ||
]=] | |||
]] | |||
local function validate_text (template, args) | local function validate_text (template, args) | ||
if not is_set (args.text) then | if not is_set (args.text) then | ||
return make_error_msg ( | return make_error_msg ('no text', args, template); | ||
end | |||
if args.text:find ("%f[\']\'\'\'\'%f[^\']") or args.text:find ("\'\'\'\'\'[\']+") then -- because we're looking, look for 4 appostrophes or 6+ appostrophes | |||
return make_error_msg ('text has malformed markup', args, template); | |||
end | end | ||
if 'lang-xx' == template then -- for the time being, this error checking does not apply to {{lang}} | if 'lang-xx' == template then -- for the time being, this error checking does not apply to {{lang}} | ||
if args. | if ('unset' ~= args.italic) and ('unset' ~= args.italics) then -- allow italic markup when |italic=unset or |italics=unset | ||
if args.text:match ("%f[\']\'\'[^\']+\'\'%f[^\']") or args.text:match ("\'\'\'\'\'[^\']+\'\'\'\'\'") then -- italic but not bold, or bold italic | |||
return make_error_msg ('text has italic markup', args, template); | |||
end | |||
end | end | ||
end | end | ||
| 第587行: | 第657行: | ||
--[[--------------------------< P R O T O _ P R E F I X >------------------------------------------------------ | --[[--------------------------< P R O T O _ P R E F I X >------------------------------------------------------ | ||
for proto languages, text is prefixed with a splat. We do that here. | for proto languages, text is prefixed with a splat. We do that here as a flag for make_text_span() so that a splat | ||
will be rendered outside of italic markup (if used). If the first character in text here is already a splat, we | |||
do nothing | |||
]] | ]] | ||
local function proto_prefix (text, language_name) | local function proto_prefix (text, language_name) | ||
if language_name:find ('^Proto%-') then | if language_name:find ('^Proto%-') and not text:find ('^*') then -- language is a proto and text does not already have leading splat | ||
return table.concat ({'*', text}); -- prefix proto language text with a splat | return table.concat ({'*', text}); -- prefix proto language text with a splat | ||
end | end | ||
| 第619行: | 第692行: | ||
if args[1] and args.code then | if args[1] and args.code then | ||
return make_error_msg (' | return make_error_msg ('conflicting: {{{1}}} and |code=', args, 'lang'); | ||
else | else | ||
args.code = args[1] or args.code; -- prefer args.code | args.code = args[1] or args.code; -- prefer args.code | ||
| 第625行: | 第698行: | ||
if args[2] and args.text then | if args[2] and args.text then | ||
return make_error_msg (' | return make_error_msg ('conflicting: {{{2}}} and |text=', args, 'lang'); | ||
else | else | ||
args.text = args[2] or args.text; -- prefer args.text | args.text = args[2] or args.text; -- prefer args.text | ||
| 第640行: | 第713行: | ||
if msg then | if msg then | ||
return make_error_msg ( | return make_error_msg ( msg, args, 'lang'); | ||
end | end | ||
args.italic = validate_italic (args.italic); | args.italic, msg = validate_italic (args.italic, args.italics); | ||
if msg then | |||
return make_error_msg (msg, args, 'lang'); | |||
end | |||
if nil == args.italic then -- nil when |italic= absent or not set or |italic=default; args.italic controls | if nil == args.italic then -- nil when |italic= absent or not set or |italic=default; args.italic controls | ||
| 第671行: | 第747行: | ||
end | end | ||
args.text = proto_prefix (args.text, language_name); | args.text = proto_prefix (args.text, language_name); -- prefix proto-language text with a splat | ||
table.insert (out, make_text_span (args.code, args.text, args.rtl, args.italic, args.size)); | table.insert (out, make_text_span (args.code, args.text, args.rtl, args.italic, args.size)); | ||
| 第678行: | 第754行: | ||
return table.concat (out); -- put it all together and done | return table.concat (out); -- put it all together and done | ||
end | |||
| 第691行: | 第767行: | ||
For normal, upright style: | For normal, upright style: | ||
<includeonly>{{#invoke:lang| | <includeonly>{{#invoke:lang|lang_xx_inherit|code=xx}}</includeonly> | ||
For italic style: | For italic style: | ||
<includeonly>{{#invoke:lang|lang_xx_italic|code=xx}}</includeonly> | <includeonly>{{#invoke:lang|lang_xx_italic|code=xx}}</includeonly> | ||
| 第708行: | 第784行: | ||
|italic = boolean true ('yes') renders displayed text in italic font; boolean false ('no') renders displayed text in normal font; not set renders according to initial_style_state | |italic = boolean true ('yes') renders displayed text in italic font; boolean false ('no') renders displayed text in normal font; not set renders according to initial_style_state | ||
|lit = text that is a literal translation of text | |lit = text that is a literal translation of text | ||
|label = 'none' to suppress all labeling (language name, 'translit.', 'lit.') | |||
any other text replaces language-name label - automatic wikilinking disabled | |||
for those {{lang-xx}} templates that support transliteration: | for those {{lang-xx}} templates that support transliteration (those template where |text= is entirely latn script): | ||
|translit = text that is a transliteration of text | |translit = text that is a transliteration of text | ||
|translit-std = the standard that applies to the transliteration | |translit-std = the standard that applies to the transliteration | ||
| 第725行: | 第803行: | ||
local args = getArgs(frame, {parentFirst= true}); -- parameters in the template override parameters set in the {{#invoke:}} | local args = getArgs(frame, {parentFirst= true}); -- parameters in the template override parameters set in the {{#invoke:}} | ||
local out = {}; | local out = {}; | ||
local language_name; -- used to make display text, article links | local language_name; -- used to make display text, article links | ||
local category_name; -- same as language_name except that it retains any parenthetical disambiguators (if any) from the data set | |||
local subtags = {}; -- IETF subtags script, region, and variant | local subtags = {}; -- IETF subtags script, region, and variant | ||
local code; -- the language code | local code; -- the language code | ||
| 第735行: | 第814行: | ||
if args[1] and args.text then | if args[1] and args.text then | ||
return make_error_msg (' | return make_error_msg ('conflicting: {{{1}}} and |text=', args, 'lang-xx'); | ||
else | else | ||
args.text = args[1] or args.text; -- prefer args.text | args.text = args[1] or args.text; -- prefer args.text | ||
| 第746行: | 第825行: | ||
if args[2] and args.translit then | if args[2] and args.translit then | ||
return make_error_msg (' | return make_error_msg ('conflicting: {{{2}}} and |translit=', args, 'lang-xx'); | ||
else | else | ||
args.translit = args[2] or args.translit -- prefer args.translit | args.translit = args[2] or args.translit -- prefer args.translit | ||
| 第752行: | 第831行: | ||
if args[3] and (args.translation or args.lit) then | if args[3] and (args.translation or args.lit) then | ||
return make_error_msg (' | return make_error_msg ('conflicting: {{{3}}} and |lit= or |translation=', args, 'lang-xx'); | ||
elseif args.translation and args.lit then | elseif args.translation and args.lit then | ||
return make_error_msg (' | return make_error_msg ('conflicting: |lit= and |translation=', args, 'lang-xx'); | ||
else | else | ||
args.translation = args[3] or args.translation or args.lit; -- prefer args.translation | args.translation = args[3] or args.translation or args.lit; -- prefer args.translation | ||
| 第760行: | 第839行: | ||
if args.links and args.link then | if args.links and args.link then | ||
return make_error_msg (' | return make_error_msg ('conflicting: |links= and |link=', args, 'lang-xx'); | ||
else | else | ||
args.link = args.link or args.links; -- prefer args.link | args.link = args.link or args.links; -- prefer args.link | ||
| 第770行: | 第849行: | ||
if msg then -- if an error detected then there is an error message | if msg then -- if an error detected then there is an error message | ||
return make_error_msg ( | return make_error_msg (msg, args, 'lang-xx'); | ||
end | end | ||
args.italic = validate_italic (args.italic); | args.italic, msg = validate_italic (args.italic, args.italics); | ||
if msg then | |||
return make_error_msg (msg, args, 'lang-xx'); | |||
end | |||
if nil == args.italic then -- args.italic controls | if nil == args.italic then -- args.italic controls | ||
| 第813行: | 第895行: | ||
end | end | ||
if ' | category_name = language_name; -- category names retain IANA parenthetical diambiguators (if any) | ||
language_name = language_name:gsub ('%s+%b()', ''); -- remove IANA parenthetical disambiguators or qualifiers from names that have them | |||
if args.label then | |||
if 'none' ~= args.label then | |||
table.insert (out, table.concat ({args.label, ': '})); -- custom label | |||
end | |||
else | else | ||
table.insert (out, make_wikilink (language_name .. ' language', language_name)); -- language name with wikilink | if 'no' == args.link then | ||
table.insert (out, language_name); -- language name without wikilink | |||
else | |||
if language_name:find ('languages') then | |||
table.insert (out, make_wikilink (language_name)); -- collective language name uses simple wikilink | |||
else | |||
table.insert (out, make_wikilink (language_name .. ' language', language_name)); -- language name with wikilink | |||
end | |||
end | |||
table.insert (out, ': '); -- separator | |||
end | end | ||
args.text = proto_prefix (args.text, language_name); | args.text = proto_prefix (args.text, language_name); -- prefix proto-language text with a splat | ||
table.insert (out, make_text_span (args.code, args.text, args.rtl, args.italic, args.size)) | table.insert (out, make_text_span (args.code, args.text, args.rtl, args.italic, args.size)) | ||
if is_set (args.translit) and not is_latn (args.text) then -- transliteration (not supported in {{lang}}); not supported when args.text is wholly latn text (this is an imperfect test) | if is_set (args.translit) and not is_latn (args.text) then -- transliteration (not supported in {{lang}}); not supported when args.text is wholly latn text (this is an imperfect test) | ||
table.insert (out, ', <small>'); | table.insert (out, ', '); -- comma to separate text from translit | ||
if 'none' ~= args.label then | |||
table.insert (out, '<small>'); | |||
if lang_name_table.script[args['translit-script']] then -- when |translit-script= is set, try to use the script's name | |||
translit_script_name = lang_name_table.script[args['translit-script'][1]]; | |||
else | |||
translit_script_name = language_name; -- fall back on language name | |||
end | |||
translit_title = mw.title.makeTitle (0, table.concat ({'Romanization of ', translit_script_name})); -- make a title object | |||
if translit_title.exists and ('no' ~= args.link) then | |||
table.insert (out, make_wikilink ('Romanization of ' .. translit_script_name or language_name, 'translit.')); -- make a wikilink if there is an article to link to | |||
else | |||
table.insert (out, '<abbr title="transliteration">translit.</abbr>'); -- else define the abbreviation | |||
end | |||
table.insert (out, ' </small>'); -- close the small tag | |||
end | end | ||
translit = make_translit (args.code, language_name, args.translit, args['translit-std'], args['translit-script']) | translit = make_translit (args.code, language_name, args.translit, args['translit-std'], args['translit-script']) | ||
if is_set (translit) then | if is_set (translit) then | ||
table.insert (out, translit); | table.insert (out, translit); | ||
else | else | ||
return make_error_msg (table.concat ({' | return make_error_msg (table.concat ({'invalid translit-std: \'', args['translit-std'] or '[missing]'}), args, 'lang-xx'); | ||
end | end | ||
end | end | ||
if is_set (args.translation) then -- translation (not supported in {{lang}}) | if is_set (args.translation) then -- translation (not supported in {{lang}}) | ||
table.insert (out, ', <small>'); | table.insert (out, ', '); | ||
if 'none' ~= args.label then | |||
table.insert (out, '<small>'); | |||
if 'no' == args.link then | |||
table.insert (out, '<abbr title="literal translation">lit.</abbr>'); | |||
else | |||
table.insert (out, make_wikilink ('Literal translation', 'lit.')); | |||
end | |||
table.insert (out, " </small>"); | |||
end | end | ||
table.insert (out, " | table.insert (out, table.concat ({"'", args.translation, "'"})); | ||
end | end | ||
table.insert (out, make_category (code, | table.insert (out, make_category (code, category_name, args.nocat)); | ||
table.insert (out, render_maint(args.nocat)); -- maintenance messages and categories | table.insert (out, render_maint(args.nocat)); -- maintenance messages and categories | ||
| 第863行: | 第968行: | ||
--[[--------------------------< L A N G _ X X _ I T A L I C >-------------------------------------------------- | --[[--------------------------< L A N G _ X X _ I T A L I C >-------------------------------------------------- | ||
Entry point for those {{lang-xx}} templates that | Entry point for those {{lang-xx}} templates that call lang_xx_italic(). Sets the initial style state to italic. | ||
style state to italic. | |||
]] | ]] | ||
| 第876行: | 第980行: | ||
--[[--------------------------< L A N G _ X X _ I N H E R I T >------------------------------------------------ | --[[--------------------------< L A N G _ X X _ I N H E R I T >------------------------------------------------ | ||
Entry point for those {{lang-xx}} templates that | Entry point for those {{lang-xx}} templates that call lang_xx_inherit(). Sets the initial style state to inherit. | ||
style state to inherit. | |||
]] | ]] | ||
| 第920行: | 第1,023行: | ||
end | end | ||
end | end | ||
language_name = language_name:gsub ('%s+%b()', ''); -- remove IANA parenthetical disambiguators or qualifiers from names that have them | |||
return language_name; | return language_name; | ||
end | |||
--[[--------------------------< T R A N S L >------------------------------------------------------------------ | |||
Prospective replacement for the template {{transl}} | |||
]] | |||
function p.transl (frame) | |||
local args = getArgs(frame); -- no {{#invoke:}} parameters | |||
local title_table = lang_data.translit_title_table; -- table of transliteration standards and the language codes and scripts that apply to those standards | |||
local language_name; -- language name that matches language code; used for tool tip | |||
local translit; -- translitterated text to display | |||
local script; -- IANA script | |||
local msg; -- for when called functions return an error message | |||
if is_set (args[3]) then -- [3] set when {{transl|code|standard|text}} | |||
args.text = args[3]; -- get the transliterated text | |||
args.translit_std = args[2] and args[2]:lower(); -- get the standard; lower case for table indexing | |||
if not title_table[args.translit_std] then | |||
return make_error_msg (table.concat ({'unrecognized transliteration standard: ', args.translit_std}), args, 'transl'); | |||
end | |||
else | |||
if is_set (args[2]) then -- [2] set when {{transl|code|text}} | |||
args.text = args[2]; -- get the transliterated text | |||
else | |||
if args[1] and args[1]:match ('^%a%a%a?%a?$') then -- args[2] missing; is args[1] a code or its it the transliterated text? | |||
return make_error_msg ('no text', args, 'transl'); -- args[1] is a code so we're missing text | |||
else | |||
args.text = args[1]; -- args[1] is not a code so we're missing that; assign args.text for error message | |||
return make_error_msg ('missing language / script code', args, 'transl'); | |||
end | |||
end | |||
end | |||
if is_set (args[1]) then -- IANA language code used for html lang= attribute; or ISO 15924 script code | |||
if args[1]:match ('^%a%a%a?%a?$') then -- args[1] has correct form? | |||
args.code = args[1]:lower(); -- use the language/script code; only (2, 3, or 4 alpha characters); lower case because table indexes are lower case | |||
else | |||
return make_error_msg (table.concat ({'unrecognized language / script code: ', args[1]}), args, 'transl'); -- invalid language / script code | |||
end | |||
else | |||
return make_error_msg ('missing language / script code', args, 'transl'); -- missing language / script code so quit | |||
end | |||
args.italic, msg = validate_italic (args.italic, args.italics); | |||
if msg then | |||
return make_error_msg (msg, args, 'transl'); | |||
end | |||
if 'italic' == args.italic then -- 'italic' when |italic=yes; because that is same as absent or not set and |italic=default | |||
args.italic = nil; -- set to nil; | |||
end | |||
if lang_data.override[args.code] then -- is code a language code defined in the override table? | |||
language_name = lang_data.override[args.code][1]; | |||
elseif lang_name_table.lang[args.code] then -- is code a language code defined in the standard language code tables? | |||
language_name = lang_name_table.lang[args.code][1]; | |||
elseif lang_name_table.script[args.code] then -- if here, code is not a language code; is it a script code? | |||
language_name = lang_name_table.script[args.code][1]; | |||
script = args.code; -- code was an ISO 15924 script so use that instead | |||
args.code = ''; -- unset because not a language code | |||
else | |||
return make_error_msg (table.concat ({'unrecognized language / script code: ', args.code}), args, 'transl'); -- invalid language / script code | |||
end | |||
-- here only when all parameters passed to make_translit() are valid | |||
return make_translit (args.code, language_name, args.text, args.translit_std, script, args.italic); | |||
end | end | ||
return p; | return p; | ||