Modulo:mlngkodnomplus

El Vikivortaro
Salti al navigilo Salti al serĉilo
StopsignIndonesia.png Ĉi tiu modulo estas multfoje bindita.
Se vi konas la eblajn sekvojn, tiam vi povas zorgeme ekredakti.
Se vi ne kuraĝas redakti tiam vi povas proponi la deziratan ŝanĝon en la diskutejo.
Memtesto disponeblas sur la dokumentaĵa subpaĝo

--[===[

MODULE "MLNGKODNOMPLUS" (lingvo kodo nomo plus)

"eo.wiktionary.org/wiki/Modulo:mlngkodnomplus" <!--2019-Oct-30-->
"id.wiktionary.org/wiki/Modul:mlngkodnomplus"

Purpose: allows to process language codes and names in different manners,
         can convert language code to language name, "find" language name
         in a longer string, "fix" case of language name, create a
         "long form" of a language name (prefix by "la" in EO or by
         "bahasa" in ID), and create an adjective form (EO
         only, "Volapuko" -> "volapuka")

Utilo: ebligas pritrakti lingvokodojn kaj lingvonomojn je diversaj manieroj,
       povas konverti lingvokodon al lingvonomo, "trovi" lingvonomon
       en pli longa signocxeno, "gxustigi" usklecon de lingvonomo, krei
       "longan formon" de lingvonomo (prefiksi per "la" en EO aux
       per "bahasa" en ID) kaj krei adjektivan formon (nur
       EO, "Volapuko" -> "volapuka")

Used by templates / Uzata far sxablonoj:
- "ligald" (EO)
- "vikipedio" (EO) and some similar templates
- "vikivortarojesne" (EO)

Required submodules / Bezonataj submoduloj / Submodul yang diperlukan:
- "mpiktbllki" in turn requiring "mtmplloaddata" in turn requiring
  template "tbllingvoj" (EO) or "tblbahasa" (ID)

Incoming: - 2 anonymous obligatory parameters:
            - control string (5 char:s with 4 item:s)
              - (a) 2 char:s site language code "eo" or "id" (anything
                else is an error) affects language-specific case
                standardization and language-specific separation
                (usually (unless "mpiktbllki" is faulty) no effec
                t if (b,c)="00", and NOT passed into "mpiktbllki")
              - (b) 1 tristate digit (input string type): "0" language code |
                "1" language name | "2" longer string containing
                the language name requiring separation
              - (c) 1 tristate digit (output control): "0" do not produce the
                "long form" | "1" do produce the "long form" | "2" produce
                the adjective form (EO only)
              - (d) 1 tristate digit (output control): "0" keep native case |
                "1" beginning letter uppercase | "2" beginning
                letter lowercase
            - input string (2...80 octet:s now but stricter checks later)
          - 1 optional named parameter "err="
            - alternative output string to replace the "=" error
              message (1...64 char:s, default is "=") (this works even
              for errors coming from anonymous parameters)

Returned: - language name in the "short form" or "long
            form" or "forced adjective"

Control value (b,c,d) = "000" means simple translation of language code
to language name. Value "100" is NOT perfectly dummy, we
still perform the language-specific case standardization.

The most-left digit (b) in the control string is tristate and
defines what type the input is.

Input language code: 2 or 3 lowercase ASCII letters, translated
via submodule "mpiktbllki", error from there is forwarded and
message can be changed using "err=".

Input language name: 2...60 octet:s, case of beginning letter is
unconditionally subject to language-specific standardization:
- "eo" : lowercase for "AJ" ending with "a" and uppercase for "SB" ending
         with "o", last letter different from lowercase "a" or "o" is an error
- "id" : always uppercase, beginning letter must be ASCII "A"..."Z" or
         "a"..."z", anything else is an error

Input longer string: 2...80 octet:s (usually pagename, but the caller
must submit it as parameter, we do NOT peek it ourselves) is subject to
language-specific separation:
- conditions "eo":
  - bracketed part is picked if the string is at least 4 octet's long
    and contains exactly one "(" and exactly one ")" and part between
    them is at least 2 octet:s long
  - remaining right part of the string is returned if the string
    is at least 5 octet's long and begins with "la " (3 char:s)
    and failed the preceding bracket separation
- conditions "id":
  - remaining right part of the string is returned if the string
    is at least 9 octet's long and begins with "bahasa " (7 char:s)
  - remaining right part of the string is returned if the string
    is at least 14 octet's long and begins with "kata bahasa " (12 char:s)
The prefix check is case insensitive about the beginning letter thus for
example both "la " and "La " are accepted but "LA " is not. If this
separation step fails then the string passes as-is. Thus no error can
occur here but the result is fed into the language-specific case
standardization where an error can occur.

The middle digit (c) in the control string is tristate and controls
whether to create the "long form" or "forced adjective":
- "0" - keep short form
- "1" - produce long form
  - "eo" : add "la " (3 char:s) for "AJ" ending with lowercase
           "a" otherwise do nothing, applied AFTER the
           case standardization step
  - "id" : always add "bahasa " (7 char:s)
- "2" - produce "forced adjective", "eo" only, if last letter is "o" then
        change it to "a", applied BEFORE the case standardization step

No error can occur in this step (we dealt with bad last letter in "eo"
earlier during the language-specific case standardization step, later
"forced adjective" evaluates simply to false if last letter is not "a").

The last digit (d) in the control string allows to uppercase (for titles for
example) or lowercase (rarely useful, maybe for sorting hints) the beginning
letter of the "short form" or complete "long form".

The processing steps are:
- seize the parameters (can cause an error)
- analyze the control string (can cause an error)
- (b=0) translate language code if requested (can cause an error)
- (b=1) check for 60 octet:s limit if appropriate
- (b=2) perform the separation if requested (can fail but NOT cause an error)
- (c=2) produce "forced adjective" form if requested
- perform the case standardization for any type of input (can cause an error)
- (c=1) brew the long form if requested (CANNOT cause an error)
- (d=1 or d=2) adjust the case of the (possibly long) result if
  requested (CANNOT cause an error)

Usage examples with results ("!!" needs site EO ie "tbllingvoj") / Ekzemploj
de uzo kun rezultoj ("!!" bezonas na retejo EO te "tbllingvoj") / Contoh
penggunaan dengan hasil ("!!" memerlukan situs EO dkl "tbllingvoj"):

: ---------------------------------------

* 00 (no params)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek}}"
* (expected result) -> "="

* 01 (3 params, too many)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo000|sv|damn}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo000|sv|damn}}"
* (expected result) -> "="

* 02 (3 params, too many, "err" used)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo000|sv|damn|err=damn}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo000|sv|damn|err=damn}}"
* (expected result) -> "damn"

: ---------------------------------------

* 10 (2 params, 0xx AKA code input) !!
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo000|sv}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo000|sv}}"
* (expected result) -> "sveda"

* 11 (2 params, 0xx AKA code input) !!
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo000|vo}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo000|vo}}"
* (expected result) -> "Volapuko"

* 12 (2 params, 0xx AKA code input, dubious usage, consider "sveda" as an "id" word, site code NOT passed into "mpiktbllki")
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|id000|sv}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|id000|sv}}"
* (expected result) -> "Sveda"

* 13 (2 params, 0xx AKA code input, site code bad)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|de000|sv}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|de000|sv}}"
* (expected result) -> "="

* 14 (2 params, 0xx AKA code input, site code bad, "err" used)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|de000|sv|err=oops}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|de000|sv|err=oops}}"
* (expected result) -> "oops"

* 15 (2 params, 0xx AKA code input, invalid language code)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo000|qqq}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo000|qqq}}"
* (expected result) -> "="

* 16 (2 params, 0xx AKA code input, invalid code, "err" used)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo000|qqq|err=nekonata}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo000|qqq|err=nekonata}}"
* (expected result) -> "nekonata"

: ---------------------------------------

* 20 (2 params, 0xx AKA code input, lowercase) !!
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo002|sv}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo002|sv}}"
* (expected result) -> "sveda"

* 21 (2 params, 0xx AKA code input, uppercase) !!
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo001|sv}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo001|sv}}"
* (expected result) -> "Sveda"

* 22 (2 params, 0xx AKA code input, lowercase) !!
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo002|vo}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo002|vo}}"
* (expected result) -> "volapuko"

* 23 (2 params, 0xx AKA code input, requested long form "eo", adding "la") !!
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo010|sv}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo010|sv}}"
* (expected result) -> "la sveda"

* 24 (2 params, 0xx AKA code input, requested long form "eo", no need for "la") !!
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo010|vo}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo010|vo}}"
* (expected result) -> "Volapuko"

* 25 (2 params, 0xx AKA code input, dubious usage, long form "id", adding "bahasa" and uppercase) !!
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|id011|sv}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|id011|sv}}"
* (expected result) -> "Bahasa Sveda"

: ---------------------------------------

* 30 (2 params, 0xx AKA code input, requested "forced adjective" "eo", works even with decorated letters) !!
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo020|ce}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo020|ce}}"
* (expected result) -> "cxecxena"

* 31 (2 params, 0xx AKA code input, requested "forced adjective" "eo") !!
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo020|vo}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo020|vo}}"
* (expected result) -> "volapuka"

* 32 (2 params, 0xx AKA code input, requested "forced adjective" "id", invalid) !!
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|id020|vo}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|id020|vo}}"
* (expected result) -> "="

* 33 (2 params, 0xx AKA code input, requested ?? by c=3 "eo", invalid) !!
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo030|vo}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo030|vo}}"
* (expected result) -> "="

: ---------------------------------------

* 40 (2 params, 1xx AKA name input, this allows to brew <<lingvo "sveda">> from <<Kategorio:Sveda>>)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo100|Sveda}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo100|Sveda}}"
* (expected result) -> "sveda"

* 41 (2 params, 1xx AKA name input, this allows to brew <<la sveda>> from <<Kategorio:Sveda>>, long form "eo")
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo110|Sveda}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo110|Sveda}}"
* (expected result) -> "la sveda"

* 42 (2 params, 1xx AKA name input, "forced adjective" "eo", dubious language name "SXtelisto")
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo120|SXtelisto}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo120|SXtelisto}}"
* (expected result) -> "sxtelista"

* 43 (2 params, 1xx AKA name input, "forced adjective" "eo", forced uppercase, dubious language name "SXtelisto")
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo121|SXtelisto}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo121|SXtelisto}}"
* (expected result) -> "SXtelista"

* 44 (2 params, 1xx AKA name input, long form "id")
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|id110|swedia}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|id110|swedia}}"
* (expected result) -> "bahasa Swedia"

: ---------------------------------------

* 50 (2 params, 1xx AKA name input, last letter must be lowercase, error in the case standardization step)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo100|SvedA}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo100|SvedA}}"
* (expected result) -> "="

* 51 (2 params, 1xx AKA name input, last letter must be "a" or "o", error in the case standardization step)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo100|Svede}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo100|Svede}}"
* (expected result) -> "="

* 52 (2 params, 1xx AKA name input, upper to lower, works even with decorated letters)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo100|CXecxena}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo100|CXecxena}}"
* (expected result) -> "cxecxena"

* 53 (2 params, 1xx AKA name input, lower to upper)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo100|novialo}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo100|novialo}}"
* (expected result) -> "Novialo"

* 54 (2 params, 1xx AKA name input, string too short, "err" used)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo100|o|err=neniu lingvonomo estas unulitera}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo100|o|err=neniu lingvonomo estas unulitera}}"
* (expected result) -> "neniu lingvonomo estas unulitera"

: ---------------------------------------

* 40 (2 params, 2xx AKA separation "eo", separation step fails and error in the case standardization step)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo200|lagom}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo200|lagom}}"
* (expected result) -> "="

* 41 (2 params, 2xx AKA separation "eo", separation step fails)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo200|lagmo}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo200|lagmo}}"
* (expected result) -> "Lagmo"

* 42 (2 params, 2xx AKA separation "eo", separation step succeeds)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo200|(lagmo)}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo200|(lagmo)}}"
* (expected result) -> "Lagmo"

* 43 (2 params, 2xx AKA separation "eo", separation step succeeds)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo200|Vortaro (Indonezia)}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo200|Vortaro (Indonezia)}}"
* (expected result) -> "indonezia"

* 44 (2 params, 2xx AKA separation "id", separation step fails)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|id200|vortaro (Indonezia)}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|id200|vortaro (Indonezia)}}"
* (expected result) -> "Vortaro (Indonezia)"

: ---------------------------------------

* 50 (2 params, 2xx AKA separation "eo", too many brackets, separation step fails and error in the case standardization step)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo200|Vortaro (mojosa) (indonezia)}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo200|Vortaro (mojosa) (indonezia)}}"
* (expected result) -> "="

* 51 (2 params, 2xx AKA separation "eo", too many brackets, separation step fails and misled case standardization step)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo200|Vortaro (mojosa) (indonezia) nova}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo200|Vortaro (mojosa) (indonezia) nova}}"
* (expected result) -> "vortaro (mojosa) (indonezia) nova"

* 52 (2 params, 2xx AKA separation "eo", too short, separation step fails and error in the case standardization step)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo200|Vortaro (i))}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo200|Vortaro (i)}}"
* (expected result) -> "="

* 53 (2 params, 2xx AKA separation "eo", separation step succeeds but error in the case standardization step)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo200|(__)a}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo200|(__)a}}"
* (expected result) -> "="

* 54 (2 params, 2xx AKA separation "eo", too short, separation step fails and misled case standardization step)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo200|(_)a}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo200|(_)a}}"
* (expected result) -> "(_)a"

* 55 (2 params, 2xx AKA separation "eo", too short, separation step fails and misled case standardization step)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo200|()a}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo200|()a}}"
* (expected result) -> "()a"

* 56 (2 params, 2xx AKA separation "id", too short, separation step fails and misled case standardization step)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|id200|a()}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|id200|a()}}"
* (expected result) -> "A()"

* 57 (2 params, 2xx AKA separation "id", too short, separation step fails and error in the case standardization step)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|id200|()a}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|id200|()a}}"
* (expected result) -> "="

: ---------------------------------------

* 80 (2 params, 2xx AKA separation "id")
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|id200|Kata bahasa Korea}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|id200|Kata bahasa Korea}}"
* (expected result) -> "Korea"

* 81 (2 params, 2xx AKA separation "id", no error for us despite miscased)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|id200|Kata bahasa korea}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|id200|Kata bahasa korea}}"
* (expected result) -> "Korea"

* 82 (2 params, 2xx AKA separation "id", no error for us despite multiply miscased)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|id200|kata bahasa korea}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|id200|kata bahasa korea}}"
* (expected result) -> "Korea"

* 83 (2 params, 2xx AKA separation "eo", separation step fails and misled case standardization step)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|eo200|Kata bahasa korea}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|eo200|Kata bahasa korea}}"
* (expected result) -> "kata bahasa korea"

* 84 (2 params, 2xx AKA separation "id", separation step succeeds but error in the case standardization step)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|id200|Kata bahasa ..}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|id200|Kata bahasa ..}}"
* (expected result) -> "="

* 85 (2 params, 2xx AKA separation "id", too short, separation step fails and misled case standardization step)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|id200|kata bahasa X}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|id200|kata bahasa X}}"
* (expected result) -> "Kata bahasa X"

* 86 (2 params, 2xx AKA separation "id", redundant spaces not reduced, separation step succeeds but error in the case standardization step)
* <code><nowiki>{{#invoke:mlngkodnomplus|ek|id200|Bahasa  Bahasa}}</nowiki></code>
* "{{#invoke:mlngkodnomplus|ek|id200|Bahasa  Bahasa}}"
* (expected result) -> "="

: ---------------------------------------

This module is unbreakable (when called with correct module name
and function name).

Cxi tiu modulo estas nerompebla (kiam vokita kun gxustaj nomo de modulo
kaj nomo de funkcio).

]===]

local lngkodnomplus = {}

------------------------------------------------------------------------
---- CONSTANTS ----
------------------------------------------------------------------------

local constrplki = "Module:mpiktbllki" -- EN prefix "Module:" works everywhere

------------------------------------------------------------------------
---- IMPORTS ----
------------------------------------------------------------------------

local piktbllki = require(constrplki) -- can crash here

------------------------------------------------------------------------
---- ORDINARY LOCAL LOW LEVEL FUNCTIONS ----
------------------------------------------------------------------------

-- Local function LFTESTUCLC

-- Test whether char is an uppercase or lowercase ASCII letter, return bool

local function lftestuclc (numcode)
  local boouclc = false
  if ((numcode>64) and (numcode<91)) then
    boouclc = true
  end--if
  if ((numcode>96) and (numcode<123)) then
    boouclc = true
  end--if
  return boouclc
end--function lftestuclc

------------------------------------------------------------------------

-- Local function LFXCASEBEG

-- Set case of beginning letter of a word or group of words to upper
-- or lower, limited unicode support

-- Input  : - strucinut : word or group of words (may be empty)
--          - booucas : "true" for uppercase and "false" for lowercase output

local function lfxcasebeg (strucinut,booucas)
  local numlein = 0
  local numchaer = 0
  local numchaes = 0
  local numcut = 1 -- becomes 2 for unicode char:s
  local booc3blok = false
  local booc4c5bl = false
  local booisuppr = false
  local booislowr = false
  numlein = string.len(strucinut)
  if (numlein~=0) then
    numchaer = string.byte(strucinut,1,1)
    if ((numchaer>127) and (numlein>=2)) then
      numchaes = string.byte(strucinut,2,2)
      numcut = 2
    end--if
    if (numcut==1) then
      booisuppr = ((numchaer>64) and (numchaer< 91))
      booislowr = ((numchaer>96) and (numchaer<123))
      if (booisuppr and (booucas==false)) then
        numchaer = numchaer+32 -- ASCII UPPER->lower
      end--if
      if (booislowr and booucas) then
        numchaer = numchaer-32 -- ASCII lower->UPPER
      end--if
    else
      booc3blok = (numchaer==195) -- case delta is 32
      booc4c5bl = ((numchaer==196) or (numchaer==197)) -- case delta is 1
      if (booc3blok) then
        if ((numchaes>=128) and (numchaes<160)) then
          booisuppr = true -- C3,80...C3,9F
        end--if
        if ((numchaes>=160) and (numchaes<192)) then
          booislowr = true -- C3,A0...C3,BF
        end--if
      end--if
      if (booc4c5bl) then
        if ((numchaes%2)==0) then
          booisuppr = true
        else
          booislowr = true
        end--if
      end--if
      if (booc3blok and booisuppr and (booucas==false)) then
        numchaes = numchaes+32 -- UC UPPER->lower -- holds f AA AE EE NN OE UE
      end--if
      if (booc3blok and booislowr and booucas) then
        numchaes = numchaes-32 -- UC lower->UPPER -- holds f aa ae ee nn oe ue
      end--if
      if (booc4c5bl and booisuppr and (booucas==false)) then
        numchaes = numchaes+1 -- UC UPPER->lower -- holds for JX SX ...
      end--if
      if (booc4c5bl and booislowr and booucas) then
        numchaes = numchaes-1 -- UC lower->UPPER -- holds for jx sx ...
      end--if
    end--if (numcut==1) else
    if (numlein>numcut) then
      strucinut = string.sub(strucinut,(numcut+1),numlein) -- remaining part
    else
      strucinut = "" -- we had just 1 char
    end--if
    if (numcut==1) then
      strucinut = string.char(numchaer) .. strucinut
    else
      strucinut = string.char(numchaer) .. string.char(numchaes) .. strucinut
    end--if
  end--if
  return strucinut
end--function lfxcasebeg

------------------------------------------------------------------------

-- Local function LFKOMPINSEN

-- Compare 2 strings case insensitively to the earliest
-- letter, limited unicode support

-- Input  : - straa, strbb

-- Output : - booeql : "true" if they are equal

local function lfkompinsen (straa,strbb)
  local booeql = false
  straa = lfxcasebeg (straa,true)
  strbb = lfxcasebeg (strbb,true)
  if (straa==strbb) then
    booeql = true
  end--if
  return booeql
end--function lfkompinsen

------------------------------------------------------------------------
---- MAIN EXPORTED FUNCTION ----
------------------------------------------------------------------------

function lngkodnomplus.ek (arxframent)

  -- general unknown type

  local vartmp = 0     -- variable without type

  -- special type "args" AKA "arx"

  local arxourown = 0  -- metaized "args" from our own "frame" (NOT caller's)

  -- general "str"

  local strctl    = ""   -- control string (5 digits)
  local strin3put = ""   -- input string (3 possible types)
  local strret    = ""   -- output string
  local strerrequ = "="  -- default or alterna string to replace "=" on error
  local strtmp    = ""

  -- general "num"

  local numoct    = 0  -- temp some char
  local numodt    = 0  -- temp some other char
  local numlong   = 0  -- length of parameter
  local numityp   = 0  -- ZERO code | 1 name | 2 longer string
  local numuskl   = 0  -- ZERO native | 1 upper | 2 lower
  local numindeks = 0  -- ONE-based char index
  local numbeg    = 0  -- ONE-based position begin of pick
  local numend    = 0  -- ONE-based position inclusive end of pick

  -- general "boo"

  local booerr    = false  -- fatal error flag
  local boositid  = false  -- (a) -- "false" is "eo" | "true" is "id"
  local boolngfrm = false  -- (c)=1 -- long form with "la" or "bahasa"
  local booforadj = false  -- (c)=2 -- forced adjective form "eo" only

  ---- SEIZE 2 OBLIGATORY ANONYMOUS PARAMETERS SENT TO US ----

  -- control string (5 octet:s)
  -- input string (2...80 octet:s now but stricter checks done later)

  arxourown = arxframent.args -- "args" from our own "frame"

  if ((arxourown[1]==nil) or (arxourown[2]==nil) or (arxourown[3])) then
    booerr = true -- need 2 obligatory params, 3 are not appreciated
  else
    strctl = arxourown[1]
    numlong = string.len (strctl) -- octet length of the input string
    if (numlong~=5) then
      booerr = true -- must be 5 octet:s
    end--if
    strin3put = arxourown[2]
    numlong = string.len (strin3put) -- octet length of the input string
    if ((numlong<2) or (numlong>80)) then
      booerr = true -- must be 2...80 octet:s
    end--if
  end--if

  ---- SEIZE OPTIONAL NAMED PARAMETER SENT TO US EVEN IF WE ALREADY SUCK ----

  -- try to pick named parameter "err=" even if we already have "booerr==true"

  vartmp = arxourown["err"] -- 1...64 char:s alternative string to replace "="
  if (type(vartmp)=="string") then
    numlong = string.len (vartmp) -- temp
    if ((numlong<1) or (numlong>64)) then
      booerr = true -- caused an error instead of catching such
    else
      strerrequ = vartmp -- was preset to "="
    end--if
  end--if

  ---- ANALYZE THE CONTROL STRING ----

  -- assign "numityp" (2 is longer), "boolngfrm", "booforadj",
  -- "numuskl" (2 is lower)

  if (booerr==false) then
    strtmp = string.sub(strctl,1,2) -- (a)
    if (strtmp=="id") then
      boositid = true
    else
      if (strtmp~="eo") then
        booerr = true -- jaevlar
      end--if
    end--if
    numityp = string.byte (strctl,3,3) - 48 -- (b) tristate input type
    if ((numityp<0) or (numityp>2)) then
      booerr = true -- jaevlar
    end--if
    numoct = string.byte (strctl,4,4) - 48 -- (c) tristate long or adjective
    if ((numoct<0) or (numoct>2)) then
      booerr = true -- jaevlar
    end--if
    if (numoct==1) then
      boolngfrm = true -- (c)=1
    end--if
    if (numoct==2) then
      if (boositid==true) then
        booerr = true -- jaevlar (no forced adjective for "id")
      else
        booforadj = true -- (c)=2
      end--if
    end--if
    numuskl = string.byte (strctl,5,5) - 48 -- (d) tristate uskleco
    if ((numuskl<0) or (numuskl>2)) then
      booerr = true -- jaevlar
    end--if
  end--if

 ---- TRANSLATE LANGUAGE CODE IF REQUESTED ----

 -- via module "mpiktbllki" and can cause an error

  if ((booerr==false) and (numityp==0)) then
    numlong = string.len (strin3put) -- octet length of the input string
    if ((numlong<2) or (numlong>3)) then
      booerr = true -- must be 2...3 octet:s
    end--if
    strin3put = piktbllki.ek { args = { strin3put , "0" , "1" , "=" } }
    if (strin3put=="=") then
      booerr = true -- jaevlar -- bad language code
    end--if
  end--if

  ---- CHECK FOR 60 OCTET:S LIMIT IF APPROPRIATE ----

  -- this can cause an error

  if ((booerr==false) and (numityp==1)) then
    numlong = string.len (strin3put)
    if (numlong>60) then
      booerr = true -- jaevlar -- must be 2...60 octet:s
    end--if
  end--if

  ---- PERFORM THE SEPARATION IF REQUESTED ----

  -- this can fail but NOT cause an error

  if ((booerr==false) and (numityp==2)) then

    numlong = string.len (strin3put) -- length of maybe translated input str

    if ((boositid==false) and (numlong>=4)) then
      numindeks = 1
      while (true) do
        if (numindeks>numlong) then
          break -- ONE-based -- if both "numbeg" "numend" non-ZERO then maybe
        end--if
        numoct = string.byte(strin3put,numindeks,numindeks)
        if (numoct==40) then -- "("
          if (numbeg==0) then
            numbeg = numindeks + 1 -- begin pos after "("
          else
            numbeg = 0
            break -- damn: more then 1 "("
          end--if
        end--if
        if (numoct==41) then -- ")"
          if ((numend==0) and (numindeks~=1)) then
            numend = numindeks - 1 -- end pos before ")"
          else
            numend = 0
            break -- damn: more then 1 ")" or begins with ")"
          end--if
        end--if
        numindeks = numindeks + 1
      end--while
      if ((numbeg+1)>numend) then
        numbeg = 0 -- part between brackets is too short, invalidate result
      end--if
    end--if ((boositid==false) and (numlong>=4))

    if ((boositid==false) and (numbeg==0) and (numlong>=5)) then
      if (lfkompinsen(string.sub(strin3put,1,3),"la ")) then
        numbeg = 4
        numend = numlong
      end--if
    end--if

    if (boositid and (numbeg==0) and (numlong>=9)) then
      if (lfkompinsen(string.sub(strin3put,1,7),"bahasa ")) then
        numbeg = 8
        numend = numlong
      end--if
    end--if

    if (boositid and (numbeg==0) and (numlong>=14)) then
      if (lfkompinsen(string.sub(strin3put,1,12),"kata bahasa ")) then
        numbeg = 13
        numend = numlong
      end--if
    end--if

    if ((numbeg~=0) and (numend~=0)) then
      strin3put = string.sub(strin3put,numbeg,numend) -- separate substring
    end--if

  end--if ((booerr==false) and (numityp==2)) then

  ---- BREW THE ADJECTIVE FORM IF REQUESTED ----

  -- "eo" only if (c)=2

  -- here we only change "o" to "a", case change done below

  -- this CANNOT cause an error

  if ((booerr==false) and booforadj) then
    numlong = string.len (strin3put) -- length of maybe multihacked input str
    numoct = string.byte(strin3put,numlong,numlong) -- last letter ie octet
    if (numoct==111) then
      strin3put = string.sub(strin3put,1,(numlong-1)) .. "a" -- "o"->"a" "eo"
    end--if
  end--if

  ---- PERFORM THE CASE STANDARDIZATION FOR ANY TYPE OF INPUT ----

  -- irrespective of input type and this can cause an error

  -- note that variable "numoct" is passed to next section

  if (booerr==false) then

    numlong = string.len (strin3put) -- length of maybe multihacked input str
    numoct = string.byte(strin3put,numlong,numlong) -- last letter ie octet
    numodt = string.byte(strin3put,1,1) -- earliest letter ie octet

    if (boositid==false) then -- "eo"
      if (numoct==97) then
        strin3put = lfxcasebeg (strin3put,false) -- "a" AJ -> lowercase
      else
        if (numoct==111) then
          strin3put = lfxcasebeg (strin3put,true) -- "o" SB -> uppercase
        else
          booerr = true -- jaevlar (neither "a" nor "o")
        end--if
      end--if
    else
      if (lftestuclc(numodt)) then
        strin3put = lfxcasebeg (strin3put,true) -- always uppercase
      else
        booerr = true -- jaevlar (NOT a letter)
      end--if
    end--if

  end--if

  ---- BREW THE LONG FORM IF REQUESTED ----

  -- "eo" or "id" if (c)=1

  -- this CANNOT cause an error

  -- note that variable "numoct" is passed from previous section

  if ((booerr==false) and boolngfrm) then
    if (boositid==false) then -- "eo"
      if (numoct==97) then
        strin3put = "la " .. strin3put -- "eo" only for AJ
      end--if
    else
      strin3put = "bahasa " .. strin3put -- "id" always
    end--if
  end--if

  ---- ADJUST THE CASE OF THE COMPLETE RESULT IF REQUESTED ----

  -- this CANNOT cause an error

  -- "numuskl" (1 upper | 2 lower)

  if (booerr==false) then
    if (numuskl==1) then
      strin3put = lfxcasebeg (strin3put,true) --  uppercase
    end--if
    if (numuskl==2) then
      strin3put = lfxcasebeg (strin3put,false) -- lowercase
    end--if
  end--if

  ---- PREPARE ----

  if (booerr==true) then
    strret = strerrequ -- error -- string "strret" was preset to empty
  else
    strret = strin3put -- valid result
  end--if

  ---- RETURN THE JUNK STRING ----

  return strret

end--function

  ---- RETURN THE JUNK LUA TABLE ----

return lngkodnomplus