imported>Vozhuo
// Edit via Wikiplus
imported>Vozhuo
// Edit via Wikiplus
第8行: 第8行:
local p = {};
local p = {};


local initial_style_state; -- set by lang_xx_normal() and lang_xx_italic()
local initial_style_state; -- set by lang_xx_inherit() and lang_xx_italic()


local getArgs = require ('Module:Arguments').getArgs;
local getArgs = require ('Module:Arguments').getArgs;
第63行: 第63行:
]]
]]


local function is_latn (text)
function p.is_latn (text)
local latn = table.concat (
local latn = table.concat (
{
{
第78行: 第78行:
'\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)
'–', -- ndash
'—', -- mdash
'«', '»', -- guillemets commonly used in several 'Latn' languages
']', -- close the set
']', -- close the set
});
});


        text = mw.text.decode (text, true); -- replace numeric and named html entities with their unicode characters
text = mw.text.decode (text, true); -- replace numeric and named html entities with their unicode characters
text = mw.ustring.gsub (text, '%[%[[^|]+|([^%]]+)%]%]', '%1'); -- remove the link and markup from complex wikilink in case interwiki to non-Latn wikipedia
text = mw.ustring.gsub (text, '%[%[[^|]+|([^%]]+)%]%]', '%1'); -- remove the link and markup from complex wikilink in case interwiki to non-Latn wikipedia
return not is_set (mw.ustring.gsub (text, latn, '')); -- replace all latn characters with empty space; if result is all empty space, text is latn
return not is_set (mw.ustring.gsub (text, latn, '')); -- replace all latn characters with empty space; if result is all empty space, text is latn
end
--[[--------------------------< I N V E R T  _ I T A L I C S >-------------------------------------------------
This function attempts to invert the italic markup a args.text by adding/removing leading/trailing italic markup
in args.text.  Like |italic=unset, |italic=invert disables automatic italic markup.  Individual leading/trailing
apostrophes are converted to their html numeric entity equivalent so that the new italic markup doesn't become
bold markup inadvertently.
Leading and trailing wiki markup is extracted from args.text into separate table elements.  Addition, removal,
replacement of wiki markup is handled by a string.gsub() replacement table operating only on these separate elements.
In the string.gsub() matching pattern, '.*' matches empty string as well as the three expected wiki markup patterns.
This function expects that markup in args.text is complete and correct; if it is not, oddness may result.
]]
local function invert_italics (source)
local invert_pattern_table = { -- leading/trailing markup add/remove/replace patterns
[""]="\'\'", -- empty string becomes italic markup
["\'\'"]="", -- italic markup becomes empty string
["\'\'\'"]="\'\'\'\'\'", -- bold becomes bold italic
["\'\'\'\'\'"]="\'\'\'", -- bold italic become bold
};
local seg = {};
source = source:gsub ("%f[\']\'%f[^\']", '&#38;'); -- protect single quote marks from being interpreted as bold markup
seg[1] = source:match ('^(\'\'+%f[^\']).+') or ''; -- get leading markup, if any; ignore single quote
seg[3] = source:match ('.+(%f[\']\'\'+)$') or ''; -- get trailing markup, if any; ignore single quote
if '' ~= seg[1] and '' ~= seg[3] then -- extract the 'text'
seg[2] = source:match ('^\'\'+%f[^\'](.+)%f[\']\'\'+$') -- from between leading and trailing markup
elseif '' ~= seg[1] then
seg[2] = source:match ('^\'\'+%f[^\'](.+)') -- following leading markup
elseif '' ~= seg[3] then
seg[2] = source:match ('(.+)%f[\']\'\'+$') -- preceding trailing markup
else
seg[2] = source -- when there is no markup
end
seg[1] = seg[1]:gsub (".*", invert_pattern_table, 1); -- replace leading markup according to pattern table
seg[3] = seg[3]:gsub (".*", invert_pattern_table, 1); -- replace leading markup according to pattern table
return table.concat (seg); -- put it all back together and done
end
end


第109行: 第158行:
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 markup inside or outside the template; returns 'inherit'
unset - disables font control so that font-style applied to text is dictated by markup inside or outside the template; returns 'inherit'
invert - disables font control so that font-style applied to text is dictated by markup outside or inverted inside the template; returns 'invert'


]]
]]


local function validate_italic (italic, italics)
local function validate_italic (italic, italics)
local properties = {['yes'] = 'italic', ['no'] = 'normal', ['unset'] = 'inherit', ['default'] = nil};
local properties = {['yes'] = 'italic', ['no'] = 'normal', ['unset'] = 'inherit', ['invert'] = 'invert', ['default'] = nil};


if italic and italics then -- return nil and an error message if both are set  
if italic and italics then -- return nil and an error message if both are set  
第241行: 第291行:
elseif source:match ('^%a%a%a?%-%d%d%d%d$') then -- ll-variant (where variant is 4 digits)
elseif source:match ('^%a%a%a?%-%d%d%d%d$') then -- ll-variant (where variant is 4 digits)
code, variant = source:match ('^(%a%a%a?)%-(%d%d%d%d)$');
code, variant = source:match ('^(%a%a%a?)%-(%d%d%d%d)$');
elseif source:match ('^%a%a%a?%-[%a%d][%a%d][%a%d][%a%d][%a%d]+$') then -- ll-variant (where variant is 5-8 alnum characters)
elseif source:match ('^%a%a%a?%-[%a%d][%a%d][%a%d][%a%d][%a%d][%a%d]?[%a%d]?[%a%d]?$') then -- ll-variant (where variant is 5-8 alnum characters)
code, variant = source:match ('^(%a%a%a?)%-([%a%d][%a%d][%a%d][%a%d][%a%d][%a%d]?[%a%d]?[%a%d]?)$');
code, variant = source:match ('^(%a%a%a?)%-([%a%d][%a%d][%a%d][%a%d][%a%d][%a%d]?[%a%d]?[%a%d]?)$');


第415行: 第465行:
]]
]]


local function make_text_span (code, text, rtl, style, size)
local function make_text_span (code, text, rtl, style, size, language)
local span = {};
local span = {};
local style_added = '';
local style_added = '';
第421行: 第471行:
if text:match ('^%*') then
if text:match ('^%*') then
table.insert (span, '&#42;'); -- move proto language text prefix outside of italic markup if any; use numeric entity because plan splat confuses MediaWiki
table.insert (span, '&#42;'); -- 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
text = text:gsub ('^%*', ''); -- remove the splat from the text
end
end


第449行: 第499行:
end
end


table.insert (span, table.concat ({style_added, '>'})); -- close the style attribute and close opening span tag
if is_set (language) then
table.insert (span, table.concat ({style_added, ' title=\"', language})); --start the title text
if language:find ('languages') then
table.insert (span, ' collective text\"'); -- for collective languages
else
table.insert (span, ' language text\"'); -- for individual languages
end
table.insert (span, '>'); -- close the opening span tag
else
table.insert (span, table.concat ({style_added, '>'})); -- close the style attribute and close opening span tag
end
table.insert (span, text); -- insert the text
table.insert (span, text); -- insert the text


第619行: 第679行:
end
end


if 'lang-xx' == template then -- for the time being, this error checking does not apply to {{lang}}
local style = args.italic or args.italics;
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
-- if ('unset' ~= args.italic) and ('unset' ~= args.italics) then -- allow italic markup when |italic=unset or |italics=unset
return make_error_msg ('text has italic markup', args, template);
if ('unset' ~= style) and ('invert' ~=style) then
end
if args.text:find ("%f[\']\'\'%f[^\']") or args.text:find ("%f[\']\'\'\'\'\'%f[^\']") then -- italic but not bold, or bold italic
return make_error_msg ('text has italic markup', args, template);
end
end
end
end
第723行: 第784行:


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
if ('latn' == subtags.script) or (is_latn (args.text) and 'en' ~= code) then -- script set to latn or text is wholly latn script but not rendering English
if ('latn' == subtags.script) or (p.is_latn (args.text) and 'en' ~= code) then -- script set to latn or text is wholly latn script but not rendering English
args.italic = 'italic'; -- DEFAULT for {{lang}} templates is upright; but if latn script set for font-style:italic
args.italic = 'italic'; -- DEFAULT for {{lang}} templates is upright; but if latn script set for font-style:italic
else
else
第748行: 第809行:
end
end


if 'invert' == args.italic then
args.text = invert_italics (args.text)
end
args.text = proto_prefix (args.text, language_name); -- prefix proto-language text with a splat
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, language_name));
table.insert (out, make_category (code, language_name, args.nocat));
table.insert (out, make_category (code, language_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
第906行: 第971行:
if 'no' == args.link then
if 'no' == args.link then
table.insert (out, language_name); -- language name without wikilink
table.insert (out, language_name); -- language name without wikilink
else
--else
table.insert (out, make_wikilink (language_name)); -- collective language name uses simple wikilink
-- 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
end
table.insert (out, ':'); -- separator
table.insert (out, ':'); -- separator
end
end


if 'invert' == args.italic then
args.text = invert_italics (args.text)
end
args.text = proto_prefix (args.text, language_name); -- prefix proto-language text with a splat
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 p.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, ', '); -- comma to separate text from translit
table.insert (out, ', '); -- comma to separate text from translit
if 'none' ~= args.label then
if 'none' ~= args.label then
第953行: 第1,026行:
table.insert (out, "&nbsp;</small>");
table.insert (out, "&nbsp;</small>");
end
end
table.insert (out, table.concat ({"'", args.translation, "'"}));
table.insert (out, table.concat ({'&#39;', args.translation, '&#39;'})); -- use html entities to avoid wiki markup confusion
end
end