Modulo:Listtable
Aspekto
[antaŭrigardi] [redakti] [historio] [renovigi]
Utilo
Sencimiga modulo kiu montras enhavon de LUA tabelo, eĉ nestigita kaj eĉ "metaigita". Vokebla aŭ el vikiteksto aŭ el alia modulo. Aŭ importas datuman modulon aŭ transprenas tabelon rekte.
Uzo
Voko el vikiteksto (nur importo de tabelo):
{{#invoke:listtable|ek|Modulo:Lingvonomo/listo/flagoj}}
Voko el modulo (importo de tabelo):
local qlisttable = require ('Modulo:listtable')
local strimport = 'Modulo:Lingvonomo/listo/flagoj'
local strmyreport = qlisttable.ek { strimport }
local qlisttable = require ('Modulo:listtable')
local strimport = 'Modulo:Lingvonomo/listo/flagoj'
local strmyreport = qlisttable.ek { strimport , 'UTF8' }
Voko el modulo (rekta transdono de tabelo):
local qlisttable = require ('Modulo:listtable')
local tabdubious = {[false]='FALSE',[0]=0,[7654]={'a','b','c'}}
local strmyreport = qlisttable.ek { tabdubious }
local qlisttable = require ('Modulo:listtable')
local strmyreport = qlisttable.ek { {3,2} } -- note the double curly brackets
local qlisttable = require ('Modulo:listtable')
local strmyreport = qlisttable.ek { {65,string.char(0xC5,0x9C),66} , 'UTF8'
Menciita Modulo:Lingvonomo/listo/flagoj estas nur ekzemplo.
| Se vi havas demandon pri ĉi tiu Lua-modulo, tiam vi povas demandi en la diskutejo pri Lua-moduloj. La Intervikiaj ligiloj estu metataj al Vikidatumoj. (Vidu Helpopaĝon pri tio.) |
|
--[===[
MODULE "LISTTABLE"
"eo.wikipedia.org/wiki/Modulo:Listtable" <!--2025-Sep-04-->
"eo.wiktionary.org/wiki/Modulo:listtable"
"id.wikipedia.org/wiki/Modul:Listtable"
"id.wiktionary.org/wiki/Modul:listtable"
"sv.wiktionary.org/wiki/Modul:listtable"
Purpose: show all content of a LUA table, even a metaized one,
even recursively up to 7 levels
Required submodules / Bezonataj submoduloj /
Submodul yang diperlukan / Behoevda submoduler: none
Incoming: * ONE to 3 anonymous parameters
* obligatory target
* when called from a template or from a
wiki page (directly or via template):
* name of data module to be imported via "loadData",
with namespace prefix
* when called from a module:
* either table to get analyzed (data type "table"), or name
of data module (data type "string") to be imported via
"loadData", with namespace prefix
* optional modifiers (order does NOT matter)
* "UTF8" to keep UTF8 char:s
* "SRC" to regenerate LUA source code !!!FIXME!!! does NOT work yet
One CANNOT submit name of function nor parameters for the imported module,
thus the direct import works only for data modules. For other modules one
has to create a 3:rd-party module importing both this module and the target
module via "require", and then feeding the table from the target module
into this module "listtable".
Examples of calling from wiki page:
{{#invoke:listtable|ek|Module:loaddata-tblfilumoj}}
{{#invoke:listtable|ek|Module:loaddata-tblfilumoj|SRC}}
Examples of calling from module (import):
local qlisttable = require ('Module:listtable')
local strimport = 'Module:tagg/data'
local strmyreport = qlisttable.ek { strimport }
local qlisttable = require ('Module:listtable')
local strimport = 'Module:tagg/data'
local strmyreport = qlisttable.ek { strimport , 'UTF8' }
Examples of calling from module (direct):
local qlisttable = require ('Module:listtable')
local tabdubious = {[false]='FALSE',[0]=0,[7654]={'a','b','c'}}
local strmyreport = qlisttable.ek { tabdubious }
local qlisttable = require ('Module:listtable')
local strmyreport = qlisttable.ek { {3,2} } -- note the double curly brackets
local qlisttable = require ('Module:listtable')
local strmyreport = qlisttable.ek { {65,string.char(0xC5,0x9C),66} , 'UTF8' }
local qlisttable = require ('Module:listtable')
local strmyreport = qlisttable.ek { {0,string.char(0xC5,0x9C),127} , 'UTF8' , 'SRC' }
]===]
local exporttable = {}
require('strict')
-- ******************************************
-- * HIGH LEVEL STRING PROCEDURES [I] * --------------------------
-- ******************************************
local function prifontsizetit (strtexto, numlevel)
-- called from "prhtablistlevel" (indent level 0...13) and
-- from "prhtablist" (special indent level -1)
local strsize = '200' -- preASSume -- for special level -1
if (numlevel==0) then
strsize = '150'
end--if
if (numlevel==1) then
strsize = '130'
end--if
if (numlevel==2) then
strsize = '110'
end--if
if (numlevel>2) then
strsize = '90'
end--if
strtexto = '<b><span style="font-size:' .. strsize .. '%;">' .. strtexto .. '</span></b>'
return strtexto
end--function prifontsizetit
------------------------------------------------------------------------
local function lfifont90nbsize (strtexxto)
strtexxto = '<span style="font-size:90%;">' .. strtexxto .. '</span>'
return strtexxto
end--function lfifont90nbsize
------------------------------------------------------------------------
local function lfileftlevel (numleewel)
local strlfandstars = string.char(10)
while true do
strlfandstars = strlfandstars .. '*' -- ONE star at level ZERO needed too
if (numleewel==0) then
break
end--if
numleewel = numleewel - 1
end--while
return strlfandstars
end--function lfileftlevel
------------------------------------------------------------------------
local function primini3ksani (strdangstring, booutf8keepit)
-- Remedy dangerous char:s in a string for the purpose of showing text,
-- including size truncation in worst case.
-- no values $C0, $C1, $F5...$FF in a UTF8 stream
local strnowsafe = ''
local num39len = 0
local num39index = 1 -- ONE-based
local numsigno = 0
local numprevious = 0
local boohtmlenc = false
local boovisienc = false
local bookeepuni = false
if (type(strdangstring)~='string') then
strdangstring = '??'
end--if
booutf8keepit = (booutf8keepit==true)
num39len = string.len (strdangstring)
while true do
if (num39index>num39len) then -- ONE-based
break
end--if
numsigno = string.byte (strdangstring,num39index,num39index)
boohtmlenc = false -- reset on
boovisienc = false -- every iteration
bookeepuni = (booutf8keepit and (numsigno>=128) and (numsigno<=245) and (numsigno~=192) and (numsigno~=193))
if (not bookeepuni) then
boohtmlenc = ((numsigno<=42) or (numsigno==58) or (numsigno==60) or (numsigno==62) or (numsigno==91) or (numsigno==93) or (numsigno>=123))
boovisienc = ((numsigno<=31) or (numsigno>=127)) -- overrides "boohtmlenc"
end--if
if ((numsigno==32) and ((numprevious==32) or (num39index==1) or (num39index==num39len))) then
boovisienc = true -- overrides "boohtmlenc"
end--if
if (boovisienc) then
strnowsafe = strnowsafe .. '{' .. tostring (numsigno) .. '}'
else
if (boohtmlenc) then
strnowsafe = strnowsafe .. '&#' .. tostring (numsigno) .. ';'
else
strnowsafe = strnowsafe .. string.char (numsigno)
end--if
end--if
if ((num39len>3000) and (num39index==1000)) then
num39index = num39len - 1000
strnowsafe = strnowsafe .. '" ... "'
else
num39index = num39index + 1 -- ONE-based
end--if
numprevious = numsigno
end--while
return strnowsafe
end--function primini3ksani
-- ***********************************
-- * HIGH LEVEL PROCEDURES [H] * ---------------------------------
-- ***********************************
local function prhreportkey (varauxnum2auxstr, booutf8ke2ep, boorebrew2lua)
-- Input : * booutf8ke2ep -- true to keep UTF8 intact, else dec-encoded
-- * boorebrew2lua -- true to rebrew LUA source, else human-readable
-- Called from PRHREPORTPAIR, in turn from 3 places in PRHTABLISTLEVEL.
local strkey2out = ''
if (type(varauxnum2auxstr)=='number') then
strkey2out = tostring(varauxnum2auxstr) -- do NOT quote number
else
strkey2out = '"' .. primini3ksani(varauxnum2auxstr,booutf8ke2ep) .. '"' -- do quote string
end--if
return strkey2out
end--function prhreportkey
------------------------------------------------------------------------
local function prhreportvalue (varany3type, booutf8ke3ep, boorebrew3lua)
-- Input : * booutf8ke3ep -- true to keep UTF8 intact, else dec-encoded
-- * boorebrew3lua -- true to rebrew LUA source, else human-readable
-- Called from PRHREPORTPAIR, in turn from 3 places in PRHTABLISTLEVEL.
local strtypeof3it = ''
local strvalue3out = ''
strtypeof3it = type(varany3type)
strvalue3out = 'type ' .. strtypeof3it
if ((strtypeof3it=='boolean') or (strtypeof3it=='number')) then
strvalue3out = strvalue3out .. ' and value ' .. tostring (varany3type)
end--if
if (strtypeof3it=='string') then
strvalue3out = strvalue3out .. ' and value "' .. primini3ksani(varany3type,booutf8ke3ep) .. '"'
end--if (strtypeof3it=='string') then
return strvalue3out
end--function prhreportvalue
------------------------------------------------------------------------
local function prhreportpair (varmykey, varmyvalue, booutf8pr4sv, boorebrew4lua)
local strpair4out = ''
if (boorebrew4lua) then
strpair4out = '[' .. prhreportkey(varmykey,booutf8pr4sv,boorebrew4lua) .. ']=' .. prhreportvalue(varmyvalue,booutf8pr4sv,boorebrew4lua)
else
strpair4out = prhreportkey(varmykey,booutf8pr4sv,boorebrew4lua) .. ' -> ' .. prhreportvalue(varmyvalue,booutf8pr4sv,boorebrew4lua)
end--if
return strpair4out
end--function prhreportpair
------------------------------------------------------------------------
local function lfhalltostring (varwhatever)
-- Called only from "lfhcompareidiotsafe".
local strtypeofstuff = ''
strtypeofstuff = type(varwhatever)
if (strtypeofstuff=='number') then
strtypeofstuff = '0'
end--if
if (strtypeofstuff=='string') then
strtypeofstuff = '1'
end--if
strtypeofstuff = strtypeofstuff .. tostring(varwhatever)
return strtypeofstuff
end--function lfhalltostring
------------------------------------------------------------------------
-- Local function LFHCOMPAREIDIOTSAFE
-- The sortorder is:
-- * number
-- * string
-- * everything else (boolean -> function -> table)
-- For example 5 will be less than "4".
-- Only for one of two uses of "table.sort" in "lfhtableanal".
local function lfhcompareidiotsafe (varaa, varbb)
local booaaisless = false
booaaisless = (lfhalltostring(varaa)<lfhalltostring(varbb))
return booaaisless
end--function lfhcompareidiotsafe
------------------------------------------------------------------------
-- Local function LFHTABLEANAL
-- we must use "in pairs" since the incoming table could be metaized
-- numeric keys out of range (-999'000...999'000) or non-integer,
-- as well as string keys out of range (1...60) land among other keys
local function lfhtableanal (tabnko)
local taballkeystring = {} -- ONE-based
local taballcetvalues = {} -- ONE-based
local numkatrol = 0
local numkeynumber = 0 -- count of numeric keys only integer and in range
local numkeystring = 0 -- count of string keys only in range
local numkeycetera = 0 -- count of other keys
local numkey77min = 999999
local numkey77max = -999999
local boodone = false
for k9k,v9v in pairs(tabnko) do
boodone = false
if (type(k9k)=='number') then
if ((k9k==math.floor(k9k)) and (k9k>=-999000) and (k9k<=999000)) then -- protect against insanity
numkey77min = math.min (numkey77min,k9k)
numkey77max = math.max (numkey77max,k9k)
numkeynumber = numkeynumber + 1
boodone = true
end--if
end--if
if (type(k9k)=='string') then
numkatrol = string.len(k9k)
if ((numkatrol~=0) and (numkatrol<=60)) then -- protect against insanity
taballkeystring [numkeystring+1] = k9k -- ONE-based for "table.sort"
numkeystring = numkeystring + 1
boodone = true
end--if
end--if
if (not boodone) then
taballcetvalues [numkeycetera+1] = v9v -- ONE-based for "table.sort"
numkeycetera = numkeycetera + 1 -- here we directly store the value !!!
end--if
end--for
table.sort(taballkeystring) -- all are strings -- otherwise the sortorder is messy
table.sort(taballcetvalues,lfhcompareidiotsafe) -- various types -- otherwise the sortorder is messy
return numkeynumber, numkey77min, numkey77max, numkeystring, numkeycetera, taballkeystring, taballcetvalues
end--function lfhtableanal
------------------------------------------------------------------------
local function prhtablistlevel (tabobscure, numincom6level, booutf8pr6sv, boorebrew6lua)
-- This is the RECURSIVE HOLY CORE.
-- Depends on procedures :
-- [H] prhreportkey prhreportvalue prhreportpair lfhalltostring lfhcompareidiotsafe
-- [H] lfhtableanal
-- [I] prifontsizetit lfifont90nbsize lfileftlevel primini3ksani
-- numeric keys -> string keys -> other keys
local varta3mp = 0
local tablisto = {}
local tabvaluo = {}
local strte7mp = ''
local strthispair = ''
local strgg = ''
local strkeystring = ''
local strli7mit = ''
local numtitlevel = 0
local numindax = 0
local numjumlahnum = 0
local numqqmin = 0
local numqqmax = 0
local numjumlahstr = 0
local numjumlahcet = 0
if (boorebrew6lua) then
strli7mit = "['ERROR']='limit of 7 nesting levels reached, deeper content is up in the air'"
else
strli7mit = " <b>limit of 7 nesting levels reached, deeper content is up in the air</b>" -- begins with space
end--if
numtitlevel = numincom6level * 2 -- consuming 2 indent levels per table level
numjumlahnum, numqqmin, numqqmax, numjumlahstr, numjumlahcet, tablisto, tabvaluo = lfhtableanal(tabobscure)
if (not boorebrew6lua) then
strte7mp = 'The table (level ' .. tostring(numincom6level) .. ')'
if ((numjumlahnum==0) and (numjumlahstr==0) and (numjumlahcet==0)) then
strte7mp = strte7mp .. ' is empty'
else
strte7mp = strte7mp .. ' contains '
if (numjumlahnum==0) then
strte7mp = strte7mp .. 'NO numeric keys'
end--if
if (numjumlahnum==1) then
strte7mp = strte7mp .. 'a single numeric key equal ' .. tostring (numqqmin)
end--if
if (numjumlahnum>=2) then
strte7mp = strte7mp .. tostring (numjumlahnum) .. ' numeric keys ranging from ' .. tostring (numqqmin) .. ' to ' .. tostring (numqqmax)
end--if
strte7mp = strte7mp .. ' and ' .. tostring (numjumlahstr) .. ' string keys and ' .. tostring (numjumlahcet) .. ' other keys'
end--if
strgg = lfileftlevel(numtitlevel) .. prifontsizetit((strte7mp .. '.'),numtitlevel)
else
strgg = '{'
if (numjumlahcet~=0) then
strgg = strgg .. "['ERROR']='other keys'"
end--if
end--if (not boorebrew6lua) else
if (numjumlahnum~=0) then
if (not boorebrew6lua) then
strgg = strgg .. lfileftlevel(numtitlevel) .. prifontsizetit('Numeric keys:',numtitlevel)
end--if
numindax = numqqmin
while true do
if (numindax>numqqmax) then
break
end--if
varta3mp = tabobscure[numindax]
if (varta3mp~=nil) then -- holes well possible
strthispair = prhreportpair(numindax,varta3mp,booutf8pr6sv,boorebrew6lua)
strgg = strgg .. lfileftlevel(numtitlevel+1) .. lfifont90nbsize(strthispair)
if (type(varta3mp)=='table') then
if (numincom6level<=6) then
strgg = strgg .. prhtablistlevel (varta3mp,(numincom6level+1),booutf8pr6sv,boorebrew6lua) -- REKURSI
else
strgg = strgg .. strli7mit
end--if
end--if
end--if (varta3mp~=nil) then
numindax = numindax + 1
end--while
end--if (numjumlahnum~=0) then
if (numjumlahstr~=0) then
if (not boorebrew6lua) then
strgg = strgg .. lfileftlevel(numtitlevel) .. prifontsizetit('String keys:',numtitlevel)
end--if
numindax = 0
while true do
if (numindax>=numjumlahstr) then -- index is ZERO-based
break
end--if
strkeystring = tablisto [numindax+1] -- ONE-based due to "table.sort"
if (type(strkeystring)=='string') then -- always true ??
varta3mp = tabobscure[strkeystring]
if (varta3mp~=nil) then -- always true ??
strthispair = prhreportpair(strkeystring,varta3mp,booutf8pr6sv,boorebrew6lua)
strgg = strgg .. lfileftlevel(numtitlevel+1) .. lfifont90nbsize(strthispair)
if (type(varta3mp)=='table') then
if (numincom6level<=6) then
strgg = strgg .. prhtablistlevel (varta3mp,(numincom6level+1),booutf8pr6sv,boorebrew6lua) -- REKURSI
else
strgg = strgg .. strli7mit
end--if
end--if
end--if (varta3mp~=nil) then
end--if
numindax = numindax + 1
end--while
end--if (numjumlahstr~=0) then
if ((not boorebrew6lua) and (numjumlahcet~=0)) then -- no reconstruction, no recursion here, all keys reported as "??"
strgg = strgg .. lfileftlevel(numtitlevel) .. prifontsizetit('Other keys:',numtitlevel)
numindax = 0
while true do
if (numindax>=numjumlahcet) then -- index is ZERO-based
break
end--if
varta3mp = tabvaluo [numindax+1] -- ONE-based due to "table.sort"
if (varta3mp~=nil) then -- always true ??
strthispair = prhreportpair('??',varta3mp,booutf8pr6sv,false)
strgg = strgg .. lfileftlevel(numtitlevel+1) .. lfifont90nbsize(strthispair)
end--if (varta3mp~=nil) then
numindax = numindax + 1
end--while
end--if ((not boorebrew6lua) and (numjumlahcet~=0)) then
if (boorebrew6lua) then
strgg = strgg .. '}'
end--if
if (numincom6level==0) then
strgg = strgg .. string.char(10) -- terminate very last line
end--if
return strgg
end--function prhtablistlevel
------------------------------------------------------------------------
local function prhtablist (tabveryobscure, strtitofreport, booutf8pr7sv, boorebrew7lua)
-- List all content of a table in a structured layout.
-- Input : * tabveryobscure -- must be type "table"
-- Depends on procedures :
-- [H] prhreportkey prhreportvalue prhreportpair lfhalltostring lfhcompareidiotsafe
-- [H] lfhtableanal prhtablistlevel
-- [I] prifontsizetit lfifont90nbsize lfileftlevel primini3ksani
local numlennel = 0
local strhh = ''
if ((not boorebrew7lua) and (type(strtitofreport)=='string')) then
numlennel = string.len(strtitofreport)
if ((numlennel~=0) and (numlennel<=100)) then -- got valid title
strhh = prifontsizetit(strtitofreport,-1) .. '<br>' -- special level
end--if
end--if
strhh = strhh .. prhtablistlevel (tabveryobscure,0,booutf8pr7sv,boorebrew7lua)
return strhh
end--function prhtablist
-- ***********************
-- * VARIABLES [R] * ---------------------------------------------
-- ***********************
function exporttable.ek (arxframent)
-- unknown type and special type "args" AKA "arx"
local vararixxo = 0
local varfromparent = 0
local varourbigtable = 0
local arxsomons = 0 -- metaized "args" from our own or parent's "frame"
-- str misc
local strerrxtra = ''
local strtajtlo = ''
local strreport = ''
local strtkmp = ''
-- num misc
local numerr = 0
-- boo misc
local boofrominvoke = false
local booutf8pr9sv = false -- from "UTF8"
local boorebrew9lua = false -- from "SRC"
local boodoimport = false
local boogotit = false
-- ******************
-- * MAIN [Z] * --------------------------------------------------
-- ******************
---- ARX EITHER FROM TEMPLATE OR FROM MODULE ----
arxsomons = arxframent.args -- "args" from our own "frame"
if (type(arxsomons)=='table') then
if (arxsomons['parentframe']=='true') then
arxsomons = arxframent:getParent().args -- "args" from parent's "frame"
end--if
boofrominvoke = (type(arxsomons)=='table') -- failure should be impossible
end--if
if (boofrominvoke) then
vararixxo = arxsomons -- from template with subtable "args"
else
vararixxo = arxframent -- from module without subtable "args"
end--if
varfromparent = vararixxo[1] -- need "string" or "table" but risk of other
booutf8pr9sv = (vararixxo[2]=='UTF8') or (vararixxo[3]=='UTF8')
boorebrew9lua = (vararixxo[2]=='SRC') or (vararixxo[3]=='SRC')
---- CHECK ----
if (varfromparent==nil) then
numerr = 2 -- #E02 -- invalid call, nothing provided
else
strtkmp = type(varfromparent)
boodoimport = (strtkmp=='string')
if ((not boodoimport) and (strtkmp~='table')) then
numerr = 3 -- #E03 -- wrong non-nil data type from module
varfromparent = 0
strerrxtra = 'wrong data type: "' .. strtkmp .. '"'
end--if
end--if
---- IMPORT VIA LOADDATA OR NOT ----
if (boodoimport) then
boogotit,varourbigtable = pcall(mw.loadData,varfromparent) -- could crash here
if (boogotit) then
boogotit = (type(varourbigtable)=='table') -- unlikely to fail here
else
strerrxtra = 'import error: "' .. tostring(varourbigtable) .. '"' -- seize error message
end--if
if (not boogotit) then
numerr = 4 -- #E04 import failure
varourbigtable = 0
end--if
else
varourbigtable = varfromparent
end--if
---- LIST ----
-- just calling big function "prhtablist"
if (numerr==0) then
if (boodoimport) then
strtajtlo = 'Table imported from data module "' .. varfromparent .. '"'
else
strtajtlo = 'Table coming directly from parent module'
end--if
strreport = prhtablist(varourbigtable, strtajtlo, booutf8pr9sv, boorebrew9lua)
else
strreport = 'ERR: ' .. tostring(numerr)
if (strerrxtra~='') then
strreport = strreport .. ' ' .. strerrxtra
end--if
end--if
---- RETURN THE STRING ----
return strreport
end--function exporttable.ek
---- RETURN THE LUA TABLE ----
return exporttable