Lompat ke isi

Modul:Listtable

Dari Wikipedia bahasa Indonesia, ensiklopedia bebas

--[===[

MODULE "LISTTABLE"

"eo.wiktionary.org/wiki/Modulo:listtable" <!--2025-Jul-12-->
"sv.wiktionary.org/wiki/Modul:listtable"

Purpose: show all content of a table, even a metaized one,
         even recursively up to 7 levels

Required submodules / Bezonataj submoduloj /
Submodul yang diperlukan / Behoevda submoduler:
* none

Incoming: * 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
              (data type "string") of data module to be imported via
              "loadData", with namespace prefix
          * optional "UTF8"

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|UTF8}}

Examples of calling from module (import):

  local qlisttable = require ('Module:listtable')
  local strimport = 'Modul:tagg/data'
  local strmyreport = qlisttable.ek { strimport }

  local qlisttable = require ('Module:listtable')
  local strimport = 'Modul: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 exporttable = {}

require('strict')

-- ******************************************
-- *    HIGH LEVEL STRING PROCEDURES [I]    * --------------------------
-- ******************************************

local function prifontsizetit (strtexto, numlevel)

-- called from "lfhtablstlev" (level 0...13) and
-- from "prhtablist" (special 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 lfimini3ksani (strdangstring, booutf8keepit)

-- 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 lfimini3ksani

-- ***********************************
-- *    HIGH LEVEL PROCEDURES [H]    * ---------------------------------
-- ***********************************

local function prhreportvari (varanytype, booutfg8keep)

-- Input  : * booutfg8keep -- true to keep UTF8 intact, else dec-encoded

-- Called from 3 places in "lfhtablstlev".


local strtypeofit = ''
local strdescription = ''

  strtypeofit = type(varanytype)
  strdescription = 'type ' .. strtypeofit
  if ((strtypeofit=='boolean') or (strtypeofit=='number')) then
    strdescription = strdescription .. ' and value ' .. tostring (varanytype)
  end--if
  if (strtypeofit=='string') then
    strdescription = strdescription .. ' and value "' .. lfimini3ksani(varanytype,booutfg8keep) .. '"'
  end--if (strtypeofit=='string') then

return strdescription

end--function prhreportvari

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

-- Local function LFHALLTOSTRING

-- Called only from "lfhcompareidiotsafe".

local function lfhalltostring (varwhatever)
  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 lfhtablstlev (tabobscure, numincomlevel, booutf8preserve)

-- Depends on procedures :
-- [H] prhreportvari lfhalltostring lfhcompareidiotsafe
-- [H] lfhtableanal
-- [I] prifontsizetit lfifont90nbsize lfileftlevel lfimini3ksani

-- numeric keys -> string keys -> other keys

  local varta3mp = 0

  local tablisto = {}
  local tabvaluo = {}

  local strte7mp = ''
  local strgg = ''
  local strkeystring = ''
  local strli7mit = ' <b>limit of 7 nesting levels reached, deeper content is up in the air</b>' -- begins with space

  local numtitlevel = 0
  local numindax = 0
  local numjumlahnum = 0
  local numqqmin = 0
  local numqqmax = 0
  local numjumlahstr = 0
  local numjumlahcet = 0

  numtitlevel = numincomlevel * 2 -- consuming 2 star levels per table level

  numjumlahnum, numqqmin, numqqmax, numjumlahstr, numjumlahcet, tablisto, tabvaluo = lfhtableanal(tabobscure)

  strte7mp = 'The table (level ' .. tostring(numincomlevel) .. ')'
  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)

  if (numjumlahnum~=0) then
    strgg = strgg .. lfileftlevel(numtitlevel) .. prifontsizetit('Numeric keys:',numtitlevel)
    numindax = numqqmin
    while true do
      if (numindax>numqqmax) then
        break
      end--if
      varta3mp = tabobscure[numindax]
      if (varta3mp~=nil) then -- holes well possible
        strte7mp = tostring (numindax) .. ' -> ' .. prhreportvari(varta3mp,booutf8preserve) -- no quot for key
        strgg = strgg .. lfileftlevel(numtitlevel+1) .. lfifont90nbsize(strte7mp)
        if (type(varta3mp)=='table') then
          if (numincomlevel<=6) then
            strgg = strgg .. lfhtablstlev (varta3mp,(numincomlevel+1),booutf8preserve) -- 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
    strgg = strgg .. lfileftlevel(numtitlevel) .. prifontsizetit('String keys:',numtitlevel)
    numindax = 0
    while true do
      if (numindax>=numjumlahstr) then -- index is ZERO-based
        break
      end--if
      strkeystring = tablisto [numindax+1] -- ONE-based for "table.sort"
      if (type(strkeystring)=='string') then -- always true ??
        varta3mp = tabobscure[strkeystring]
        if (varta3mp~=nil) then -- always true ??
          strte7mp = '"' .. lfimini3ksani(strkeystring,booutf8preserve) .. '" -> ' .. prhreportvari(varta3mp,booutf8preserve)
          strgg = strgg .. lfileftlevel(numtitlevel+1) .. lfifont90nbsize(strte7mp)
          if (type(varta3mp)=='table') then
            if (numincomlevel<=6) then
              strgg = strgg .. lfhtablstlev (varta3mp,(numincomlevel+1),booutf8preserve) -- 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 (numjumlahcet~=0) then -- 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 for "table.sort"
      if (varta3mp~=nil) then -- always true ??
        strte7mp = '?? -> ' .. prhreportvari(varta3mp,booutf8preserve)
        strgg = strgg .. lfileftlevel(numtitlevel+1) .. lfifont90nbsize(strte7mp)
      end--if (varta3mp~=nil) then
      numindax = numindax + 1
    end--while
  end--if (numjumlahcet~=0) then

  if (numincomlevel==0) then
    strgg = strgg .. string.char(10) -- terminate very last line
  end--if

  return strgg

end--function lfhtablstlev

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

local function prhtablist (tabveryobscure, strtitofreport, boopresutf8erve)

-- List all content of a table in a structured layout.

-- Input  : * tabveryobscure -- must be type "table"

-- Depends on procedures :
-- [H] prhreportvari lfhalltostring lfhcompareidiotsafe
-- [H] lfhtableanal lfhtablstlev
-- [I] prifontsizetit lfifont90nbsize lfileftlevel lfimini3ksani

local numlennel = 0
local strhh = ''

  if (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 .. lfhtablstlev (tabveryobscure,0,boopresutf8erve)

return strhh

end--function prhtablist

-- ***********************
-- *    VARIABLES [R]    * ---------------------------------------------
-- ***********************

function exporttable.ek (arxframent)

  -- unknown type and special type "args" AKA "arx"

  local varfromparent  = 0
  local varutf8pres    = 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 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
    varfromparent = arxsomons[1] -- from template with "args", risk of "nil"
    varutf8pres   = arxsomons[2]
  else
    varfromparent = arxframent[1] -- from module without "args", risk of "nil"
    varutf8pres   = arxframent[2]
  end--if

  ---- CHECK ----

  if (varfromparent==nil) then
    numerr = 2 -- #E02 -- invalid call
  else
    strtkmp = type(varfromparent)
    boodoimport = (strtkmp=='string')
    if ((not boodoimport) and (strtkmp~='table')) then
      numerr = 3 -- #E03 -- wrong data type
      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, (varutf8pres=='UTF8'))
  else
    strreport = 'ERR: ' .. tostring(numerr)
    if (strerrxtra~='') then
      strreport = strreport .. ' ' .. strerrxtra
    end--if
  end--if

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

  return strreport

end--function exporttable.ek

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

return exporttable