Modulo:mpiktbllki
Salti al navigilo
Salti al serĉilo
|
Memtesto disponeblas sur la dokumentaĵa subpaĝo |
--[===[
MODULE "MPIKTBLLKI" (pick from table lingvokodo al info)
"eo.wiktionary.org/wiki/Modulo:mpiktbllki" <!--2021-Jan-01-->
"id.wiktionary.org/wiki/Modul:mpiktbllki"
Purpose: picks an element from a raw two-dimensional table, or more
precisely from "tbllingvoj" (EO) or "tblbahasa" (ID)
Utilo: ellegas elementon el kruda dudimensia tabelo, aux pli
precize el "tbllingvoj" (EO) aux "tblbahasa" (ID)
Manfaat: membaca elemen dari tabel berdimensi dua
Syfte: laeser ut ett element fraan en tvaadimensionell tabell
Used by templates / Uzata far sxablonoj /
Digunakan oleh templat / Anvaent av mallar:
- "Lingvo" "auxdo" "deveno3" ...
- "Modulo:mlawc" siavice uzata far sxablono "livs" (EO) /
"Modul:mlawc" digunakan oleh templat "bakk" (ID)
Required submodules / Bezonataj submoduloj / Submodul yang diperlukan:
- "mbllingvoj" in turn requiring template "tbllingvoj" (EO)
- "mtblbahasa" in turn requiring template "tblbahasa" (ID)
We do NOT need "mpiksubstrind" since we contain a copy of a part of its code.
Incoming: - 2 obligatory anonymous parameters
- requested y-index (access code of the
language, 2 or 3 lowercase chars) string indexing
- requested x-index (0...9) (soon 0...10) or special
value "+" or "-" numerical indexing
- 2 optional anonymous parameters (1 or 2 can be given,
but none can be skipped, specify default value if needed)
- "1" if removal of rl-lr-enclosement (for non-latin scripts) is
desired, or "0" to keep it (default is "1")
- alternative output string to replace "-" coming literally
from the source table (1...64 char:s, default is "-")
- 2 optional named parameters
- "err=" alternative output string to replace the "=" error
message (1...64 char:s, default is "=") (this works even
for errors coming from anonymous parameters)
- "detrc=" value "true" to create trace debug content
Returned: - one string
- for index number 0...9 (soon 0...10) the found element or "=" if
the element was not found (due to y or x) or an error occurred
- for special input value "+" the complete table line including
the y-index marker (but excessive whitespace reduced), or "="
if the y-index marker was not found or an error occurred
- for special input value "-" binary output either "1" if the
y-index marker was found (not checking the table line), or
"0" if the requested y-index was not found or an error occurred
This module is unbreakable (when called with correct module name
and function name). Every imaginable input will output either a useful
result or the string "=" (not found or error).
Cxi tiu modulo estas nerompebla (kiam vokita kun gxustaj nomo de modulo
kaj nomo de funkcio). Cxiu imagebla enigo eldonas aux utilan
rezulton aux signocxenon "=" (ne trovita aux eraro).
The function of this module is governed by
the "Specification of the 2-dimensional table picking system".
- y-index markers are obligatory and
lowercase (numbers and "-" not yet allowed) !!!FIXME!!!
- x-index markers are disallowed
Column numbering in the source table:
- numbering starts from ZERO
- "cy" does not count (it has theoretically index "-1")
- note that there is no comma between "cy" and "c0"
- "mpiktbllki" with special input value "+" returns the complete table line
including the y-index marker "cy", this means that unless the "cy" part is
trimmed off, index ZERO fed into "mpiksubstrind" will return both "cy"
and "c0", thus the indexes used by "mpiksubstrind" will NOT be OFF-by-ONE
y-index marker (row index marker) placed in the
table content area (here lowercase)
x-index marker (column index marker) placed in the
table content area (here prohibitied)
digit index marker (only digits) (here NOT supported)
lowercase index marker (lowercase letters and maybe a bit more)
incoming requested index (per spec may be evaluated to string indexing
or numerical indexing, but here hardcoded)
string indexing <--> lowercase index marker
numerical indexing <--> digit index marker or no index
marker and counting (here only counting)
General rules and specific limits (see spec):
- double square brackets "[[" and "]]" are reserved for y-index markers
and such may occur only at the beginning of line (here we assume this)
- usage of single square brackets "[" and "]" is not limited
- double round brackets "((" and "))" are reserved for x-index markers
(here we don't support x-index markers at all)
- usage of single round brackets "(" and ")" is not limited
- more than two subsequent brackets ie for
example "[[[" or ")))" are prohibited
- no comma "," following [[...]] and ((...)), inline whitespace
is recommended but not required
- index markers are optional, it's possible (and potentially useful) to mix
elements with index markers and elements without index markers, and it's
possible (but probaly less useful) to mix lines with index markers and
lines without index markers (here we require index markers for lines
and disallow them for elements)
- index markers must be 2 or 3 or 4 chars long and consist of either
only lowercase letters (lowercase index marker) or only digits
(digit index marker), it's possible (but maybe barely useful) to
mix the 2 types (here we don't support digit index markers at all,
and limit lowercase index markers to 2 or 3 chars)
- if digit index markers are used then they must match the index numbers for
both lines and columns, ie a digit index marker inside [[...]] and ((...))
is optional but cannot hold a value different from what it would be
anyway based on ZERO-based counting (here we don't support digit
index markers at all)
- if y-index markers are used then they must be sorted, with a privileged role
for 1 entry at the beginning and 1 entry at the end of the table that
are guaranteed to be found even if they are misplaced (here we
require y-index markers, sorting rule holds)
- redundant whitespace is not a problem as long as "maxwidth" is not exceeded
(this applies also to the beginning of the table) and no inline whitespace
(TAB or SPACE) follows EOL whitespace (ASCII 0...8 and 10...31),
this applies both to table lines and empty lines, ie an EOL
must be followed by either EOL or a table line (ie [[...]] or ((...))
or raw table element data)
- an empty table not containing any lines is valid as long as whitespace
rules are observed, this means EOL's are tolerable while inline whitespace
is not (here we require at least 1 line)
- a table line may not be empty, there must be at least 1 element
(note that allowing empty lines would cause inconsistencies between
lines with [[...]] and those without it)
- truncated table lines, ie lines shorter than other lines are tolerable, they
can end with element data or inline whitespace following element data, but
not with a comma ","
- a table element may not empty, dash "-" is the recommended filler for
dummy elements, or ((...)) can be used to "jump" over columns, even an
x-index marker ((...)) must be followed by at least one char of table
data (here we don't support x-index markers at all)
- a table element may not contain the string "=", if this string is found it
is translated to "-", the string "=" is reserved to indicate "not found or
error" (this rule holds even if alternative output string is requested)
Strategy:
- read out "minwidth" and "maxwidth" as suggested by
spec branch "y-index markers are obligatory" and check their validity
- size of the table block in octets must be 320 ... 1'000'000 (checked)
- size of the table content area must be >= (2 * "maxwidth") (checked)
- we support only lowercase index markers, not digit index markers,
the incoming requested y-index string must have 2 or 3 chars (checked)
- the incoming requested x-index number must be 0...9 (soon 0...10) (checked)
- we support only index marker for "y" and expect [[...]] in every line
- we support only counting for "x" and expect ((...)) not to occur
- we give a f**k in UTF8 and consider the table to be an array of octets
- for "y" indexing we apply a mixed strategy of linear forward and backward
search with step 2 and binary search
- for "y" indexing we begin with checking 0th entry, then last entry, then
continue with binary search, and switch back to linear search as soon as
the remaining size becomes dangerously low
- for "x" indexing we perform a linear forward search with step 1
- we give a f**k in closing "]]" and compare only opening "[["
and 2 or 3 chars
This is how "minwidth" and "maxwidth" constants work:
- they restrict the legth of a complete table line
including the obligatory EOL in octets
- "maxwidth" is the maximal distande between two line beginnings, and
includes possible trailing spaces and blank lines (no other
redundant whitespace is permitted)
- there is a special rule for the earliest line allowing up to "maxwidth"
extra area preceding the table if "[[" is used in all lines, otherwise
up to "maxwidth" of blank lines
- there is a special rule for the last line allowing up to "maxwidth"
of garbage following the table if "[[" is used in all lines, otherwise
up to "maxwidth" of blank lines
- the minimal teoretically possible "minwidth" value
per spec is 2 (one char + EOL)
- here the minimal sane "minwidth" value is
11 ("[[..]]" (6) + space + "Ido" (3) + EOL
Special rule about enclosing of elements written with
non-latin scripts (rl-lr-enclosement):
- non-ASCII, non-latin and even RTL (right-to-left) scripts are permitted
in the table
- a table element longer than 2 Octet:s may be enclosed in "rl " and " lr"
strings on both sides, this is useful since many editors would otherwise
break the element order if an RTL script is used
- by default the enclosing strings are not stripped off, but an extra
parameter "1" can enable this for ordinary x-index requests (0...9)
(soon 0...10), for special values "+" or "-" this extra parameter is ignored
Usage examples with results / Ekzemploj de uzo
kun rezultoj / Contoh penggunaan dengan hasil:
(assuming that the huge table seized via "mw.loadData" contains the silly
line "[[id]] indonezia , Q999 , rl bahasa Indonesia lr , 1 , id , i
nd , id , - , Indonezia lingvo , Kategori:Bahasa Esperanto , 100"
but no line with y-index marker "zzz", note that it is pointless to
rl-lr-enclose the string "bahasa Indonesia")
: ---------------------------------------
* #T00 {mpiktbllki|ek} (obligatory params missing, 0 given)
* expected result: "="
* actual result: "{{#invoke:mpiktbllki|ek}}"
:* #T01 {mpiktbllki|ek|eo} (obligatory params missing, only 1 given)
:* expected result: "="
:* actual result: "{{#invoke:mpiktbllki|ek|eo}}"
* #T02 {mpiktbllki|ek|err=fatal error} (obligatory params missing, 0 given, "err=" param used)
* expected result: "fatal error"
* actual result: "{{#invoke:mpiktbllki|ek|err=fatal error}}"
:* #T03 {mpiktbllki|ek|id|2} (strip garbage by default)
:* expected result: "bahasa Indonesia" (possibly useless in practise)
:* actual result: "{{#invoke:mpiktbllki|ek|id|2}}"
* #T04 {mpiktbllki|ek|ar|2} (strip garbage by default)
* expected result: ....... (maybe better attempt to test stripping)
* actual result: "{{#invoke:mpiktbllki|ek|ar|2}}"
:* #T05 {mpiktbllki|ek|id|2|0} ("c2", keep rl lr)
:* expected result: "rl bahasa Indonesia lr" (possibly failure in practise)
:* actual result: "{{#invoke:mpiktbllki|ek|id|2|0}}"
* #T06 {mpiktbllki|ek|ar|2|0} ("c2", keep rl lr)
* expected result: "rl "......." lr" (maybe better attempt to test "keep rl lr")
* actual result: "{{#invoke:mpiktbllki|ek|ar|2|0}}"
:* #T07 {mpiktbllki|ek|id|2|1} ("c2", explicit strip by "1")
:* expected result: "bahasa Indonesia" (possibly useless in practise)
:* actual result: "{{#invoke:mpiktbllki|ek|id|2|1}}"
* #T08 {mpiktbllki|ek|ar|2|1} ("c2", explicit strip by "1")
* expected result: ....... (maybe better attempt to test stripping)
* actual result: "{{#invoke:mpiktbllki|ek|ar|2|1}}"
: ---------------------------------------
* #T10 {mpiktbllki|ek|id|3} ("c3")
* expected result: "1"
* actual result: "{{#invoke:mpiktbllki|ek|id|3}}"
:* #T11 {mpiktbllki|ek|id|5} ("c5")
:* expected result: "ind"
:* actual result: "{{#invoke:mpiktbllki|ek|id|5}}"
* #T12 "{mpiktbllki|ek|id|7} ("c7", keep found "-")
* expected result: "-"
* actual result: "{{#invoke:mpiktbllki|ek|id|7}}"
* "{{#invoke:mpiktbllki|ek|id|7|1|N/A}}" (replace found "-")
* expected result: "N/A"
* "{{#invoke:mpiktbllki|ek|zzz|3}}" (unknown y-index)
* expected result: "="
* "{{#invoke:mpiktbllki|ek|zzz|3|err=bugger}}" (unknown y-index, "err=" param)
* expected result: "bugger"
: ---------------------------------------
* "{{#invoke:mpiktbllki|ek|id|11}}"
* expected result: "="
* "{{#invoke:mpiktbllki|ek|id|A}}" (invalid x-index)
* expected result: "="
* "{{#invoke:mpiktbllki|ek|id|A|1}}" (invalid x-index)
* expected result: "="
* "{{#invoke:mpiktbllki|ek|id|A|err=bugger}}" (invalid x-index, "err=" param)
* expected result: "bugger"
: ---------------------------------------
* #T30 {mpiktbllki|ek|grc|-} (binary request, assuming that "grc" exists)
* expected result: "1"
* actual result: "{{#invoke:mpiktbllki|ek|grc|-}}"
:* #T31 {mpiktbllki|ek|xxx|-} (binary request, assuming that "xxx" does not exist)
:* expected result: "0"
:* actual result: "{{#invoke:mpiktbllki|ek|xxx|-}}"
* #T32 {mpiktbllki|ek|id|+} (complete line, remove excessive whitespace)
* expected result: <nowiki> "[[id]] indonezia , Q999 , rl bahasa Indo
nesia lr , 1 , id , ind , id , - , Ind
onezia lingvo , Kategori:Bahasa Esperanto , 100" </nowiki> (possibly failure in practise)
* actual result via debu: {{debu|"{{#invoke:mpiktbllki|ek|id|+}}"|0020}}
:* #T33 {mpiktbllki|ek|xxx|+} (complete line, assuming that "xxx" does not exist)
:* expected result: "="
:* actual result: "{{#invoke:mpiktbllki|ek|xxx|+}}"
* #T34 {mpiktbllki|ek|xxx|+|detrc=true} (complete line, assuming that "xxx" does not exist, "detrc=true")
* expected result: long text followed by the short shameful verdict "="
* actual result: "{{#invoke:mpiktbllki|ek|xxx|+|detrc=true}}"
::* note that test #T32 depends on "debu"
::* note that test #T32 cannot be reasonably executed on the docs subpage without help of "pate" or "debu"
: ---------------------------------------
Note that output from this module when sent to screen directly as wikitext
will be subject to partial wiki parsing and full HTML parsing. This will
result in "[[id]" turned into a wikilink and in whitespace reduction. It
is not possible to call a module between "<pre>". In order to test this
module more thoroughly the output can be fed into another module ("debu"
or "pate") that analyzes the string and diplays ASCII codes or similar.
]===]
local piktbllki = {}
---- CONSTANTS ----
-- uncommentable EO vs ID constant strings (core site-related features)
local construsmo = "Modulo:mtbllingvoj" -- EO
-- local construsmo = "Modul:mtblbahasa" -- ID
-- bool "boo"
local conmiddig = false -- assign to "true" to allow middle digit "s7a"
-- integers "num"
local conmaxitemind = 9 -- 10 columns 0...9 (soon 11 columns 0...10)
---- SEIZE THE HUGE TABLE (OUTSIDE OF MAIN FUNCTION) ----
local tbllingvoj = mw.loadData(construsmo) -- can crash here
local constrtbl = "" -- huge table (320 ... 1'000'000 chars)
if (tbllingvoj~=nil) then -- seems to be always true
constrtbl = tbllingvoj [1] -- table -> string (with a small risk)
end--if
------------------------------------------------------------------------
---- ORDINARY LOCAL MATH FUNCTIONS ----
------------------------------------------------------------------------
local function mathmin (xmindd, xminee)
local resultmin = 0 -- min operator lacks in LUA :-(
resultmin = xmindd
if (resultmin>xminee) then
resultmin = xminee
end--if
return resultmin
end--function mathmin
local function mathdiv (xdividend, xdivisor)
local resultdiv = 0 -- DIV operator lacks in LUA :-(
resultdiv = math.floor (xdividend / xdivisor)
return resultdiv
end--function mathdiv
------------------------------------------------------------------------
---- ORDINARY LOCAL STRING FUNCTIONS ----
------------------------------------------------------------------------
-- test whether char is an ASCII lowercase letter, return bool
local function lftestlc (numcode)
local boolowerc = false
boolowerc = ((numcode>=97) and (numcode<=122))
return boolowerc
end--function lftestlc
------------------------------------------------------------------------
-- Local function LFCOUNTNDG
-- Count occurrences of non-digits (from a customizable set) in a string
-- Tolerable char:s that do not count as evil are:
-- * digits "0"..."9"
-- * maybe apo for (trictl=1) or (trictl=2)
-- * maybe space for (trictl=2)
local function lfcountndg (strzzz,trictl)
local numjrezalt = 0
local numcair = 0
local numjukuran = 0
local numjindxe = 0 -- ZERO-based
numjukuran = string.len(strzzz)
while (true) do
if (numjindxe==numjukuran) then
break
end--if
numcair = string.byte(strzzz,(numjindxe+1),(numjindxe+1))
if ((numcair==39) and (trictl~=0)) then
numcair=48 -- apo OK
end--if
if ((numcair==32) and (trictl==2)) then
numcair=48 -- space OK
end--if
if ((numcair<48) or (numcair>57)) then
numjrezalt = numjrezalt + 1
end--if
numjindxe = numjindxe + 1
end--while
return numjrezalt
end--function lfcountndg
------------------------------------------------------------------------
---- ORDINARY LOCAL LOW LEVEL FUNCTIONS ----
------------------------------------------------------------------------
-- Local function LFDEC1DIGIT
-- Convert 1 decimal digit to integer 0...9 (255 if invalid)
local function lfdec1digit (num1digit)
num1digit = num1digit - 48 -- may become invalid
if ((num1digit<0) or (num1digit>9)) then
num1digit = 255
end--if
return num1digit
end--function lfdec1digit
------------------------------------------------------------------------
-- Local function LFSTR12DIG2INT
-- Convert 1 or 2 decimal digits to integer 0...99 (255 if invalid)
local function lfstr12dig2int (strmasuk)
local numleen = 0
local numaa = 255 -- preassign to "error"
local numbb = 0
numleen = string.len (strmasuk)
if ((numleen==1) or (numleen==2)) then
numaa = string.byte (strmasuk,1,1)
numaa = lfdec1digit (numaa) -- 255 if invalid, ZERO would be valid
end--if
if ((numaa~=255) and (numleen==2)) then
numbb = string.byte (strmasuk,2,2)
numbb = lfdec1digit (numbb) -- 255 if invalid, ZERO would be valid
if (numbb==255) then
numaa = 255 -- 255 is invalid, note that ZERO would be valid
else
numaa = numaa * 10 + numbb -- valid integer number 0...99 now
end--if
end--if
return numaa
end--function lfstr12dig2int
------------------------------------------------------------------------
---- ORDINARY LOCAL HIGH LEVEL FUNCTIONS ----
------------------------------------------------------------------------
-- Local function LFTESTLNGKOD (see also LFCHKKODINV)
-- Test whether language code is valid depending on "boodigit".
-- Incoming empty string is safe but "nil" type is NOT
local function lftestlngkod (strlikodo,boodigit)
local boovalid = true
local numlencxcx = 0
local numchaa = 0
numlencxcx = string.len (strlikodo)
if ((numlencxcx<2) or (numlencxcx>3)) then
boovalid = false
else
numchaar = string.byte (strlikodo,1,1)
if (lftestlc(numchaar)==false) then
boovalid = false
end--if
numchaar = string.byte (strlikodo,2,2)
if (lftestlc(numchaar)==false) then
if ((numlencxcx==3) and boodigit) then
if (lfdec1digit(numchaar)>9) then
boovalid = false -- neither lowercase nor digit
end--if
else
boovalid = false -- digits NOT permitted in middle position
end--if
end--if
if (numlencxcx==3) then
numchaar = string.byte (strlikodo,3,3)
if (lftestlc(numchaar)==false) then
boovalid = false
end--if
end--if
end--if
return boovalid
end--function lftestlngkod
------------------------------------------------------------------------
-- Local function LFRLSTRIP
-- Strip "rl .. lr" if present and string length is at least 8 octet:s
local function lfrlstrip (strrlinut)
local numsoct = 0
local numsodt = 0
local numsoet = 0
local numsoft = 0
local numsogt = 0
local numsoht = 0
local numlaengd = 0
numlaengd = string.len(strrlinut)
if (numlaengd>=8) then -- at least 2 Octet:s length "rl .. lr" after strip
numsoct = string.byte(strrlinut,1,1)
numsodt = string.byte(strrlinut,2,2)
numsoet = string.byte(strrlinut,3,3)
numsoft = string.byte(strrlinut,(numlaengd-2),(numlaengd-2))
numsogt = string.byte(strrlinut,(numlaengd-1),(numlaengd-1))
numsoht = string.byte(strrlinut,(numlaengd ),(numlaengd ))
if ((numsoct==114) and (numsodt==108) and (numsoet==32) and (numsoft==32) and (numsogt==108) and (numsoht==114)) then
strrlinut = string.sub(strrlinut,4,(numlaengd-3)) -- stri off 3+3 char:s
end--if
end--if
return strrlinut
end--function lfrlstrip
------------------------------------------------------------------------
---- MAIN EXPORTED FUNCTION ----
------------------------------------------------------------------------
function piktbllki.ek (arxframent)
-- general unknown type
local vartmp = 0 -- variable without type
-- special type "args"
local arxourown = 0 -- metaized "args" from our own "frame" (NOT caller's)
-- general str
local strtmp = "" -- temp
local strtpm = "" -- temp
local stroutdsh = "-" -- alternative string to replace "-" literal fr table
local strerrequ = "=" -- default or alterna string to replace "=" on error
local strtrace = "" -- trace debug text
local strret = "" -- output string
-- general num
local numoct = 0 -- temp
local numlong = 0 -- temp for parameter evaluation, length of parameter
local numinxlen = 0 -- length of y-index word f arxframent.args[1] (2 or 3)
local numfoulen = 0 -- length of found y-index word (2 or 3)
local numiwo0 = 0 -- searched y-index word
local numiwo1 = 0 -- searched y-index word
local numiwo2 = 0 -- searched y-index word, ZERO if only 2 chars are used
local numxin = 255 -- x-inx f arxframent.args[2] (0...9, 0...10, 177, 199)
-- table positions "num"
local numtbllen = 0 -- length of the huge table seized via "mw.loadData"
local numposirr = 0
local numposiss = 0
local numminwidth = 0 -- safe values 8...1/2 * "maxwidth" def 11
local nummaxwidth = 0 -- safe values 40...40'000 and lower is bettr def 216
local numtblbeg = 0 -- size of extra area before the table, begin of table
local numipos = 0 -- octet position in "constrtbl", ZERO-based
local numfndpos = 0 -- position of found line with [[...]], ZERO-based
local numbinlow = 0 -- lower limit for binary search, ZERO-based positi
local numbinhaj = 0 -- higher limit for binary search, ZERO-based positi
-- general boo
local bootrace = false -- from "detrc=true"
local booerr = true -- overall error flag
local boostrip = true -- flag for stripping rl-lr-enclosement
local booyxfnd = false -- multipurpose found flag
local boospc = false -- flag for whitespace reduction feature
local boouch = false -- flag for found useful char when skipping element
-- only for built-in function "searchdblchr"
local isubnumlim = 0 -- octets to check (2 * "amount of iterations")
local isubnumchr = 0 -- char to search (91 for "[[" or 40 for "((")
local isubboodwn = false -- "true" for downward search
local osubboofnd = false -- "true" if the dblchar was found
-- only for built-in function "cmp2or3wordeq"
local osubbooequal = false -- "true" if found idx word equal to "numiwo"
-- only for built-in function "cmp2or3wordbi"
local osubboobiger = false -- "true" if found idx word bigger than "numiwo"
---- BUILT-IN GOSUB-STYLE FUNCTION "SEARCHDBLCHR" ----
-- PURPOSE: searches for a dblchar (91 for "[[" or 40 for "((")
-- upwards or downwards
-- IN : isubnumlim, isubnumchr, isubboodwn (unchanged)
-- OUT : osubboofnd (not in)
-- USE : constrtbl (acts as a constant in the module)
-- CHG : numipos (in and out)
-- NOTE: if "isubboodwn" is "false" then we run upwards and check the limit
-- upwards, thus with incoming position "numipos"=10 we start checking
-- at positions 11&(12,10), with incoming "isubnumlim"=10 we will no
-- longer check positions 23&(24,22) but will check 21&(22,20) ... we
-- need 3 chars margin at the top of range
-- NOTE: if "isubboodwn" is "true" then we run downwards but check the limit
-- by separately counting upwards, thus with incoming position
-- "numipos"=10 we start checking at
-- positions 11&(12,10), with incoming "isubnumlim"=10 we will no
-- longer check positions -01&(00,-02) but will check 01&(02,00) ... we
-- need 3 chars margin at the top of range but nothing at the bottom
-- NOTE: we are supposed to safely ignore single occurrences (ie continue
-- searching), as opposed to the fact that triple and longer
-- occurrences are prohibited
local searchdblchr = function ()
local usubnumsrch = 0 -- search position checker counting always up
local usubnumok = 0 -- single char (giving a f**k about UTF8)
local usubnumincr = 2 -- de facto constant "+2" or "-2"
osubboofnd = true -- pre-assume that we will find our dblchr
if (isubboodwn) then
usubnumincr = -2
end--if
while (true) do -- iterate through octets searching for dblchr (up or dwn)
if (usubnumsrch>isubnumlim) then
osubboofnd = false -- give up, table broken, "numipos" irrelevant now
break
end--if
usubnumok = string.byte (constrtbl,(numipos+2),(numipos+2)) -- "+1" actu
if (usubnumok==isubnumchr) then
usubnumok = string.byte (constrtbl,(numipos+3),(numipos+3)) -- "+2" ab
if (usubnumok==isubnumchr) then
numipos = numipos + 1
break -- found and "numipos" valid ... otherwise try to look below
end--if
usubnumok = string.byte (constrtbl,(numipos+1),(numipos+1)) -- "+0" bl
if (usubnumok==isubnumchr) then
break -- found and "numipos" valid ... otherwise continue search
end--if
end--if
usubnumsrch = usubnumsrch + 2 -- always upwards
numipos = numipos + usubnumincr -- "+2" or "-2"
end--while
end--function searchdblchr
---- BUILT-IN GOSUB-STYLE FUNCTION "CHK2OR3LIM" ----
-- PURPOSE: performs a wild guess whether the found y-index marker
-- has 2 letters or 3 letters, lacks thorough checks,
-- result will be ZERO if we would hit the limit
-- IN : numipos, numtbllen
-- OUT : numfoulen
-- USE : constrtbl (acts as a constant in the module)
-- CHG : N/A
local chk2or3lim = function ()
local usubnum1ch = 0 -- single char
if ((numipos+6)>=numtbllen) then
numfoulen = 0 -- peek +4 only but need 6 for [[aa]] or 7 for [[aaa]]
else
usubnum1ch = string.byte (constrtbl,(numipos+5),(numipos+5)) -- "+4" act
if (lftestlc(usubnum1ch)==true) then
numfoulen = 3
else
numfoulen = 2
end--if
end--if
end--function chk2or3lim
---- BUILT-IN GOSUB-STYLE FUNCTION "CMP2OR3WORDEQ" ----
-- PURPOSE: performs a comparison of 2 or 3 char:s testing for equality only
-- IN : numipos, numinxlen, numfoulen
-- OUT : osubbooequal ("true" if equal)
-- USE : constrtbl, 3 numiwo (act as constants in the module)
-- CHG : N/A
-- NOTE: it is the caller's responsibility to ensure
-- that "numinxlen" and "numfoulen" are 2 or 3 !!!
-- NOTE: it is the caller's responsibility to ensure
-- that we don't hit the limit here in
local cmp2or3wordeq = function ()
osubbooequal = true -- pre-assume found, likely abort after 1 or 2 compa
if (numinxlen~=numfoulen) then
osubbooequal = false -- NOT found
else
if ((string.byte (constrtbl,numipos+3,numipos+3)) ~= numiwo0) then
osubbooequal = false ; -- NOT found
else
if ((string.byte (constrtbl,numipos+4,numipos+4)) ~= numiwo1) then
osubbooequal = false ; -- NOT found
else
if (numinxlen==3) then
if ((string.byte (constrtbl,numipos+5,numipos+5)) ~= numiwo2) then
osubbooequal = false ; -- NOT found
end--if
end--if
end--if
end--if
end--if
end--function cmp2or3wordeq
---- BUILT-IN GOSUB-STYLE FUNCTION "CMP2OR3WORDBI" ----
-- PURPOSE: performs a comparison of 2 or 3 char:s testing for "bigger"
-- IN : numipos, numinxlen, numfoulen, numiwo
-- OUT : osubboobiger ("true" if found index word is bigger than "numiwo")
-- USE : constrtbl (acts as a constant in the module)
-- CHG : N/A
-- NOTE: it is the caller's responsibility to ensure
-- that "numinxlen" and "numfoulen" are 2 or 3 !!!
-- NOTE: it is the caller's responsibility to ensure
-- that we don't hit the limit here in
-- NOTE: the 2 strings are expected not to be equal on entry here,
-- but single letters may be, thus ("grc" and "grc") is impossible,
-- but ("grc" and "gro") or ("grc" and "gr") can occur, actually,
-- the code here itself tests for "bigger" vs "smaller or equal"
local cmp2or3wordbi = function ()
local usubnum1char = 0 ; -- single char
osubboobiger = false ; -- pre-assume smaller or equal, likely abort soon
usubnum1char = (string.byte (constrtbl,numipos+3,numipos+3)) ;
if (usubnum1char>numiwo0) then
osubboobiger = true ; -- bigger
else
if (usubnum1char==numiwo0) then
usubnum1char = (string.byte (constrtbl,numipos+4,numipos+4)) ;
if (usubnum1char>numiwo1) then
osubboobiger = true ; -- bigger
else
if ((usubnum1char==numiwo1) and ((numinxlen+numfoulen)>4)) then
if (numfoulen>numinxlen) then
osubboobiger = true -- (3:2 - found:previous) and bigger
else
if (numfoulen==3) then
usubnum1char = (string.byte (constrtbl,numipos+5,numipos+5)) ;
else
usubnum1char = 0
end--if
if (usubnum1char > numiwo2) then
osubboobiger = true -- bigger
end--if
end--if
end--if
end--if (usubnum1char>numiwo1) else
end--if
end--if
end--function cmp2or3wordbi
---- CHECK THE HUGE TABLE ----
-- we do NOT have "nummaxwidth" yet
-- spec allows 32 ... 8'000'000 but here we restrict to 320...1'000'000
booerr = true
if (type(constrtbl)=="string") then -- important check
numtbllen = string.len (constrtbl)
if ((numtbllen>=320) and (numtbllen<=1000000)) then
strtmp = "passed 320...1'000'000 check: " .. tostring (numtbllen)
booerr = false -- was preassigned to "true"
else
strtmp = "failed 320...1'000'000 check"
end--if
strtrace = strtrace .. "<br>" .. strtmp
end--if
---- SEIZE 2 OBLIGATORY ARGUMENTS FROM THE CALLER (2 MORE ARE OPTIONAL) ----
-- as output for the index string from arxourown[1] we use 3 separate
-- var:s (numiwo0, numiwo1, numiwo2) and "numinxlen" equal 2 or 3
-- from arxourown[2] var "numxin" (0...9, soon 0...10,
-- special 177, special 199, invalid 255
arxourown = arxframent.args -- "args" from our own "frame"
if ((arxourown[1]==nil) or (arxourown[2]==nil)) then
strtrace = strtrace .. "<br>lack 2 obligatory anonymous parameters"
booerr = true
end--if
if (booerr==false) then
strtpm = arxourown[1] -- requested y-index string (2 or 3 lowercase chars)
numinxlen = string.len (strtpm)
if (lftestlngkod(strtpm,conmiddig)==false) then
strtrace = strtrace .. "<br>y-index code invalid"
booerr = true -- not valid language code
else
numiwo0 = string.byte (strtpm,1,1)
numiwo1 = string.byte (strtpm,2,2)
if (numinxlen==3) then
numiwo2 = string.byte (strtpm,3,3) -- otherwise ZERO
end--if
end--if
end--if
if (booerr==false) then
strtmp = arxourown[2] -- x-index (1 or 2 digit, 0...9, 0...10, ZERO-based)
numlong = string.len (strtmp) -- temp for decimal conversion
if ((numlong==1) or (numlong==2)) then
numxin = string.byte (strtmp,1,1)
if (numxin==43) then
numxin = 177 -- special "+" (complete) special value 177
else
if (numxin==45) then
numxin = 199 -- special "-" (binary) special value 199
else
numxin = lfstr12dig2int (strtmp) -- 255 if invalid
if (numxin>conmaxitemind) then
numxin = 255 -- damn: no valid x-index
end--if
end--if
end--if (numxin==43) else
end--if
if (numxin==255) then
strtrace = strtrace .. "<br>x-index invalid"
booerr = true -- damn: no valid x-index number
end--if
end--if
if (booerr==false) then
if (type(arxourown[3])=="string") then
strtmp = arxourown[3] -- optional "0" or "1" (default) strip flag
numlong = string.len (strtmp) -- temp
if (numlong==1) then
numoct = string.byte (strtmp,1,1)
if (numoct==48) then
boostrip = false -- was preassigned to true
end--if
if ((numoct~=48) and (numoct~=49)) then
strtrace = strtrace .. "<br>strip flag invalid not 0 or 1"
booerr = true -- damn
end--if
else
strtrace = strtrace .. "<br>strip flag invalid length"
booerr = true -- damn
end--if
end--if (type(arxourown[3])=="string") then
if (type(arxourown[4])=="string") then
strtmp = arxourown[4] -- 1...64 char:s alterna string to replace "-"
numlong = string.len (strtmp) -- temp
if ((numlong<1) or (numlong>64)) then
strtrace = strtrace .. "<br>anon dash alterna string invalid"
booerr = true -- damn
else
stroutdsh = strtmp -- was preassigned to "-"
end--if
end--if (type(arxourown[4])=="string") then
end--if
---- SEIZE NAMED PARAMETER "ERR" EVEN IF WE ALREADY SUCK ----
-- try to pick named param "err=" even if we already have "booerr==true"
-- 1...64 char:s alternative string to replace "="
vartmp = arxourown["err"] -- can be type "nil"
if (type(vartmp)=="string") then
numlong = string.len (vartmp)
if ((numlong<1) or (numlong>64)) then
strtmp = "err equ alterna string invalid"
booerr = true -- damn -- maybe redundant -- keep "strerrequ" == "="
else
strtmp = "err equ alterna string seized"
strerrequ = vartmp -- was preassigned to "="
end--if
strtrace = strtrace .. "<br>" .. strtmp
end--if
---- SEIZE NAMED PARAMETER "DETRC" EVEN IF WE ALREADY SUCK ----
-- try to pick named param "detrc=" even if we already have "booerr==true"
-- so far we collected to "strtrace" unconditionally
if (arxourown["detrc"]=="true") then
bootrace = true -- was preassigned to "false"
end--if
---- PREASSIGN ----
booyxfnd = false -- set to "true" as soon as specified y-index word found
---- SEARCH FOR TABLE BEGIN AKA THE 0TH Y-INDEX MARKER AND MINW MAXW ----
-- * start at position ZERO
-- * check char after char
-- * if end of table block or 80'000 octet:s reached then
-- abort search (S-position is still "invalid", bad)
-- * if string "[[" found then assign S-position to index and abort
-- search (good so far)
-- * if S-position is "valid" then
-- * restart at position ZERO
-- * check char after char
-- * if (S-position - 21) reached then abort (good so far)
-- * if string "minw=" found at earliest hit assign R-position to
-- index, at further hit assign R-position to "invalid"
-- and abort (bad)
-- * if we do not have both R-position and S-position then give up
-- * if ( ("R-position") + 22 > "S-position") then give up
-- * check and evaluate the line found at R-position, if good then assign
-- "minwidth" and "maxwidth", otherwise give up
-- * if ("S-position" > "maxwidth") then give up
-- * done: table content area begins at "S-position", "minwidth" and
-- "maxwidth" are assigned (garbage area following the last table
-- line must be evaluated separately)
-- "minw=00010 maxw=00200" the length is 21 char:s plus EOL
-- note that table size "numtbllen" guaranteed from above is at least
-- 320 (44 by spec) but the table may contain an extra area and a garbage
-- area and shrink considerably after those are trimmed off or disregarded
-- search limit will be min(80000,("numtbllen"-3)), 80K is per spec, we need
-- a safety margin of 3 char:s, and the subtraction cannot underflow
if (booerr==false) then
numposirr = -1
numposiss = -1
numipos = 0 -- ZERO-based position in "constrtbl"
isubnumlim = mathmin(80000,(numtbllen-3))
isubnumchr = 91 -- look for "[["
isubboodwn = false -- upwards
searchdblchr () -- OUT: osubboofnd | USE: constrtbl | CHG: numipos
if (osubboofnd) then
numtblbeg = numipos -- else ZERO
numposiss = numipos -- else "-1" invalid
end--if
end--if
if ((booerr==false) and (numposiss~=-1)) then
numipos = 0 -- ZERO-based position in "constrtbl"
while (true) do
if ((numipos+21)>=numposiss) then
break
end--if
numoct = string.byte (constrtbl,(numipos+1),(numipos+1))
if (numoct==109) then -- ASCII lowercase "m"
strtpm = string.sub (constrtbl,(numipos+2),(numipos+5))
if (strtpm=="inw=") then
if (numposirr==-1) then
numposirr = numipos -- good hit
else
numposirr = -1 -- more hits prohibited per spec
break
end--if
end--if (strtpm=="inw=") then
end--if
numipos = numipos + 1
end--while
end--if
if (booerr==false) then
while (true) do -- fake loop
if ((numposirr==-1) or (numposiss==-1)) then
booerr = true -- give up, line is not found
break -- to join mark
end--if
if ((numposirr+22) > numposiss) then
booerr = true -- give up, line is not valid
break -- to join mark
end--if
strtpm = string.sub (constrtbl,(numposirr+1),(numposirr+22)) -- 22 cha
numoct = string.byte (strtpm,22,22) -- need EOL
if (numoct~=10) then
booerr = true -- give up, line is not valid
break -- to join mark
end--if
strtmp = string.sub (strtpm,11,16)
if (strtmp~=" maxw=") then
booerr = true -- give up, line is not valid
break -- to join mark
end--if
strtmp = string.sub (strtpm,6,10)
if (lfcountndg(strtmp,0)~=0) then -- valid number ?
booerr = true -- give up, number is not valid
break -- to join mark
end--if
numminwidth = tonumber(strtmp)
strtmp = string.sub (strtpm,17,21)
if (lfcountndg(strtmp,0)~=0) then -- valid number ?
booerr = true -- give up, number is not valid
break -- to join mark
end--if
nummaxwidth = tonumber(strtmp)
if ((numposiss>nummaxwidth) or (numminwidth<8) or ((numminwidth*2)>nummaxwidth) or (nummaxwidth<40) or (nummaxwidth>40000) or ((nummaxwidth*2)>numtbllen)) then
booerr = true -- give up, number is not valid
break -- to join mark
end--if
break -- finally to join mark
end--while -- fake loop -- join mark
if (bootrace) then
if (booerr) then
strtmp = "failure to seize min&max"
else
strtmp = "min&max seized: " .. tostring(numminwidth) .. "," .. tostring(nummaxwidth)
end--if
strtrace = strtrace .. "<br>" .. strtmp
end--if
end--if
-- now ZERO-based "numtblbeg" maybe points to the found "[["
-- we will not touch "numtblbeg" since here but will update "numipos"
---- COMPARE THE 0TH Y-INDEX WORD ----
if (booerr==false) then
numipos = numtblbeg
chk2or3lim () -- IN: numipos, numtbllen | USE: constrtbl | CHG: numfoulen
if (numfoulen==0) then
booerr = true -- barely can occur
else
cmp2or3wordeq () -- OUT: osubbooequal | USE: constrtbl, numiwo
if (osubbooequal==true) then
numfndpos = numipos
booyxfnd = true -- found the y-index word !!!
else
numbinlow = numipos -- points to found "[[", will need this later
end--if
end--if
end--if
-- now ZERO-based "numfndpos" maybe points to the found "[[...]]"
-- now "numipos" is irrelevant
---- SEARCH FOR THE LAST Y-INDEX WORD ----
-- will succeed if we find "[[" within "maxwidth"
-- if we have only one line then found last index word will
-- be the same as the found 0th index word
if ((booerr==false) and (booyxfnd==false)) then
numipos = numtbllen - numminwidth -- ZERO-based positi in "constrtbl"
isubnumlim = 2 * nummaxwidth - numminwidth -- allow full "maxwidth" of garb
isubnumchr = 91 -- look for "[["
isubboodwn = true -- downwards
searchdblchr () -- OUT : osubboofnd | USE : constrtbl | CHG : numipos
if (osubboofnd==false) then
booerr = true -- give up, table is broken, "numipos" irrelevant now
end--if
end--if
-- now ZERO-based "numipos" maybe points to the found "[["
---- COMPARE THE LAST Y-INDEX WORD ----
if ((booerr==false) and (booyxfnd==false)) then
chk2or3lim () -- IN: numipos, numtbllen | USE: constrtbl | CHG: numfoulen
if (numfoulen==0) then
booerr = true -- barely can occur
else
cmp2or3wordeq () ; -- OUT: osubbooequal | USE: constrtbl, numiwo
if (osubbooequal==true) then
numfndpos = numipos
booyxfnd = true ; -- found the y-index word !!!
else
numbinhaj = numipos ; -- points to found "[[", will need this later
end--if
end--if
end--if
-- now ZERO-based "numfndpos" maybe points to the found "[[...]]"
-- now "numipos" is irrelevant
---- PERFORM THE BINARY SEARCH ----
-- ZERO-based "numbinlow" and "numbinhaj" always point to begi of "[[...]]"
-- note that here SUB "searchdblchr" can fail with "osubboofnd==false"
-- if the table exceeds "maxwidth", this is an error
-- the other risk with SUB "searchdblchr" is that could hit "numbinhaj"
-- and find the "[[" there, this is highly undesirable as this would
-- cause a subsequent invalid comparison with random result, we prevent
-- this by aborting the binary search at this point
if ((booerr==false) and (booyxfnd==false)) then
while (true) do -- reduce size by halving until it becomes too small
numipos = mathdiv((numbinlow + numbinhaj),2) -- ZERO-based positi
if ((numipos+nummaxwidth+numminwidth)>numbinhaj) then
break -- NOT found, continue with desperate last step linear search
end--if
isubnumlim = nummaxwidth -- do NOT subtract here
isubnumchr = 91 -- search for "[["
isubboodwn = false -- upwards
searchdblchr () -- OUT : osubboofnd | USE : constrtbl | CHG : numipos
if (osubboofnd==false) then
booerr = true
break -- give up, not found or table brokn, "numipos" irrelevant now
end--if
chk2or3lim () -- IN: numipos, numtbllen | USE: constrtbl | CHG: numfoulen
cmp2or3wordeq () -- OUT: osubbooequal | USE: constrtbl, numiwo
if (osubbooequal==true) then
numfndpos = numipos
booyxfnd = true ;
break ; -- found the y-index word !!!
end--if
cmp2or3wordbi () -- OUT: osubboobiger | USE: constrtbl, numiwo
if (osubboobiger==true) then -- "true" if found y-index word > "numiwo"
numbinhaj = numipos -- was too high, check below, reduce "numbinhaj"
else
numbinlow = numipos -- was too low, check above, increas "numbinlow"
end--if
end--while
end--if
-- below look at "booerr", then at "booyxfnd",
-- then at "numfndpos" or ("binlow" and "binhaj")
---- PERFORM THE DESPERATE LAST STEP LINEAR SEARCH ----
-- search through range "binlow" to "binhaj", this can be more than
-- "maxwidth" (almost double size in worst case)
-- there definitely is "[[" at both "binlow" and "binhaj" and there can
-- be ZERO, ONE or several further "[[" in the range
-- so we indeed subtract "minwidth" from the range size two times
if ((booerr==false) and (booyxfnd==false)) then
numipos = numbinlow ;
while (true) do -- there can be several lines left
numipos = numipos + numminwidth ;
isubnumlim = numbinhaj - numipos - numminwidth ; -- is "[[" at "binhaj"
if (isubnumlim<numminwidth) then
booerr = true
break ; -- give up, not found or table brokn, "numipos" irrelevant now
end--if
isubnumchr = 91 -- search for "[["
isubboodwn = false -- upwards
searchdblchr () -- OUT : osubboofnd | USE : constrtbl | CHG : numipos
if (osubboofnd==false) then
booerr = true
break ; -- give up, not found or table brokn, "numipos" irrelevant now
end--if
chk2or3lim () ; -- IN: numipos, numtbllen | USE: constrtbl | CHG: numfoulen
cmp2or3wordeq () ; -- OUT: osubbooequal | USE: constrtbl, numiwo
if (osubbooequal==true) then
numfndpos = numipos
break -- found the y-index word but "booyxfnd" not needed anymore !!
end--if
end--while
end--if
-- below not look at "booyxfnd", look at "booerr" only and maybe "numfndpos"
---- RETURN ONE ELEMENT PICKED ACCORDING TO X-INDEX NUMBER IF 0...9x10 ----
-- This is done in 3 + 1 steps:
-- * skip possible unsuitable elements
-- * skip possible whitespace preceding the searched element
-- * copy the searched element (takes a char from previous step)
-- * strip off rl-lr-enclosement if requested (boostrip=true) and it is present
-- this is a copy of module "mpiksubstrind" with minimal modifications
-- "numxin" can be 0...9 (soon 0...10) and values > 100 are reserved
if ((booerr==false) and (numxin<100)) then
booxyfnd = false
numipos = numfndpos + 4 + numinxlen -- ZERO-based index in "constrtbl"
numite = numxin -- count down
while (true) do -- iterate through elements in order to skip them
if (numite==0) then -- nothing to skip anymore
booxyfnd = true ;
break ; -- exit the outer loop, nothing to skip anymore
end--if
numite = numite - 1
booxyfnd = false
boouch = false
while (true) do -- iterate through whspc & chars mix looking for comma
if (numipos>=numtbllen) then
break ; -- exit the inner loop, NOT found, give up
end--if
numipos = numipos + 1 ;
numoct = string.byte (constrtbl,numipos,numipos) ;
if ((numoct<32) and (numoct~=9)) then
break -- EOL: exit the inner loop, NOT found, give up
end--if
if ((numoct>32) and (numoct~=44)) then
boouch = true ; -- found a valid char (empty field is an error)
end--if
if (numoct==44) then
if (boouch==true) then
booxyfnd = true ; -- field was not empty
end--if
break ; -- exit the inner loop, found a comma, this is good or bad
end--if
end--while
if (booxyfnd==false) then
break -- exit the outer loop, NOT found or empty field, give up
end--if
end--while
if (booxyfnd==true) then
booxyfnd = false ;
while (true) do -- iterate through chars skipping whitespace
if (numipos>=numtbllen) then
break ; -- exit the loop, NOT found, give up
end--if
numipos = numipos + 1 ;
numoct = string.byte (constrtbl,numipos,numipos)
if ((numoct<32) and (numoct~=9)) then
break -- EOL: exit the loop, NOT found, give up
end--if
if (numoct>32) then
if (numoct==44) then
break ; -- exit loop, found comma, give up according to rules
end--if
booxyfnd = true ;
break ; -- exit the loop, found valid char, start copying now
end--if
end--while
end--if
if (booxyfnd==true) then
while (true) do -- iterate through chars copying the found element
if ((numoct==32) or (numoct==9)) then
boospc=true
else
if (boospc==true) then
strret = strret .. " " -- was preassigned to empty
boospc = false
end--if
strret = strret .. string.char (numoct)
end--if
if (numipos>=numtbllen) then
break ; -- exit the loop, done
end--if
numipos = numipos + 1 ;
numoct = string.byte (constrtbl,numipos,numipos)
if ((numoct<32) and (numoct~=9)) then
break -- EOL: exit the loop, done
end--if
if (numoct==44) then
break -- comma: exit the loop, done
end--if
end--while
end--if
if (booxyfnd==false) then
booerr = true -- damn: failed in the x-search
end--if
end--if
-- strip off rl-lr-enclosement if requested (boostrip=true) and it is present
if ((booerr==false) and (numxin<100) and (boostrip==true)) then
strret = lfrlstrip (strret)
end--if
---- RETURN COMPLETE LINE IF SPECIAL "+" AKA 177 ----
-- we do reduce excessive whitespace
if ((booerr==false) and (numxin==177)) then
boospc = false
numipos = 0 -- limit width again
while (true) do -- iterate through char:s copying the found line
if (numipos>=nummaxwidth) then
booerr = true
break -- damn: violated "maxwidth"
end--if
numoct = string.byte (constrtbl,(numfndpos+1),(numfndpos+1)) ;
if ((numoct<32) and (numoct~=9)) then
break -- done (anything < 32 other than TAB counts as EOL)
end--if
if ((numoct==32) or (numoct==9)) then
boospc=true
else
if (boospc==true) then
strret = strret .. " " -- was preassigned to empty
boospc = false
end--if
strret = strret .. string.char (numoct) -- was preassigned to empty
end--if
numipos = numipos + 1
numfndpos = numfndpos + 1
end--while
end--if
---- CARE ABOUT PROHIBITED EQUAL SIGN ----
if (strret=='=') then
strret = '-' -- string "=" is prohibited, punishment is conversion to "-"
end--if
---- CARE ABOUT ERRORS ----
-- this is NOT final or valid for input x-index number "-" AKA 199
if (booerr==true) then
strret = strerrequ -- string "strret" was preassigned to empty
end--if
---- CARE ABOUT DASH TRANSLATION ----
if (strret=='-') then
strret = stroutdsh
end--if
---- RETURN BINARY DIGIT IF SPECIAL X-INDEX NUMBER "-" AKA 199 ----
if (numxin==199) then
if (booerr==true) then
strret = "0" -- y-index word NOT found or error
else
strret = "1" -- y-index word found
end--if
end--if
---- RETURN THE JUNK STRING ----
if (bootrace) then
strret = "<br>" .. strtrace .. "<br><br>" .. strret
end--if
return strret
end--function
---- RETURN THE JUNK LUA TABLE ----
return piktbllki