Nicht angemeldeter Benutzer - Bearbeiten von Seiten ist nur als angemeldeter Benutzer möglich.

Modul:Vorlage:lang: Unterschied zwischen den Versionen

Aus imedwiki
Zur Navigation springen Zur Suche springen
(2018-12-13)
(2018-12-15)
Zeile 1: Zeile 1:
local Export = { serial = "2018-12-13",
+
local Export = { serial = "2018-12-15",
 
                 suite  = "lang",
 
                 suite  = "lang",
 
                 item  = 26826825 }
 
                 item  = 26826825 }
Zeile 20: Zeile 20:
 
   errMissing    = { en = "Missing parameter",
 
   errMissing    = { en = "Missing parameter",
 
                       de = "Parameter fehlt" },
 
                       de = "Parameter fehlt" },
   errSuggest    = { en = "%s * probably %s intended",
+
   errSuggest    = { en = "'%s' * probably '%s' intended",
                       de = "%s * vermutlich ist %s gemeint" },
+
                       de = "'%s' * vermutlich ist '%s' gemeint" },
 
   errUnkown      = { en = "Unkown parameter:",
 
   errUnkown      = { en = "Unkown parameter:",
 
                       de = "Parameter unbekannt:" },
 
                       de = "Parameter unbekannt:" },
Zeile 33: Zeile 33:
 
                       "nachgestellt",
 
                       "nachgestellt",
 
                       "demo",
 
                       "demo",
 +
                      "demo2",
 +
                      "demo3",
 +
                      "demo4",
 
                       "NoCat" },
 
                       "NoCat" },
 
   percents      = false,
 
   percents      = false,
Zeile 42: Zeile 45:
 
   scripts        = "Multilingual/scripts",
 
   scripts        = "Multilingual/scripts",
 
   sepComma      = "Latn Cyrl Grek Thai",
 
   sepComma      = "Latn Cyrl Grek Thai",
 +
  site          = "Latn",
 
   tmplAudio      = false,    -- template for media player link
 
   tmplAudio      = false,    -- template for media player link
 
   tmplLang      = false,    -- template for language name link
 
   tmplLang      = false,    -- template for language name link
Zeile 270: Zeile 274:
 
     --    assign  -- string, with text
 
     --    assign  -- string, with text
 
     -- Returns string, with applied text
 
     -- Returns string, with applied text
 +
    -- Throws error, if template not existing
 
     local template = Config[ access ]
 
     local template = Config[ access ]
 
     local r        = apply
 
     local r        = apply
Zeile 291: Zeile 296:
  
  
local function first( apply, assign )
+
local function first( assign, apply )
 
     -- Equip element with TemplateStyles
 
     -- Equip element with TemplateStyles
    --    apply  -- mw.html element
 
 
     --    assign  -- string, with script code
 
     --    assign  -- string, with script code
     -- Returns string, or false
+
    --    apply  -- mw.html element, or false
 +
     -- Returns string, perhaps with tag
 +
    local r
 
     if type( Config.tmplStyles ) == "table" then
 
     if type( Config.tmplStyles ) == "table" then
 
         local source = Config.tmplStyles[ assign ]
 
         local source = Config.tmplStyles[ assign ]
 
         if source then
 
         if source then
             source = Frame():extensionTag( "templatestyles",
+
             r = Frame():extensionTag( "templatestyles",
                                          nil,
+
                                      nil,
                                          { src = source } )
+
                                      { src = source } )
             apply:wikitext( source )
+
             if apply then
 +
                apply:wikitext( r )
 +
            end
 
         end
 
         end
 
     end
 
     end
 +
    return r or ""
 
end -- first()
 
end -- first()
  
Zeile 412: Zeile 421:
 
           and Config.owns[ acquire ]  then
 
           and Config.owns[ acquire ]  then
 
             story = string.format( Config.owns[ acquire ], apply )
 
             story = string.format( Config.owns[ acquire ], apply )
         elseif advanced == acquire  or
+
         elseif advanced == acquire  and  Config.site == "Latn"  or
 
               advanced == acquire .. "-Latn" then
 
               advanced == acquire .. "-Latn" then
 
             s = "italic"
 
             s = "italic"
Zeile 439: Zeile 448:
 
     local sep  = ahead
 
     local sep  = ahead
 
     local r    = ""
 
     local r    = ""
     local s, t
+
     local lucky, s, t
 
     family()
 
     family()
 
     facility()
 
     facility()
Zeile 460: Zeile 469:
 
     for i = 1, #aliens do
 
     for i = 1, #aliens do
 
         t = aliens[ i ]
 
         t = aliens[ i ]
 +
        s = false
 
         if t.short == Config.slang  and
 
         if t.short == Config.slang  and
 
           t.script  and
 
           t.script  and
 
           Config.tmplScript  and
 
           Config.tmplScript  and
 
           t.n > 0 then
 
           t.n > 0 then
             s = fill( "tmplScript", t.script )
+
             lucky, s = pcall( fill, "tmplScript", t.script )
         elseif Config.tmplLang and t.n > 0 then
+
            if not lucky then
             s = fill( "tmplLang", t.short )
+
                s = false
         else
+
            end
 +
        end
 +
         if not s  and  Config.tmplLang and t.n > 0 then
 +
             lucky, s = pcall( fill, "tmplLang", t.short )
 +
            if not lucky then
 +
                s = false
 +
            end
 +
        end
 +
         if not s then
 
             s = mw.language.fetchLanguageName( t.short, Config.standard )
 
             s = mw.language.fetchLanguageName( t.short, Config.standard )
 
             if Config.Multilingual  and
 
             if Config.Multilingual  and
Zeile 483: Zeile 501:
 
                                       t.slang,
 
                                       t.slang,
 
                                       t.script ) )
 
                                       t.script ) )
         sep = ","    -- follow( t.script )
+
         sep = follow( t.script )
 
     end -- for i
 
     end -- for i
 
     return r
 
     return r
Zeile 535: Zeile 553:
 
         local sep  = ""
 
         local sep  = ""
 
         local slang = Config.slang
 
         local slang = Config.slang
         local params, s
+
         local s
         if Config.scripting == "Latn" then
+
         if Config.scripting == Config.site then
 
             if slang == facility() then
 
             if slang == facility() then
 
                 arglist.style = false
 
                 arglist.style = false
Zeile 542: Zeile 560:
 
                 arglist.style = "font-style:italic"
 
                 arglist.style = "font-style:italic"
 
             end
 
             end
             sep = ","
+
             sep = follow( Config.site )
 
             if arglist.Text2 then
 
             if arglist.Text2 then
                 arglist.Text2 = fault( "errInvalid", "Latn+2=" )
+
                 arglist.Text2 = fault( "errInvalid",
 +
                                      Config.site .. "+2=" )
 
             end
 
             end
 
         elseif not Config.low  and  not arglist.style then
 
         elseif not Config.low  and  not arglist.style then
Zeile 561: Zeile 580:
 
                           arglist.class )
 
                           arglist.class )
 
         if arglist.Text2 then
 
         if arglist.Text2 then
             params = { lang = string.format( "%s-Latn",
+
             local e = mw.html.create( "span" )
                                              Config.slang ),
+
                            :addClass( Config.site )
                      style = "font-style:italic" }
+
                            :attr( "lang",
            s     = mw.text.tag( "span", params, arglist.Text2 )
+
                                    string.format( "%s-%s",
             r     = string.format( "%s %s", r, s )
+
                                                  Config.slang,
             sep   = ","
+
                                                  Config.site ) )
 +
                            :css( { ["font-weight"] = "normal" } )
 +
                            :wikitext( arglist.Text2 )
 +
                            if Config.site == "Latn" then
 +
                                s = "italic"
 +
                            else
 +
                                s = "normal"
 +
                            end
 +
                            e:css( { ["font-style"] = s } )
 +
             r   = string.format( "%s %s%s",
 +
                                r,
 +
                                first( Config.site ),
 +
                                tostring( e ) )
 +
             sep = follow( Config.site )
 
         end
 
         end
 
         if arglist.trans then
 
         if arglist.trans then
 
             local e = mw.html.create( "span" )
 
             local e = mw.html.create( "span" )
 +
                            :addClass( Config.site )
 
                             :attr( "lang",
 
                             :attr( "lang",
                                     string.format( "%s-Latn",
+
                                     string.format( "%s-%s",
                                                   Config.slang ) )
+
                                                   Config.slang,
                             :css( { ["font-style"]  = "italic",
+
                                                  Config.site ) )
                                    ["font-weight"] = "normal" } )
+
                             :css( { ["font-weight"] = "normal" } )
                             :wikitext( arglist.Latn )
+
                             :wikitext( arglist[ Config.site ] )
 +
            if Config.site == "Latn" then
 +
                s = "italic"
 +
            else
 +
                s = "normal"
 +
            end
 +
            e:css( { ["font-style"] = s } )
 
             if type( Config.transys ) == "table"  and
 
             if type( Config.transys ) == "table"  and
 
               type( Config.transys[ arglist.trans ] ) == "table" then
 
               type( Config.transys[ arglist.trans ] ) == "table" then
Zeile 599: Zeile 638:
 
                 s = arglist.trans
 
                 s = arglist.trans
 
             end
 
             end
             r  = string.format( "%s%s %s %s", r, sep, s, tostring( e ) )
+
             r  = string.format( "%s%s %s %s%s",
             sep = ","
+
                                r, sep, s,
 +
                                first( Config.site ), tostring( e ) )
 +
             sep = follow( Config.site )
 
         end
 
         end
 
         if not Config.low then
 
         if not Config.low then
Zeile 607: Zeile 648:
 
                 if s  and
 
                 if s  and
 
                   faculty( s )  and
 
                   faculty( s )  and
 +
                  Config.tmplScript  and
 
                   not arglist.Text2 then
 
                   not arglist.Text2 then
 +
                    local lucky
 
                     s = fill( "tmplScript", Config.scripting )
 
                     s = fill( "tmplScript", Config.scripting )
                elseif Config.service then
+
                     lucky, s = pcall( fill,
                     s = facet( Config.service )
+
                                      "tmplScript", Config.scripting )
 +
                    if not lucky then
 +
                        s = false
 +
                    end
 
                 else
 
                 else
 
                     s = false
 
                     s = false
 +
                end
 +
                if not s  and  Config.service then
 +
                    s = facet( Config.service )
 
                 end
 
                 end
 
             elseif Config.service then
 
             elseif Config.service then
Zeile 628: Zeile 677:
 
         end
 
         end
 
         if arglist.IPA then
 
         if arglist.IPA then
             params = { [1] = arglist.IPA }
+
             local params = { [1] = arglist.IPA }
             s     = Frame():expandTemplate{ title = Config.ipa,
+
             s   = Frame():expandTemplate{ title = Config.ipa,
                                            args  = params }
+
                                          args  = params }
             r     = string.format( "%s [%s]", r, s )
+
             r   = string.format( "%s [%s]", r, s )
             sep   = ","
+
             sep = ","
 
         end
 
         end
 
         if arglist.trsl then
 
         if arglist.trsl then
Zeile 698: Zeile 747:
 
                             r.Text1 = v
 
                             r.Text1 = v
 
                             k      = false
 
                             k      = false
                         elseif Config.scripting == "Latn" then
+
                         elseif Config.scripting == Config.site then
 
                             k = "2"
 
                             k = "2"
 
                         else
 
                         else
Zeile 757: Zeile 806:
 
                         v = mw.text.trim( v )
 
                         v = mw.text.trim( v )
 
                         if v ~= "" then
 
                         if v ~= "" then
                             r.trans = k
+
                             r.trans         = k
                             r.Latn  = v
+
                             r[ Config.site ] = v
 
                         end
 
                         end
 
                         k = false
 
                         k = false
Zeile 891: Zeile 940:
 
                                 :attr( "lang", slang )
 
                                 :attr( "lang", slang )
 
                                 :wikitext( show )
 
                                 :wikitext( show )
                 local s = slang
+
                 local s
 
                 if q and q.suggest then
 
                 if q and q.suggest then
 
                     local say = factory( "errSuggest" )
 
                     local say = factory( "errSuggest" )
                     s = string.format( say, s, q.suggest )
+
                     s = string.format( say, slang, q.suggest )
 +
                else
 +
                    s = slang
 
                 end
 
                 end
 
                 r = tostring( e ) .. fault( "errInvalid", s )
 
                 r = tostring( e ) .. fault( "errInvalid", s )
Zeile 979: Zeile 1.030:
 
         end
 
         end
 
         if script then
 
         if script then
             first( bdo, script )
+
             first( script, bdo )
 
             bdi:attr( "lang", string.format( "%s-%s", slang, script ) )
 
             bdi:attr( "lang", string.format( "%s-%s", slang, script ) )
 
             features( bdi, script )
 
             features( bdi, script )
Zeile 1.040: Zeile 1.091:
 
             ltr = not rtl[ script ]
 
             ltr = not rtl[ script ]
 
         end
 
         end
         if script ~= "Latn" then
+
         if script ~= Config.site then
 
             selector = script
 
             selector = script
 
             if type( Config.classScript ) == "table" then
 
             if type( Config.classScript ) == "table" then
Zeile 1.053: Zeile 1.104:
 
             elem:attr( "lang", string.format( "%s-%s", slang, script ) )
 
             elem:attr( "lang", string.format( "%s-%s", slang, script ) )
 
             features( elem, script )
 
             features( elem, script )
             if script ~= "Latn" then
+
             if script ~= Config.site then
                 first( elem, script )
+
                 first( script, elem )
 
             end
 
             end
 
         else
 
         else
Zeile 1.067: Zeile 1.118:
 
         elem:wikitext( apply )
 
         elem:wikitext( apply )
 
         r = tostring( elem )
 
         r = tostring( elem )
         if script  and  script ~= "Latn" then
+
         if script  and  script ~= Config.site then
 
             local lucky, x = pcall( require,
 
             local lucky, x = pcall( require,
 
                                     "Module:Vorlage:lang/Zwiebelfisch" )
 
                                     "Module:Vorlage:lang/Zwiebelfisch" )
Zeile 1.090: Zeile 1.141:
 
                                     args  = params }
 
                                     args  = params }
 
     end
 
     end
     return r
+
     return r or ""
 
end -- Export.format()
 
end -- Export.format()
  

Version vom 16. Dezember 2018, 18:10 Uhr

Die Dokumentation für dieses Modul kann unter Modul:Vorlage:lang/Doku erstellt werden

local Export = { serial = "2018-12-15",
                 suite  = "lang",
                 item   = 26826825 }
--[=[
Vorlage:lang und Sprachnamenvorlagen usw. unterstützen
]=]



local Config = {
   errCat         = false,
   errClass       = "error_lang",
   errClasses     = false,
   errHide        = true,
   errNS          = false,
   errDoubled     = { en = "Doubled:",
                      de = "Doppelangabe:" },
   errInvalid     = { en = "Invalid:",
                      de = "Ungültig:" },
   errMissing     = { en = "Missing parameter",
                      de = "Parameter fehlt" },
   errSuggest     = { en = "'%s' * probably '%s' intended",
                      de = "'%s' * vermutlich ist '%s' gemeint" },
   errUnkown      = { en = "Unkown parameter:",
                      de = "Parameter unbekannt:" },
   ipa            = "IPA",
   params         = { "Text1",
                      "Audio",
                      "IPA",
                      "class",
                      "script",
                      "style",
                      "nachgestellt",
                      "demo",
                      "demo2",
                      "demo3",
                      "demo4",
                      "NoCat" },
   percents       = false,
   orderOther     = { grc = 1,
                      hbo = 2,
                      la  = 3,
                      en  = 9 },
   owns           = { de = "‚%s‘" },
   scripts        = "Multilingual/scripts",
   sepComma       = "Latn Cyrl Grek Thai",
   site           = "Latn",
   tmplAudio      = false,    -- template for media player link
   tmplLang       = false,    -- template for language name link
   tmplScript     = false,    -- template for script name link
   tmplStyles     = false
}



local function Fetch( ask )
    -- Fetch module
    -- Parameter:
    --     ask  -- string, with name
    --                     "Multilingual"
    --                     "TemplUtl"
    -- Returns string, with error message, if not available
    local r
    if type( Config[ ask ] ) ~= "table" then
        local lucky, g = pcall( require, "Module:" .. ask )
        if type( g ) == "table" then
            g = g[ ask ]
            if type( g ) == "function" then
                Config[ ask ] = g()
            end
            g = false
        else
            g = false
        end
        if type( Config[ ask ] ) ~= "table" then
            if not g then
                g = "Invalid library *** Module:" .. ask
            end
            g = mw.html.create( "span" )
                       :attr( "class", "error" )
                       :wikitext( g )
            r = tostring( g )
        end
    end
    return r
end -- Fetch()



local function Frame()
    -- Fetch current frame
    -- Returns frame
    if not Config.frame then
        Config.frame = mw.getCurrentFrame()
    end
    return Config.frame
end -- Frame()



local function Friend()
    -- Fetch Module:Multilingual/scripts
    if not Config.multiScripts then
        local lucky
        lucky, Config.multiScripts = pcall( mw.loadData,
                                            "Module:" .. Config.scripts )
        if type( Config.multiScripts ) ~= "table" then
            Config.multiScripts = { }
        end
    end
    return Config.multiScripts
end -- Friend()




local function facet( assign )
    -- Format language name
    --     apply  -- string, with language name, might be linked
    -- Returns string
    local e = mw.html.create( "span" )
                     :css( { ["font-style"]  = "normal",
                             ["font-weight"] = "normal" } )
                     :wikitext( assign )
    return tostring( e )
end -- facet()



local function facility()
    -- Fetch current site language
    -- Returns language code
    if not Config.standard then
        Config.standard = mw.language.getContentLanguage():getCode()
    end
    return Config.standard
end -- facility()



local function factory( apply )
    -- Localization of messages
    --     apply  -- string, with message key
    -- Returns message text; at least english
    local r
    entry = Config[ apply ]
    if entry then
        r = entry[ facility() ]
        if not r then
            r = entry.en
        end
    else
        r = string.format( "<span class=\"error\">????.%s.????</span>",
                           apply )
    end
    return r
end -- factory()



local function faculty( adjust )
    -- Test template arg for boolean
    --     adjust  -- string or nil
    -- Returns boolean
    local s = type( adjust )
    local r
    if s == "string" then
        r = mw.text.trim( adjust )
        r = ( r ~= ""  and  r ~= "0" )
    elseif s == "boolean" then
        r = adjust
    else
        r = false
    end
    return r
end -- faculty()



local function family()
    -- attempt to load local config
    if not Config.data then
        local lucky, sub
        sub = string.format( "%s/config", Frame():getTitle() )
        lucky, Config.data = pcall( mw.loadData, sub )
        if type( Config.data ) == "table" then
            for k, v in pairs( Config.data ) do
                sub         = type( v )
                Config[ k ] = v
            end -- for k, v
        else
            Config.data = sub .. " not found"
        end
    end
end -- family()



local function fault( alert, about )
    -- Format message with class="error" or similar
    --     alert  -- string, with message key
    --     about  -- string, with explanation
    -- Returns message with markup
    local story = factory( alert )
    local err   = mw.html.create( "span" )
    local r
    err:addClass( Config.errClass )
       :css( { ["margin-left"]  = "1em",
               ["margin-right"] = "1em" } )
    family()
    story = string.format( "[[%s]] &#8211; %s",
                           Frame():getParent():getTitle(),
                           story )
    if about then
        story = string.format( "%s %s", story, about )
    end
    if Config.errClasses then
        err:addClass( Config.errClasses )
    end
    err:wikitext( story )
    r = Fetch( "TemplUtl" )
    if Config.TemplUtl then
        r = Config.TemplUtl.failure( tostring( err ),
                                     not Config.errHide,
                                     false,
                                     Frame() )
    end
    if type( Config.errCat ) == "string" then
        if Config.errNS then
            local ns = mw.title.getCurrentTitle().namespace
            local st = type( Config.errNS )
            if st == "string" then
                local space  = string.format( ".*%%s%d%%s.*", ns )
                local spaces = string.format( " %s ", Config.errNS )
                if spaces:match( space ) then
                    Config.errNS = false
                end
            elseif st == "table" then
                for i = 1, #Config.errNS do
                    if Config.errNS[ i ] == ns then
                        Config.errNS = false
                        break    -- for i
                    end
                end -- for i
            end
        end
        if not Config.errNS then
            r = string.format( "%s[[Category:%s]]", r, Config.errCat )
        end
    end
    return r
end -- fault()



local function features( apply, assign )
    -- Equip element with script attributes
    --     apply   -- mw.html element
    --     assign  -- string, with script code
    if type( Config.percents ) == "table" then
        local more = Config.percents[ assign ]
        if more then
            apply:css( "font-size",  string.format( "%d%%", more ) )
        end
    end
end -- features()



local function fill( access, apply, assign )
    -- Expand template
    --     access  -- string, with template definition ID
    --     apply   -- string, with code
    --     assign  -- string, with text
    -- Returns string, with applied text
    -- Throws error, if template not existing
    local template = Config[ access ]
    local r        = apply
    if type( template ) == "table" then
        local source = template.title
        local params
        if type( source ) ~= "string" then
            if type( template.namePat ) == "string"  and
               template.namePat:find( "%s", 1, true ) then
                source = string.format( template.namePat, apply )
            end
        end
        if type( source ) == "string" then
            r = Frame():expandTemplate{ title = source,
                                        args  = params }
        end
    end
    return r
end -- fill()



local function first( assign, apply )
    -- Equip element with TemplateStyles
    --     assign  -- string, with script code
    --     apply   -- mw.html element, or false
    -- Returns string, perhaps with tag
    local r
    if type( Config.tmplStyles ) == "table" then
        local source = Config.tmplStyles[ assign ]
        if source then
            r = Frame():extensionTag( "templatestyles",
                                      nil,
                                      { src = source } )
            if apply then
                apply:wikitext( r )
            end
        end
    end
    return r or ""
end -- first()



local function fit( acquire )
    -- Retrieve script code for language
    --     acquire  -- string, with language code
    -- Returns string or false
    local r
    local written = Friend().written
    if type( written ) == "table" then
        r = written[ acquire ]
        if type( r ) == "table" then
            r = r[ 1 ]
        end
    end
    return r
end -- fit()



local function flag( already, apply )
    -- Check whether space separated classes contain
    --     already  -- string or false, with classes
    --     apply    -- string or false, with single class
    -- Returns true, if apply is in already
    local r
    if already then
        if apply then
            local classes = mw.text.split( already, "%s+" )
            local plus    = mw.text.split( apply, "%s+" )
            local single
            for i = 1, #plus do
                single = plus[ i ]
                for k = 1, #classes do
                    if classes[ k ] == single then
                        single = false
                        break -- for k
                    end
                end -- for k
                if single then
                    table.insert( classes, single )
                end
            end -- for i
            r = table.concat( classes, " " )
        else
            r = already
        end
    else
        r = apply
    end
    return r
end -- flag()



local function follow( affine )
    -- Retrieve appropriate separator
    --     affine    -- string or nil, with code of script
    -- Returns string, with separator (comma) or not
    local r
    if affine then
        if Config.sepComma:find( affine, 1, true ) then
            r = ","
        else
            r = ""
        end
    else
        r = ","
    end
    return r
end -- follow()



local function foreign( apply, acquire, advanced, affine )
    -- Format text in some language
    --     apply     -- string, with text
    --     acquire   -- string, with basic code of language
    --     advanced  -- string, with full code of language
    --     affine    -- string or nil, with code of script
    -- Returns string
    local story  = apply
    local script = affine
    local p = { ["font-weight"] = "normal" }
    local ltr, r
    if advanced == acquire then
        ltr = not mw.language.new( acquire ):isRTL()
    elseif not script  and  advanced:find( "-", 3, true ) then
        local parts = mw.text.split( advanced, "-", true )
        if #parts > 1  and  parts[ 2 ]:match( "^%u%l%l%l$" ) then
            script = parts[ 2 ]
        end
    end
    if script then
        local rtl = Friend().rtl
        if type( rtl ) == "table" then
            ltr = not rtl[ script ]
        end
    end
    if ltr then
        local e = mw.html.create( "span" )
                         :attr( "lang", advanced )
        local s = "normal"
        if acquire == Config.standard
           and Config.owns[ acquire ]  then
            story = string.format( Config.owns[ acquire ], apply )
        elseif advanced == acquire  and  Config.site == "Latn"   or
               advanced == acquire .. "-Latn" then
            s = "italic"
        end
        p["font-style"] = s
        e:css( p )
         :wikitext( story )
        r = tostring( e )
    else
        p["font-style"] = "normal"
        r = Export.fold( { css   = p },
                         { [ 1 ] = apply,
                           lang  = advanced } )
    end
    return r
end -- foreign()



local function foreigns( ahead, aliens )
    -- Create list of translations
    --     ahead   -- string, with leading separator
    --     aliens  -- sequence table, with assignment tables
    -- Returns string, starting with separator (comma)
    local pars = { }
    local sep  = ahead
    local r    = ""
    local lucky, s, t
    family()
    facility()
    Fetch( "Multilingual" )
    for i = 1, #aliens do
        t = aliens[ i ]
        if t.short == Config.standard then
            t.n = 0
        else
            local o = Config.orderOther[ t.short ]
            if o then
                t.n = o
            end
        end
    end -- for i
    table.sort( aliens,
                function ( a1, a2 )
                    return ( a1.n < a2.n )
                end )
    for i = 1, #aliens do
        t = aliens[ i ]
        s = false
        if t.short == Config.slang  and
           t.script  and
           Config.tmplScript  and
           t.n > 0 then
            lucky, s = pcall( fill, "tmplScript", t.script )
            if not lucky then
                s = false
            end
        end
        if not s  and  Config.tmplLang  and  t.n > 0 then
            lucky, s = pcall( fill, "tmplLang", t.short )
            if not lucky then
                s = false
            end
        end
        if not s then
            s = mw.language.fetchLanguageName( t.short, Config.standard )
            if Config.Multilingual  and
               Config.Multilingual.isMinusculable( s ) then
                s = mw.ustring.lower( mw.ustring.sub( s, 1, 1 ) )
                    .. mw.ustring.sub( s, 2 )
            end
        end
        r   = string.format( "%s%s %s %s",
                             r,
                             sep,
                             s,
                             foreign( t.story,
                                      t.short,
                                      t.slang,
                                      t.script ) )
        sep = follow( t.script )
    end -- for i
    return r
end -- foreigns()



local function frontend( action, argsF, argsT, about )
    -- Template service
    --     action  -- string, "flat" or "full" etc.
    --     argsF   -- table, with #invoke parameters, or false
    --     argsT   -- table, with template parameters
    --     about   -- string or nil, invocation name
    -- Returns frame
    local lucky, r
    lucky, r = pcall( Export[ action ], argsF, argsT )
    if not lucky then
        local e = mw.html.create( "span" )
                         :attr( "class", "error" )
        if about then
            r = string.format( "&#123;{%s}&#125; %s",  about,  r )
        end
        e:wikitext( r )
        r = tostring( e )
    end
    return r
end -- frontend()



local function frontier( frame, action )
    -- Template transclusion
    --     frame   -- object
    --     action  -- string, "flat" or "full" etc.
    -- Returns appropriate string
    Config.frame = frame
    return frontend( action,
                     frame.args,
                     frame:getParent().args,
                     frame:getTitle() )
end -- frontier()



local function full( arglist )
    -- Finalize invocation of template
    --     arglist  -- table, with parameters
    -- Returns appropriate string
    local r
    if arglist.Text1 then
        local sep   = ""
        local slang = Config.slang
        local s
        if Config.scripting == Config.site then
            if slang == facility() then
                arglist.style = false
            elseif not arglist.style then
                arglist.style = "font-style:italic"
            end
            sep = follow( Config.site )
            if arglist.Text2 then
                arglist.Text2 = fault( "errInvalid",
                                       Config.site .. "+2=" )
            end
        elseif not Config.low  and  not arglist.style then
            arglist.style = "font-style:normal"
        end
        if Config.state then
            slang = string.format( "%s-%s", slang, Config.state )
        end
        if Config.scripting then
            slang = string.format( "%s-%s", slang, Config.scripting )
        end
        r = Export.format( slang,
                           arglist.Text1,
                           arglist.style,
                           arglist.Audio,
                           arglist.class )
        if arglist.Text2 then
            local e = mw.html.create( "span" )
                             :addClass( Config.site )
                             :attr( "lang",
                                    string.format( "%s-%s",
                                                   Config.slang,
                                                   Config.site ) )
                             :css( { ["font-weight"] = "normal" } )
                             :wikitext( arglist.Text2 )
                             if Config.site == "Latn" then
                                 s = "italic"
                             else
                                 s = "normal"
                             end
                             e:css( { ["font-style"] = s } )
            r   = string.format( "%s %s%s",
                                 r,
                                 first( Config.site ),
                                 tostring( e ) )
            sep = follow( Config.site )
        end
        if arglist.trans then
            local e = mw.html.create( "span" )
                             :addClass( Config.site )
                             :attr( "lang",
                                    string.format( "%s-%s",
                                                   Config.slang,
                                                   Config.site ) )
                             :css( { ["font-weight"] = "normal" } )
                             :wikitext( arglist[ Config.site ] )
            if Config.site == "Latn" then
                s = "italic"
            else
                s = "normal"
            end
            e:css( { ["font-style"] = s } )
            if type( Config.transys ) == "table"  and
               type( Config.transys[ arglist.trans ] ) == "table" then
                local transys = Config.transys[ arglist.trans ]
                if transys.class then
                    e:addClass( transys.class )
                end
                if transys.show then
                    s = transys.show
                else
                    s = arglist.trans
                end
                if transys.support then
                    if s == transys.support then
                        s = string.format( "[[%s]]", s )
                    else
                        s = string.format( "[[%s|%s]]",
                                           transys.support,
                                           s )
                    end
                end
            else
                s = arglist.trans
            end
            r   = string.format( "%s%s %s %s%s",
                                 r, sep, s,
                                 first( Config.site ), tostring( e ) )
            sep = follow( Config.site )
        end
        if not Config.low then
            if Config.scripting then
                s = arglist[ Config.scripting ]
                if s  and
                   faculty( s )  and
                   Config.tmplScript  and
                   not arglist.Text2 then
                    local lucky
                    s = fill( "tmplScript", Config.scripting )
                    lucky, s = pcall( fill,
                                      "tmplScript", Config.scripting )
                    if not lucky then
                        s = false
                    end
                else
                    s = false
                end
                if not s  and  Config.service then
                    s = facet( Config.service )
                end
            elseif Config.service then
                s = Config.service
            else
                s = false
            end
            if s then
                if arglist.later then
                    r = string.format( "%s (%s)", r, s )
                else
                    r = string.format( "%s %s", s, r )
                end
            end
        end
        if arglist.IPA then
            local params = { [1] = arglist.IPA }
            s   = Frame():expandTemplate{ title = Config.ipa,
                                          args  = params }
            r   = string.format( "%s [%s]", r, s )
            sep = ","
        end
        if arglist.trsl then
            r = r .. foreigns( sep, arglist.trsl )
        end
    elseif arglist.Text2 then
        r = fault( "errInvalid", "2=" )
    else
        if Config.sole then
            r = Config.sole
        else
            r = Config.service
        end
    end
    return r
end -- full()



local function furnish( argsF, argsT )
    -- General entry point; basic argument consumption
    --     argsF  -- table, with #invoke parameters, or false
    --     argsT  -- table, with template parameters
    -- Returns appropriate string
    local r = { }
    local s
    if argsF then
        if argsF.errHide ~= nil then
            Config.errHide = faculty( argsF.errHide )
        end
        Config.errCat     = argsF.errCat
        Config.errClasses = argsF.errClasses
        Config.errNS      = argsF.errNS
        if argsF.SUITABLE then
            local params = mw.text.split( argsF.SUITABLE, " ", true )
            for k, v in pairs( params ) do
                table.insert( Config.params, v )
            end -- for k, v
        end
    end
    if Config.scripting == "" then
        Config.scripting = false
    end
    if Config.scripting then
        table.insert( Config.params, Config.scripting )
    end
    if type( argsT ) == "table" then
        local n = table.maxn( Config.params )
        local script, unknown
        for k, v in pairs( argsT ) do
            s = type( k )
            if s == "number" then
                if Config.low then
                    k = k - 1
                end
                if k <= 2 then
                    if k == 0 then
                        k = false
                    else
                        v = mw.text.trim( v )
                        if v == "" then
                            v = false
                        end
                        if k == 1 then
                            r.Text1 = v
                            k       = false
                        elseif Config.scripting == Config.site then
                            k = "2"
                        else
                            r.Text2 = v
                            k       = false
                        end
                    end
                else
                    k = tostring( k )
                end
            elseif k:match( "^%l%l%l?%-?" ) then
                s = k:match( "^(%l%l%l?)$" )  or
                    k:match( "^(%l%l%l?)%-%u%u$" )  or
                    k:match( "^(%l%l%l?)%-%u%l%l%l$" )
                v = mw.text.trim( v )
                if v == "" then
                    v = false
                    k = false
                else
                    script = k:match( "^%l%l%l?%-(%u%l%l%l)$" )
                end
                if v   and   s   and
                   ( s ~= Config.slang  or
                     script ~= Config.scripting )   and
                   mw.language.isSupportedLanguage( s ) then
                    if not script then
                        script = fit( s )
                        if script then
                            k = string.format( "%s-%s", s, script )
                        end
                    end
                    if not r.trsl then
                        r.trsl = { }
                    end
                    table.insert( r.trsl,
                                  { n      = #r.trsl + 10,
                                    script = script,
                                    short  = s,
                                    slang  = k,
                                    story  = v } )
                    k = false
                end
            elseif k:match( "^%u+%d*%-?%d?$" ) then
                local trans = Friend().trans
                if type( trans ) == "table" then
                    local t = trans[ Config.slang ]   or
                              trans[ Config.scripting ]
                    trans = false
                    if type( t ) == "table" then
                        for kT, vT in pairs( t ) do
                            if vT == k then
                                trans = true
                                break    -- for kT, vT
                            end
                        end -- for kT, vT
                    end
                    if trans then
                        v = mw.text.trim( v )
                        if v ~= "" then
                            r.trans          = k
                            r[ Config.site ] = v
                        end
                        k = false
                    end
                end
            end
            if k then
                for i = 1, n do
                    if Config.params[ i ] == k then
                        if v ~= "" then
                            r[ k ] = v
                        end
                        k = false
                        break -- for i
                    end
                end -- for i
            end
            if k then
                if not unknown then
                    unknown = { }
                end
                table.insert( unknown, k )
            end
        end -- for k, v
        if r.demo  or  faculty( r.NoCat ) then
            Config.errCat  = 0
            Config.errHide = false
        end
        r.later = faculty( r.nachgestellt )
        if r.b and Config[ "OBSOLETING-bwd" ] then
            if r.de then
                r = fault( "errDoubled", "'de=' und 'b='" )
            else
                r.de = r.b
            end
        end
        if r.w and Config[ "OBSOLETING-bwd" ] then
            if r.Text2 then
                r = fault( "errDoubled", "'2=' und 'w='" )
            else
                r.Text2 = r.w
            end
        end
        if unknown then
            r = string.format( "'<code>%s</code>'",
                               table.concat( unknown, " " ) )
            r = fault( "errUnkown", r )
        end
    end
    if type( r ) == "table" then
        r = full( r )
    end
    return r
end -- furnish()



Export.failsafe = function ( assert )
    -- Retrieve versioning and check for compliance
    -- Precondition:
    --     assert  -- string, with required version or "wikidata",
    --                or false
    -- Postcondition:
    --     Returns  string with appropriate version, or false
    local since = assert
    local r
    if since == "wikidata" then
        local item = Export.item
        since = false
        if type( item ) == "number"  and  item > 0 then
            local entity = mw.wikibase.getEntity( string.format( "Q%d",
                                                                 item ) )
            if type( entity ) == "table" then
                local vsn = entity:formatPropertyValues( "P348" )
                if type( vsn ) == "table"  and
                   type( vsn.value ) == "string" and
                   vsn.value ~= "" then
                    r = vsn.value
                end
            end
        end
    end
    if not r then
        if not since  or  since <= Export.serial then
            r = Export.serial
        else
            r = false
        end
    end
    return r
end -- Export.failsafe()



Export.flat = function ( argsF, argsT, auxilary )
    -- Invocation of basic language template
    --     argsF     -- table, with #invoke parameters, or false
    --     argsT     -- table, with template parameters
    --     auxilary  -- Multilingual library, or false
    -- Returns appropriate string
    local r
    if type( auxilary ) == "table" then
        Config.Multilingual = auxilary
    else
        r = Fetch( "Multilingual" )
    end
    if Config.Multilingual then
        local slang = argsT[ 1 ]
        local show  = argsT[ 2 ]
        if slang then
            slang = mw.text.trim( slang )
            if slang == "" then
                slang = false
            end
        end
        if show then
            show = mw.text.trim( show )
            if show == "" then
                show = false
            end
        end
        if slang and show then
            local q = Config.Multilingual.getLang( slang )
            if q and q.legal then
                Config.low       = true
                Config.slang     = q.base
                Config.state     = q.region
                Config.scripting = q.script
                r = furnish( argsF, argsT )
            else
                local e = mw.html.create( "span" )
                                 :attr( "lang", slang )
                                 :wikitext( show )
                local s
                if q and q.suggest then
                    local say = factory( "errSuggest" )
                    s = string.format( say, slang, q.suggest )
                else
                    s = slang
                end
                r = tostring( e ) .. fault( "errInvalid", s )
            end
        else
            r = fault( "errMissing" )
            if show then
                r = show .. r
            end
        end
    end
    return r
end -- Export.flat()



Export.fold = function ( argsF, argsT )
    -- Invocation of RTL template
    --     argsF  -- table, with #invoke parameters, or false
    --     argsT  -- table, with template parameters
    -- Returns appropriate string, or nil
    local params = { }
    local r, s, slang
    for k, v in pairs( argsT ) do
        if v then
            v = mw.text.trim( v )
            if v ~= "" then
                params[ k ] = v
            end
        end
    end -- for k, v
    if params[ 2 ] then
        s = params[ 2 ]:gsub( mw.ustring.char( 0x202A ), "" )
                       :gsub( mw.ustring.char( 0x202B ), "" )
                       :gsub( mw.ustring.char( 0x202C ), "" )
                       :gsub( mw.ustring.char( 0x202D ), "" )
                       :gsub( mw.ustring.char( 0x202E ), "" )
                       :gsub( mw.ustring.char( 0x2066 ), "" )
                       :gsub( mw.ustring.char( 0x2067 ), "" )
                       :gsub( mw.ustring.char( 0x2068 ), "" )
                       :gsub( mw.ustring.char( 0x2069 ), "" )
                       :gsub( mw.ustring.char( 8206 ), "&lrm;" )
                       :gsub( "&#0*8206;",             "&lrm;" )
                       :gsub( "&#x0*200[Ee];",         "&lrm;" )
                       :gsub( mw.ustring.char( 8207 ), "&rlm;" )
                       :gsub( "&#0*8207;",             "&rlm;" )
                       :gsub( "&#x0*200[Ff];",         "&rlm;" )
        if s:find( "&", 1, true ) then
            local shift = "^&rlm;%s*"
            while s:match( shift ) do
                s = s:gsub( shift, "" )
            end -- while
            shift = "%s*&lrm;$"
            while s:match( shift ) do
                s = s:gsub( shift, "" )
            end -- while
            if s == "" then
                s = false
            end
        end
    end
    if s then
        local bdi    = mw.html.create( "bdi" )
                              :attr( "dir", "rtl" )
                              :css( "unicode-bidi", "isolate" )
                              :wikitext( s )
        local bdo    = mw.html.create( "bdo" )
                              :attr( "dir", "ltr" )
        local slang  = params[ 1 ]
        local script = argsF.SCRIPTING
        local selector
        family()
        if slang then
            if slang:find( "-", 3, true ) then
                local parts = mw.text.split( slang, "-", true )
                slang = parts[ 1 ]
                if #parts > 1  and  parts[ 2 ]:match( "^%u%l%l%l$" ) then
                    script = parts[ 2 ]
                end
            end
            slang = slang:lower()
        else
            slang = "ar"
        end
        if script then
            first( script, bdo )
            bdi:attr( "lang", string.format( "%s-%s", slang, script ) )
            features( bdi, script )
            selector = script
            if type( Config.classScript ) == "table" then
                selector = flag( selector, Config.classScript[ script ] )
            end
        else
            bdi:attr( "lang", slang )
        end
        selector = flag( selector, argsF.class )
        selector = flag( selector, params.class )
        if selector then
            bdi:addClass( selector )
        end
        if argsF.css then
            bdi:css( argsF.css )
        end
        if argsF.style then
            bdi:cssText( argsF.style )
        end
        if params.style then
            bdi:cssText( params.style )
        end
        bdo:node( bdi )
        r = tostring( bdo )
    end
    return r
end -- Export.fold()



Export.format = function ( alien, apply, appear, audio, alike )
    -- Markup foreign language text
    --     alien   -- string, with language code
    --     apply   -- string, with text
    --     appear  -- string, with additional CSS, or nil
    --     audio   -- string, with title of an audio file, or nil
    --     alike   -- string, with additional class(es), or nil
    -- Returns appropriate string with HTML tag
    local ltr = true
    local r, script, selector, slang
    family()
    if alien:find( "-", 3, true ) then
        local parts = mw.text.split( alien, "-", true )
        slang = parts[ 1 ]
        if #parts > 1  and  parts[ 2 ]:match( "^%u%l%l%l$" ) then
            script = parts[ 2 ]
        end
    else
        slang = alien
    end
    slang = slang:lower()
    if not script then
        script = fit( slang )
    end
    if script then
        local rtl = Friend().rtl
        if type( rtl ) == "table" then
            ltr = not rtl[ script ]
        end
        if script ~= Config.site then
            selector = script
            if type( Config.classScript ) == "table" then
                selector = flag( selector, Config.classScript[ script ] )
            end
        end
    end
    selector = flag( selector, alike )
    if ltr then
        local elem = mw.html.create( "span" )
        if script then
            elem:attr( "lang", string.format( "%s-%s", slang, script ) )
            features( elem, script )
            if script ~= Config.site then
                first( script, elem )
            end
        else
            elem:attr( "lang", slang )
        end
        if selector then
            elem:addClass( selector )
        end
        if appear then
            elem:cssText( appear )
        end
        elem:wikitext( apply )
        r = tostring( elem )
        if script  and  script ~= Config.site then
            local lucky, x = pcall( require,
                                    "Module:Vorlage:lang/Zwiebelfisch" )
            if type( x ) == "table"  and  type( x.f ) == "function" then
                x = x.f( Friend().unicodes, apply, script )
                if type( x ) == "string" then
                    r = r .. x
                end
            end
        end
    else
        r = Export.fold( { SCRIPTING = script },
                         { [ 1 ] = slang,
                           [ 2 ] = apply,
                           class = selector,
                           style = appear } )
    end
    if audio and Config.tmplAudio then
        local params = { [ Config.tmplAudio.filepar ] = audio,
                         [ Config.tmplAudio.textpar ] = r }
        r = Frame():expandTemplate{ title = Config.tmplAudio.title,
                                    args  = params }
    end
    return r or ""
end -- Export.format()



Export.full = function ( argsF, argsT )
    -- Invocation of language name template
    --     argsF  -- table, with #invoke parameters, or false
    --     argsT  -- table, with template parameters
    -- Returns appropriate string
    if argsF then
        Config.long      = faculty( argsF.LONG )
        Config.scripting = argsF.SCRIPTING
        Config.service   = argsF.SERVICE
        Config.slang     = argsF.CODE
        Config.sole      = argsF.SOLE
        if argsF["OBSOLETING-bwd"] then
            table.insert( Config.params, "b" )
            table.insert( Config.params, "d" )
            table.insert( Config.params, "w" )
        end
    end
    Config.low = false
    return furnish( argsF, argsT )
end -- Export.full()



-- Export
local p = { }



p.test = function ( action, argsF, argsT )
    --     action  -- string, "flat" or "full" etc.
    --     argsF   -- table, with #invoke parameters, or false
    --     argsT   -- table, with template parameters
    return frontend( action, argsF, argsT )
end -- p.test()



p.feedIAST = function ( frame )
    local trans = Friend().trans
    return type( trans ) == "table"  and
           trans[ frame.args[ 1 ] ] == "IAST"  and
           "1"   or   ""
end -- p.feedIAST()



p.flat = function ( frame )
    return frontier( frame, "flat" )
end -- p.flat()



p.fold = function ( frame )
    return frontier( frame, "fold" )  or   ""
end -- p.fold()



p.full = function ( frame )
    return frontier( frame, "full" )
end -- p.full()



p.failsafe = function ( frame )
    local s = type( frame )
    local since
    if s == "table" then
        since = frame.args[ 1 ]
    elseif s == "string" then
        since = frame
    end
    if since then
        since = mw.text.trim( since )
        if since == "" then
            since = false
        end
    end
    return Export.failsafe( since )  or  ""
end -- p.failsafe()



p.lang = function ()
    return Export
end -- p.lang()

return p