Module:Data to Table

Revision as of 14:56, 3 September 2026 by ReisuDesign (talk | contribs) (Created page with "local p = {} local CleanTT = require('Module:tt').CleanTT local lib = require('Module:Feature') local ne = lib.isNotEmpty local block = false --check for if the entry is the first on the level local first = {true, true, true} --check for if the entry is right after the end of a deeper level local previous = {false, false, false} --escape characters local function clean(txt) txt = txt:gsub('&(%a+;)','&%1'):gsub('\'','\\''):gsub('<', '<'):gsub('\'', '\\\'') r...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Module documentation

This module implements {{Data to Table}}.

local p = {}
local CleanTT = require('Module:tt').CleanTT
local lib = require('Module:Feature')
local ne = lib.isNotEmpty
local block = false
--check for if the entry is the first on the level
local first = {true, true, true}
--check for if the entry is right after the end of a deeper level
local previous = {false, false, false}

--escape characters
local function clean(txt)
	txt = txt:gsub('&(%a+;)','&amp;%1'):gsub('\'','\\&#39;'):gsub('<', '&lt;'):gsub('\'', '\\\'')
	return txt
end

function p.main(frame)
	local info = {}
	local dataKeys = {}
	if frame.args.info then
		if ne(frame.args.cleanTT) then frame.args.info = CleanTT(frame.args.info) end -- remove TTs
		info = lib.parseTemplateFormat(frame.args.info, ';;', '$$$', '==')
	else return '' end
	if frame.args.keys then dataKeys = p.ParseKeys(frame.args.keys) end
	if ne(frame.args.block) then block = true end
	local sortkey = frame.args.sortkey or 'page'
	local subtable = frame.args.subtable
	
	local result = mw.html.create('pre'):css({['min-height'] = '25px',['line-height'] = '16px'}):wikitext('return {\n')
	local items = {}
	for _,entry in lib.spairs(info, function(tVal, a, b) if sortkey == 'INPUT' then return a < b else return (tVal[a][sortkey] or '') < (tVal[b][sortkey] or '') end end) do
		if ne(entry.page) then
			entry.page = clean(entry.page)
			if #dataKeys == 0 then
				result:wikitext('\t\'', entry.page, '\',\n')
			else
				first = {true, true, true}
				previous = {false, false, false}
				local valid = false
				local values = mw.html.create()
				values:wikitext('\t[\'', entry.page, '\']')
				
				--build entry
				local function parseLevels(K, level)
					level = level or 1
					if type(K) == 'string' and ne(entry[K]) then
						valid = true
						values:node(p.BuildEntry(entry[K], K, level, subtable))
					elseif type(K) == 'table' then
						level = level + 1
						for _, K2 in ipairs(K) do
							parseLevels(K2, level)
						end
						values:wikitext((block and ('\n' .. string.rep('\t', level-1)) or ' '),'},\n')
					end
				end
				parseLevels(dataKeys, 1)
				
				--return table is any valid data, return plain string otherwise
				if valid then
					result:node(values)
				else
					result:wikitext('\t\'', entry.page, '\',\n')
				end
			end
	    end
	end
	result:wikitext('}')
	
	if frame.args.copy then
		result = require('Module:CopyText')._main({ tostring(result), frame.args.copy, 'Copy Table' })
	end
	
	return result
end

--format data
function p.BuildEntry(value, key, level, subtable)
	level = level or 1
	local container = mw.html.create()
	if ne(value) then
		if subtable and value:find(subtable) then
			value = lib.split(clean(value), subtable)
			value = '{ \'' .. table.concat(value, '\', \'') .. '\' }'
		else
			value = '\'' .. clean(value) .. '\''
		end
		if first[level] then
			container:wikitext(' = {', (block and ('\n' .. string.rep('\t', level)) or ' '), clean(key), ' = ', value)
			first[level] = false
			if level > 2 then first[2] = false end
			if level > 1 then first[1] = false end
		elseif (not first[level]) then
			container:wikitext((block and (',\n' .. string.rep('\t', level)) or ', '), clean(key), ' = ', value)
			previous[level] = false
		end
	end
	return container
end

--parse data keys into specified levels
function p.ParseKeys(keys)
	keys = lib.split(keys, ';;')
	for i, key in pairs(keys) do
		if key:find('//') then
			local keys2 = lib.split(key, '//')
			for i2, key2 in pairs(keys2) do
				if key2:find('@@') then
					keys2[i2] = lib.split(key, '@@')
				end
			end
			keys[i] = keys2
		end
	end
	return keys
end

return p