Modulo:maudilingdial
Aspekto
MODULO | ||
Memtesto disponeblas sur la dokumentaĵa subpaĝo. |
|
- vokata sole el
{{aŭdo}}
, dependas de Modulo:loaddata-tbllingvoj
--[===[
MODULE "MAUDILINGDIAL" (audio lingvo dialekto)
"eo.wiktionary.org/wiki/Modulo:maudilingdial" <!--2023-Aug-07-->
Purpose: picks language and dialect codes from name of an audio file
or explicit override parameters "ling=" and "dial="
Utilo: elprenas lingvan kaj dialektan kodon el nomo de sondosiero
aux eksplicitaj transpasaj parametroj "ling=" kaj "dial="
Used by templates / Uzata far sxablonoj:
- "auxdo"
Required submodules / Bezonataj submoduloj / Submodul yang diperlukan:
- "loaddata-tbllingvoj" in turn requiring template "tbllingvoj" (EO)
- "loaddata-tblbahasa" in turn requiring template "tblbahasa" (ID)
Incoming: - 3 anonymous obligatory parameters (can cause an error)
- name of the audio file (caller must forward it to us)
(5...120 octet:s to prevent error, further limits
apply for seizures)
- type of information to seize: "l" for "ling" or "d" for "dial"
- default value for result if seizure fails (1...32 octet:s),
even this one will get victim of case fixing if 2...3 char:s
- 2 named optional parameters (CANNOT cause an error, caller
must forward them to us by "ling={{{ling}}}" etc, wall "|"
is NOT needed, all 1...32 octet:s, rejected and ignored if
it begins with curly "{")
- "ling=" (should be code, other text not appreciated here)
- "dial=" (can be code or other text)
Returned: - code (2 or 3 letters) or other text picked from name of the
audio file or provided override parameter "ling=" or "dial=" if
available, or default string (from anonymous obligatory parameter)
otherwise, case is fixed to lowercase ("l") or uppercase ("d")
if 2 or 3 letters, or unchanged otherwise (can occur only with
"dial=" parameter and theoretically even with "ling=" parameter,
at worst hardcoded string "=" if an error occurs (bad anonymous
obligatory parameters)
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).
There are 2 common naming patterns for pronunciation files at
"Commons" and we support them both:
* (traditional pattern) "en-us-rail.oga" with dialect or
"en-rail.oga" without dialect
* (LLQ pattern, "Lingua Libre")
"LL-Q143 (epo)-Mojosulo-nenio.wav" always without dialect
Early branching checks:
In order to qualify for the LLQ pattern the name must (and applies):
* be at least 22 char:s long (this means at least 2 char:s user name with
3-digit number and 1 char word and 3+1 char:s extension)
* begin with "LL-Q" (exact case sensitive comparison) and the following
char must be a digit
Otherwise it is considered as traditional pattern. This means also that
a dialect cannot be found if LLQ pattern is detected, no attempt to read
it via traditional pattern is made.
Subsequent checks:
- 3...9 digits ("Q100"..."Q999999999", actually "100"..."999999999")
- Q-item successfully converted via "T81-1" from "loaddata-tbllingvoj"
Failure here means no pick and give up, not fallback to traditional pattern.
We completely ignore the later following ISO 639-3:2007 code in any case.
Usage examples with results / Ekzemploj de uzo
kun rezultoj / Contoh penggunaan dengan hasil:
{{hr3}} <!-------------------------------->
* #T00 (no params, too few)
* expected result: "="
* actual result: "{{#invoke:maudilingdial|ek}}"
::* #T01 (two params, still too few)
::* expected result: "="
::* actual result: "{{#invoke:maudilingdial|ek|nonsense|bullshit}}"
* #T02 ({maudilingdial|ek|four|l|nine}, 3 params, left one bad)
* expected result: "="
* actual result: "{{#invoke:maudilingdial|ek|four|l|nine}}"
::* #T03 ({maudilingdial|ek|seven|eight|nine}, 3 params, middle one bad)
::* expected result: "="
::* actual result: "{{#invoke:maudilingdial|ek|seven|eight|nine}}"
* #T04 ({maudilingdial|ek|seven|d|abcdefghijklmnopxabcdefghijklmnop}, 3 params, right one bad)
* expected result: "="
* actual result: "{{#invoke:maudilingdial|ek|seven|d|abcdefghijklmnopxabcdefghijklmnop}}"
{{hr3}} <!-------------------------------->
* #T10 ({maudilingdial|ek|en-us-rail.oga|l|-}, request "l" and SUCCESS)
* expected result: "en"
* actual result: "{{#invoke:maudilingdial|ek|en-us-rail.oga|l|-}}"
::* #T11 ({maudilingdial|ek|en-us-rail.oga|d|-}, request "d" and SUCCESS)
::* actual result: "{{#invoke:maudilingdial|ek|en-us-rail.oga|d|-}}"
::* expected result: "US"
* #T12 (maudilingdial|ek|en-us-r.oga|d|-}, request "d" and SUCCESS, equal minimum, valid)
* expected result: "US"
* actual result: "{{#invoke:maudilingdial|ek|en-us-r.oga|d|-}}"
::* #T13 ({maudilingdial|ek|en-us+r.oga|d|xx}, request "d" and FAILURE, equal minimum but only one dash "-" in filename)
::* expected result: "XX" (uppercase even here)
::* actual result: "{{#invoke:maudilingdial|ek|en-us+r.oga|d|xx}}"
* #T14 ({maudilingdial|ek|en-us+r.oga|d|xxxx}, request "d" and FAILURE, equal minimum but only one dash "-" in filename)
* expected result: "xxxx" (NOT uppercase)
* actual result: "{{#invoke:maudilingdial|ek|en-us+r.oga|d|xxxx}}"
::* #T15 ({maudilingdial|ek|en-us-r.og|d|-}, request "d" and FAILURE, length below minimum)
::* expected result: "-"
::* actual result: "{{#invoke:maudilingdial|ek|en-us-r.og|d|-}}"
* #T16 ({maudilingdial|ek|eN-uS-rail.oga|d|-}, request "d" and SUCCESS, tolerable strange case)
* expected result: "US"
* actual result: "{{#invoke:maudilingdial|ek|eN-uS-rail.oga|d|-}}"
::* #T17 ({maudilingdial|ek|pen-bus-rail.oga|l|-}, request "l" and SUCCESS)
::* expected result: "pen"
::* actual result: "{{#invoke:maudilingdial|ek|pen-bus-rail.oga|l|-}}" (3+3)
* #T18 ({maudilingdial|ek|pen-bus-rail.oga|d|-}, request "d" and SUCCESS)
* expected result: "BUS"
* actual result: "{{#invoke:maudilingdial|ek|pen-bus-rail.oga|d|-}}" (3+3)
{{hr3}} <!-------------------------------->
* #T20 ({maudilingdial|ek|en-abus-rail.oga|l|-}, request "l" and SUCCESS, although "d" in filename is bad)
* expected result: "en"
* actual result: "{{#invoke:maudilingdial|ek|en-abus-rail.oga|l|-}}"
::* #T21 ({maudilingdial|ek|en-abus-rail.oga|d|-}, request "d" and FAILURE, since "d" in filename is bad)
::* expected result: "-"
::* actual result: "{{#invoke:maudilingdial|ek|en-abus-rail.oga|d|-}}"
* #T22 ({#invoke:maudilingdial|ek|entr-us-rail.oga|l|-}, bad "l" NOT found)
* expected result: "-"
* actual result: "{{#invoke:maudilingdial|ek|entr-us-rail.oga|l|-}}"
::* #T23 ({#invoke:maudilingdial|ek|entr-us-rail.oga|d|-}, "d" NOT found since "l" bad)
::* expected result: "-"
::* actual result: "{{#invoke:maudilingdial|ek|entr-us-rail.oga|d|-}}"
{{hr3}} <!-------------------------------->
* #T30 ({maudilingdial|ek|en-us-rail.oga|l|-|ling=id}, request "l", parameter "ling=" overrides)
* expected result: "id"
* actual result: "{{#invoke:maudilingdial|ek|en-us-rail.oga|l|-|ling=id}}"
::* #T31 ({maudilingdial|ek|en-us-rail.oga|l|-|dial=uk}, "dial=" supplied but request "l", no override)
::* expected result: "en"
::* actual result: "{{#invoke:maudilingdial|ek|en-us-rail.oga|l|-|dial=uk}}"
* #T32 ({maudilingdial|ek|en-us-rail.oga|d|-|dial=uk}, request "d", parameter "dial=" overrides)
* expected result: "UK"
* actual result: "{{#invoke:maudilingdial|ek|en-us-rail.oga|d|-|dial=uk}}"
::* #T33 ({maudilingdial|ek|en-us-rail.oga|d|-|dial=Fuk}, request "d", parameter "dial=" overrides)
::* expected result: "FUK"
::* actual result: "{{#invoke:maudilingdial|ek|en-us-rail.oga|d|-|dial=Fuk}}"
* #T34 ("dial=Fusk")
* expected result: "Fusk"
* actual result: "{{#invoke:maudilingdial|ek|en-us-rail.oga|d|-|dial=Fusk}}"
::* #T35 ("dial=(uk)", bad but acceptable for us)
::* expected result: "(uk)"
::* actual result: "{{#invoke:maudilingdial|ek|en-us-rail.oga|d|-|dial=(uk)<!--o-->}}"
* #T36 ("dial={uk}", rejected due to curly at begin)
* expected result: "US"
* actual result: "{{#invoke:maudilingdial|ek|en-us-rail.oga|d|-|dial={uk}<!--o-->}}"
{{hr3}} <!-------------------------------->
* #T40 ({maudilingdial|ek|LL-Q143 (epo)-Mojosulo-nenio.wav|l|damn}, request "l")
* expected result: "eo"
* actual result: "{{#invoke:maudilingdial|ek|LL-Q143 (epo)-Mojosulo-nenio.wav|l|damn}}"
::* #T41 ({maudilingdial|ek|LL-Q1405077 (zepo)-Mojosulo-nuenio.wav|l|damn}, request "l")
::* expected result: "kj"
::* actual result: "{{#invoke:maudilingdial|ek|LL-Q1405077 (zepo)-Mojosulo-nuenio.wav|l|damn}}"
* #T42 ({maudilingdial|ek|LL-Q143 (epo)-Mojosulo-nenio.wav|d|damn}, request "d", no dialect exists)
* expected result: "damn"
* actual result: "{{#invoke:maudilingdial|ek|LL-Q143 (epo)-Mojosulo-nenio.wav|d|damn}}"
::* #T43 ({maudilingdial|ek|LL-P143 (epo)-Mojosulo-nenio.wav|l|damn}, request "l")
::* expected result: "ll" (name is invalid for LLQ pattern and thus processed as traditional with bad result)
::* actual result: "{{#invoke:maudilingdial|ek|LL-P143 (epo)-Mojosulo-nenio.wav|l|damn}}"
* #T44 ({maudilingdial|ek|LL-Q99 (zep)-Mojosulo-nuen.wav|l|damn}, request "l", number too short)
* expected result: "damn"
* actual result: "{{#invoke:maudilingdial|ek|LL-Q99 (zep)-Mojosulo-nuen.wav|l|damn}}"
::* #T45 ({maudilingdial|ek|LL-Q9999999999 (zzp)-Malmojosulo-xxnuen.wav|l|toolong}, request "l", number too long)
::* expected result: "toolong"
::* actual result: "{{#invoke:maudilingdial|ek|LL-Q9999999999 (zzp)-Malmojosulo-xxnuen.wav|l|toolong}}"
* #T46 ({maudilingdial|ek|LL-Q1405077 (zep)-Mojosulo-nuenio.wav|l|damn|ling=SV}, request "l", parameter "ling=" overrides)
* expected result: "sv"
* actual result: "{{#invoke:maudilingdial|ek|LL-Q1405077 (zep)-Mojosulo-nuenio.wav|l|damn|ling=SV}}"
{{hr3}} <!-------------------------------->
]===]
local exporttable = {}
------------------------------------------------------------------------
---- CONSTANTS [O] ----
------------------------------------------------------------------------
-- uncommentable EO vs ID constant strings (core site-related features, "constrpriv" NOT needed)
local constringvoj = "Modulo:loaddata-tbllingvoj" -- EO
-- local constringvoj = "Modul:loaddata-tblbahasa" -- ID
------------------------------------------------------------------------
---- SPECIAL STUFF OUTSIDE MAIN [B] ----
------------------------------------------------------------------------
---- SPECIAL VAR:S ----
local qldingvoj = {} -- type "table" and nested
local qbooguard = false -- only for the guard test, pass to other var ASAP
---- GUARD AGAINST INTERNAL ERROR AND IMPORT ONE VIA LOADDATA ----
qbooguard = (type(constringvoj)~='string')
if (not qbooguard) then
qbooguard = (constringvoj=='')
end--if
if (not qbooguard) then
qldingvoj = mw.loadData(constringvoj) -- can crash here
qbooguard = (type(qldingvoj)~='table') -- seems to be always false
end--if
------------------------------------------------------------------------
---- LOW LEVEL STRING FUNCTIONS [G] ----
------------------------------------------------------------------------
-- test whether char is an ASCII digit "0"..."9", return boolean
local function lfgtestnum (numkaad)
local boodigit = false
boodigit = ((numkaad>=48) and (numkaad<=57))
return boodigit
end--function lfgtestnum
------------------------------------------------------------------------
-- test whether char is an ASCII uppercase letter, return boolean
local function lfgtestuc (numkode)
local booupperc = false
booupperc = ((numkode>=65) and (numkode<=90))
return booupperc
end--function lfgtestuc
------------------------------------------------------------------------
-- test whether char is an ASCII lowercase letter, return boolean
local function lfgtestlc (numcode)
local boolowerc = false
boolowerc = ((numcode>=97) and (numcode<=122))
return boolowerc
end--function lfgtestlc
------------------------------------------------------------------------
-- Local function LFTESTLITERO
-- Test whether supplied char is an ASCII letter (65...90 and 97...122).
-- Depends on functions :
-- [G] lfgtestuc lfgtestlc
local function lftestlitero (numinkoo)
local boorezult = false
boorezult = lfgtestuc (numinkoo) or lfgtestlc (numinkoo)
return boorezult
end--function lftestlitero
------------------------------------------------------------------------
-- Local function LFFIXCASE
-- Adjust letter case of all ASCII letters in a string, other
-- char:s untouched.
-- Input : * strmasuk -- string (empty tolerable)
-- * booupper -- "true" for uppercase and "false" for lowercase
-- Output : * strkeluar -- string
-- Depends on functions :
-- [G] lfgtestuc lfgtestlc
local function lffixcase (strmasuk,booupper)
local strkeluar = ""
local numlejn = 0
local numindexx = 0 -- ZERO-based
local numchar = 0
numlejn = string.len (strmasuk)
while true do
if (numindexx==numlejn) then
break
end--if
numchar = string.byte (strmasuk,(numindexx+1),(numindexx+1))
if (lfgtestuc(numchar) and (not booupper)) then
numchar = numchar + 32
end--if
if (lfgtestlc(numchar) and booupper) then
numchar = numchar - 32
end--if
strkeluar = strkeluar .. string.char (numchar)
numindexx = numindexx + 1
end--while
return strkeluar
end--function lffixcase
------------------------------------------------------------------------
---- HIGH LEVEL FUNCTIONS [H] ----
------------------------------------------------------------------------
-- Local function LFVALI1X32NOCUR
-- Validate a string (length 1...32 octet:s, must not begin with "{").
-- Input : * stryyn : string
-- Output : * booisvalid : "true" if the string is valid
local function lfvali1x32nocur (stryyn)
local numomongkosong = 0
local booisvalid = false -- preASSume guilt
numomongkosong = string.len (stryyn)
if ((numomongkosong~=0) and (numomongkosong<=32)) then
numomongkosong = string.byte (stryyn,1,1)
booisvalid = (numomongkosong~=123) -- curly "{" is a crime
end--if
return booisvalid
end--function lfvali1x32nocur
------------------------------------------------------------------------
-- Local function LFPICKDASH
-- Pick a dash-delimited substring (2 or 3 char:s) from given
-- position of a string.
-- Input : * straudio : string (example: "en-uk-nonsense.oga")
-- * numzpos : ZERO-based position of start
-- Output : * strkode : result (empty string if no pick)
-- Picking occurs if:
-- * remaining length from "numzpos" to end is at least 8 octet:s
-- * there is a dash at relative position + 2 or + 3
-- * there are at least 5 octet:s left after the dash at relative + 3
-- * char at given position is a letter
-- * char at next position and maybe overnext position is a letter
-- Depends on functions :
-- [G] lftestlitero
local function lfpickdash (straudio,numzpos)
local strkode = ''
local numlenn = 0
local numdpos = 0 -- ZERO-based position of dash
local numascii = 0
local boogottri = false
while true do -- fake loop
numlenn = string.len (straudio)
if ((numzpos+8)>numlenn) then
break -- to join mark -- NOT at least 8 octet:s after "numzpos"
end--if
numascii = string.byte (straudio,(numzpos+3),(numzpos+3)) -- pos + 2
if (numascii==45) then
numdpos = numzpos+2 -- found a dash at + 2 !!!
else
numascii = string.byte (straudio,(numzpos+4),(numzpos+4)) -- pos + 3
if ((numascii==45) and ((numzpos+8)<numlenn)) then
numdpos = numzpos+3 -- found a dash and at least 9 char:s left !!!
boogottri = true
end--if
end--if
if (numdpos==0) then
break -- to join mark -- no Boulder Dash found
end--if
numascii = string.byte (straudio,(numzpos+1),(numzpos+1))
if (lftestlitero(numascii)==false) then
break -- to join mark -- no letter at + 0
end--if
numascii = string.byte (straudio,(numzpos+2),(numzpos+2))
if (lftestlitero(numascii)==false) then
break -- to join mark -- no letter at + 1
end--if
if (boogottri) then
numascii = string.byte (straudio,(numzpos+3),(numzpos+3))
if (lftestlitero(numascii)==false) then
break -- to join mark -- no letter at + 2
end--if
end--if
strkode = string.sub (straudio,(numzpos+1),numdpos) -- do NOT include "-"
break -- finally to join mark -- success
end--while -- fake loop -- join mark
return strkode
end--function lfpickdash
------------------------------------------------------------------------
-- Local function LFVALILLQ
-- Detect possible LLQ pattern, return boolean.
-- Example: "LL-Q143 (epo)-Mojosulo-nenio.wav"
-- Depends on functions :
-- [G] lfgtestnum
local function lfvalillq (straudiollq)
local numjunklen = 0
local numjunkchr = 0
local booisllqjes = false
while true do -- fake loop
numjunklen = string.len (straudiollq)
if (numjunklen<22) then
break -- too short
end--if
if (string.sub(straudiollq,1,4)~="LL-Q") then
break -- too bad
end--if
numjunkchr = string.byte (straudiollq,5,5)
booisllqjes = lfgtestnum (numjunkchr) -- success or failure
break -- finally to join mark
end--while -- fake loop -- join mark
return booisllqjes
end--function lfvalillq
------------------------------------------------------------------------
-- Local function LFPICKLLQ
-- Try to pick a Q-number (WikiData item) as a substring.
-- String must be already validated, among others >= 22 char:s. This means
-- that we do NOT have to bother about possible end of it since we run from
-- one-based pos 5 to 14 max far away from the dangerous end.
-- Need 3...9 digits for "Q100"..."Q999999999", actually "100"..."999999999".
-- Input : * strllqaudi : string (example: "LL-Q143 (epo)-Anon-nenio.wav")
-- Output : * strkodde : result as string (for example "Q143", empty
-- string if no pick)
-- Depends on functions :
-- [G] lfgtestnum
local function lfpickllq (strllqaudi)
local strkodde = "Q" -- type "string" or "nil"
local numddpos = 5 -- ONE-based position
local numeating = 0 -- char code, start eating __AFTER__ the "Q"
while true do
if (numddpos==15) then
break -- damn, number too long
end--if
numeating = string.byte (strllqaudi,numddpos,numddpos)
if (not lfgtestnum(numeating)) then
break -- good or bad
end--if
strkodde = strkodde .. string.char (numeating) -- "100"..."999999999" vali
numddpos = numddpos + 1
end--while
if ((numddpos<8) or (numddpos==15)) then
strkodde = "" -- 8 means 3 digits (good) ... 15 means 10 digits (bad)
end--if
return strkodde
end--function lfpickllq
------------------------------------------------------------------------
---- VARIABLES [R] ----
------------------------------------------------------------------------
function exporttable.ek (arxframent)
-- general unknown type "var"
local vartmp = 0 -- variable without type multipurpose
-- special type "args" AKA "arx"
local arxourown = 0 -- metaized "args" from our own "frame" (NOT caller's)
-- general "str"
local strnam = '' -- incoming parameter filename
local strret = '' -- incoming parameter default output and output string
local strling = '' -- override parameter or empty string
local strdial = '' -- override parameter or empty string
local strtump = ''
-- general "num"
local numlong = 0 -- length of parameter
local numoct = 0 -- temp some char
-- general "boo"
local booerr = false -- fatal error flag
local boodia = false -- false for "l" and true for "d"
------------------------------------------------------------------------
---- MAIN [Z] ----
------------------------------------------------------------------------
---- GUARD AGAINST INTERNAL ERROR ----
booerr = qbooguard
---- PICK ONE SUBTABLE ----
while true do -- fake loop
if (booerr) then
break -- to join mark
end--if
num2statcode = qldingvoj[2] -- risk of type "nil"
if (num2statcode~=0) then
booerr = true -- #E02 malica
break -- to join mark
end--if
tab811colone = qldingvoj['T81-1'] -- WikiData Q-item -> langcode
if (type(tab811colone)~='table') then -- important check
booerr = true -- #E02 malica
break -- to join mark
end--if
break -- finally to join mark
end--while -- fake loop -- join mark
---- SEIZE 3 ANON OBLIGATORY PARAMETERS FROM CALLER ----
-- assign "strnam" and "boodia" and "strret"
arxourown = arxframent.args -- "args" from our own "frame" only
if ((arxourown[1]==nil) or (arxourown[2]==nil) or (arxourown[3]==nil) or (arxourown[4])) then
booerr = true -- need 3 obligatory params, 4 are not appreciated
else
strnam = arxourown[1] -- name of the audio file
numlong = string.len(strnam)
if ((numlong<5) or (numlong>120)) then
booerr = true -- must be 5...120 octet:s
end--if
strtump = arxourown[2] -- only "l" or "d" -- becomes a boolean
numlong = string.len(strtump)
if (numlong~=1) then
booerr = true -- must be 1 octet
else
numoct = string.byte(strtump,1,1)
if (numoct==100) then
boodia = true
else
if (numoct~=108) then
booerr = true -- only "l" or "d" tolerable
end--if
end--if (numoct==100) else
end--if (numlong~=1) else
strret = arxourown[3] -- string 1...32 -- next-worst default result
numlong = string.len(strret)
if ((numlong==0) or (numlong>32)) then
booerr = true -- must be 1...32 octet:s
end--if
end--if
---- SEIZE 2 NAMED OPTIONAL PARAMETERS FROM CALLER ----
-- seize (ling,dial) into (strling,strdial)
-- both 1...32 octet:s, rejected if it begins with "{", but no "booerr=true"
-- otherwise leave (strling,strdial) empty
-- no error possible here
vartmp = arxourown["ling"]
if (type(vartmp)=="string") then
if (lfvali1x32nocur(vartmp)) then
strling = vartmp
end--if
end--if
vartmp = arxourown["dial"]
if (type(vartmp)=="string") then
if (lfvali1x32nocur(vartmp)) then
strdial = vartmp
end--if
end--if
---- CARRY OUT THE HARD WORK ----
-- "strret" is prefilled from arxourown[3] with next-worst default
-- result length 1...32 char:s, it CANNOT be empty (very worst is "=")
-- (strling,strdial) independently contain override code or are empty
if (booerr) then
strret = "=" -- damn (hardcoded worst error string)
else
if (boodia) then
strtump = strdial -- "d" override but can also be empty
else
strtump = strling -- "l" override but can also be empty
end--if
if (strtump~="") then
strret = strtump -- repl nxwor defa fr arxourown[3] by "ling=" or "dial="
else
if (lfvalillq(strnam)) then -- LLQ pattern
if (not boodia) then
strtump = lfpickllq (strnam) -- attempt to pick substring
if (strtump~='') then
strtump = tab811colone[strtump] -- attempt convert into langcode
if (type(strtump)~='string') then
strtump = '' -- finally out of luck, no langcode
end--if
end--if
end--if
else
strtump = lfpickdash (strnam,0) -- try to pick "l" but can be empty
numlong = string.len (strtump)
if (boodia and (numlong~=0)) then
strtump = lfpickdash (strnam,(numlong+1)) -- try to pick "d" but ...
end--if
end--if (lfvalillq(strnam)) else
if (strtump~="") then
strret = strtump -- use successful pick, otherwise leave next-worst
end--if
end--if (strtump~="") else
numlong = string.len (strret) -- "strret" CANNOT be empty here
if ((numlong==2) or (numlong==3)) then
strret = lffixcase (strret,boodia) -- lowercase "l" -- uppercase "d"
end--if
end--if
---- RETURN THE JUNK STRING ----
return strret
end--function
---- RETURN THE JUNK LUA TABLE ----
return exporttable