Jump to content

Module:Data to Table: Difference between revisions

From The Petit Planet Wiki
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..."
 
ReisuDesign (talk | contribs)
No edit summary
Line 1: Line 1:
local p = {}
local p = {}
local CleanTT = require('Module:tt').CleanTT
local CleanTT = require('Module:tt').CleanTT
local lib = require('Module:Feature')
local lib = require('Module:Feature')
local ne = lib.isNotEmpty
local ne = lib.isNotEmpty
local block = false
local block = false
--check for if the entry is the first on the level
 
-- Check if the entry is the first on the level
local first = {true, true, true}
local first = {true, true, true}
--check for if the entry is right after the end of a deeper level
 
-- Check if the entry is right after the end of a deeper level
local previous = {false, false, false}
local previous = {false, false, false}


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


function p.main(frame)
function p.main(frame)
local info = {}
local info = {}
local dataKeys = {}
local dataKeys = {}
local rawKeys = {}
-- Parse DPL data
if frame.args.info then
if frame.args.info then
if ne(frame.args.cleanTT) then frame.args.info = CleanTT(frame.args.info) end -- remove TTs
if ne(frame.args.cleanTT) then
info = lib.parseTemplateFormat(frame.args.info, ';;', '$$$', '==')
frame.args.info = CleanTT(frame.args.info)
else return '' end
end
if frame.args.keys then dataKeys = p.ParseKeys(frame.args.keys) end
 
if ne(frame.args.block) then block = true end
info = lib.parseTemplateFormat(
frame.args.info,
';;',
'$$$',
'=='
)
else
return ''
end
 
-- Parse keys
if frame.args.keys then
dataKeys = p.ParseKeys(frame.args.keys)
end
 
-- Parse unquoted/raw keys
if frame.args.unquoted then
rawKeys = p.ParseKeys(frame.args.unquoted)
end
 
-- Block formatting
if ne(frame.args.block) then
block = true
end
 
local sortkey = frame.args.sortkey or 'page'
local sortkey = frame.args.sortkey or 'page'
local subtable = frame.args.subtable
local subtable = frame.args.subtable
 
local result = mw.html.create('pre'):css({['min-height'] = '25px',['line-height'] = '16px'}):wikitext('return {\n')
 
-- Check whether a key should be output as raw Lua
local function isUnquotedKey(key)
for _, rawKey in ipairs(rawKeys) do
if rawKey == key then
return true
end
end
 
return false
end
 
 
-- Build result
local result = mw.html.create('pre')
:css({
['min-height'] = '25px',
['line-height'] = '16px'
})
:wikitext('return {\n')
 
 
local items = {}
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
 
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
if ne(entry.page) then
entry.page = clean(entry.page)
entry.page = clean(entry.page)
-- No data keys: output page as a simple string
if #dataKeys == 0 then
if #dataKeys == 0 then
result:wikitext('\t\'', entry.page, '\',\n')
 
result:wikitext(
'\t\'',
entry.page,
'\',\n'
)
 
else
else
-- Reset formatting state for every entry
first = {true, true, true}
first = {true, true, true}
previous = {false, false, false}
previous = {false, false, false}
local valid = false
local valid = false
local values = mw.html.create()
local values = mw.html.create()
values:wikitext('\t[\'', entry.page, '\']')
 
-- Entry name
--build entry
values:wikitext(
'\t[\'',
entry.page,
'\'] = {'
)
 
-- Build entry
local function parseLevels(K, level)
local function parseLevels(K, level)
level = level or 1
level = level or 1
if type(K) == 'string' and ne(entry[K]) then
 
if type(K) == 'string' and entry[K] ~= nil then
 
valid = true
valid = true
values:node(p.BuildEntry(entry[K], K, level, subtable))
 
values:node(
p.BuildEntry(
entry[K],
K,
level,
subtable,
isUnquotedKey(K)
)
)
 
elseif type(K) == 'table' then
elseif type(K) == 'table' then
level = level + 1
level = level + 1
for _, K2 in ipairs(K) do
for _, K2 in ipairs(K) do
parseLevels(K2, level)
parseLevels(K2, level)
end
end
values:wikitext((block and ('\n' .. string.rep('\t', level-1)) or ' '),'},\n')
 
values:wikitext(
block
and ('\n' .. string.rep('\t', level - 1))
or ' ',
'},'
)
end
end
end
end
parseLevels(dataKeys, 1)
parseLevels(dataKeys, 1)
 
--return table is any valid data, return plain string otherwise
-- Return table if there is valid data,
-- otherwise return the page as a plain string
if valid then
if valid then
values:wikitext('\n')
result:node(values)
result:node(values)
else
else
result:wikitext('\t\'', entry.page, '\',\n')
result:wikitext(
'\t\'',
entry.page,
'\',\n'
)
end
end
end
end
    end
end
end
end
result:wikitext('}')
result:wikitext('}')
 
-- Copy button
if frame.args.copy then
if frame.args.copy then
result = require('Module:CopyText')._main({ tostring(result), frame.args.copy, 'Copy Table' })
result = require('Module:CopyText')._main({
tostring(result),
frame.args.copy,
'Copy Table'
})
end
end
 
return result
return result
end
end


--format data
 
function p.BuildEntry(value, key, level, subtable)
-- Format data
function p.BuildEntry(value, key, level, subtable, unquoted)
level = level or 1
level = level or 1
local container = mw.html.create()
local container = mw.html.create()
if ne(value) then
 
-- Keep empty values
if value ~= nil then
 
-- Format value
if subtable and value:find(subtable) then
if subtable and value:find(subtable) then
value = lib.split(clean(value), subtable)
 
value = '{ \'' .. table.concat(value, '\', \'') .. '\' }'
value = lib.split(
clean(value),
subtable
)
 
value = '{ \'' ..
table.concat(value, '\', \'') ..
' }'
 
elseif unquoted then
 
-- Raw Lua value
value = clean(value)
 
else
else
value = '\'' .. clean(value) .. '\''
 
-- String value
value = '\'' ..
clean(value) ..
'\''
 
end
end
-- Format key as ['key']
local formattedKey =
'[\'' .. clean(key) .. '\']'
-- First item on this level
if first[level] then
if first[level] then
container:wikitext(' = {', (block and ('\n' .. string.rep('\t', level)) or ' '), clean(key), ' = ', value)
 
container:wikitext(
'\n',
string.rep('\t', level),
formattedKey,
' = ',
value,
','
)
 
first[level] = false
first[level] = false
if level > 2 then first[2] = false end
 
if level > 1 then first[1] = false end
if level > 2 then
elseif (not first[level]) then
first[2] = false
container:wikitext((block and (',\n' .. string.rep('\t', level)) or ', '), clean(key), ' = ', value)
end
 
if level > 1 then
first[1] = false
end
 
 
-- Subsequent item on this level
else
 
container:wikitext(
'\n',
string.rep('\t', level),
formattedKey,
' = ',
value,
','
)
 
previous[level] = false
previous[level] = false
end
end
end
end
return container
return container
end
end


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


return p
return p

Revision as of 17:08, 3 September 2026

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 if the entry is the first on the level
local first = {true, true, true}

-- Check 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 = {}
	local rawKeys = {}

	-- Parse DPL data
	if frame.args.info then
		if ne(frame.args.cleanTT) then
			frame.args.info = CleanTT(frame.args.info)
		end

		info = lib.parseTemplateFormat(
			frame.args.info,
			';;',
			'$$$',
			'=='
		)
	else
		return ''
	end

	-- Parse keys
	if frame.args.keys then
		dataKeys = p.ParseKeys(frame.args.keys)
	end

	-- Parse unquoted/raw keys
	if frame.args.unquoted then
		rawKeys = p.ParseKeys(frame.args.unquoted)
	end

	-- Block formatting
	if ne(frame.args.block) then
		block = true
	end

	local sortkey = frame.args.sortkey or 'page'
	local subtable = frame.args.subtable


	-- Check whether a key should be output as raw Lua
	local function isUnquotedKey(key)
		for _, rawKey in ipairs(rawKeys) do
			if rawKey == key then
				return true
			end
		end

		return false
	end


	-- Build result
	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)

			-- No data keys: output page as a simple string
			if #dataKeys == 0 then

				result:wikitext(
					'\t\'',
					entry.page,
					'\',\n'
				)

			else

				-- Reset formatting state for every entry
				first = {true, true, true}
				previous = {false, false, false}

				local valid = false
				local values = mw.html.create()

				-- Entry name
				values:wikitext(
					'\t[\'',
					entry.page,
					'\'] = {'
				)

				-- Build entry
				local function parseLevels(K, level)
					level = level or 1

					if type(K) == 'string' and entry[K] ~= nil then

						valid = true

						values:node(
							p.BuildEntry(
								entry[K],
								K,
								level,
								subtable,
								isUnquotedKey(K)
							)
						)

					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 ' ',
							'},'
						)
					end
				end

				parseLevels(dataKeys, 1)

				-- Return table if there is valid data,
				-- otherwise return the page as a plain string
				if valid then
					values:wikitext('\n')
					result:node(values)
				else
					result:wikitext(
						'\t\'',
						entry.page,
						'\',\n'
					)
				end
			end
		end
	end

	result:wikitext('}')

	-- Copy button
	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, unquoted)
	level = level or 1

	local container = mw.html.create()

	-- Keep empty values
	if value ~= nil then

		-- Format value
		if subtable and value:find(subtable) then

			value = lib.split(
				clean(value),
				subtable
			)

			value = '{ \'' ..
				table.concat(value, '\', \'') ..
				' }'

		elseif unquoted then

			-- Raw Lua value
			value = clean(value)

		else

			-- String value
			value = '\'' ..
				clean(value) ..
				'\''

		end


		-- Format key as ['key']
		local formattedKey =
			'[\'' .. clean(key) .. '\']'


		-- First item on this level
		if first[level] then

			container:wikitext(
				'\n',
				string.rep('\t', level),
				formattedKey,
				' = ',
				value,
				','
			)

			first[level] = false

			if level > 2 then
				first[2] = false
			end

			if level > 1 then
				first[1] = false
			end


		-- Subsequent item on this level
		else

			container:wikitext(
				'\n',
				string.rep('\t', level),
				formattedKey,
				' = ',
				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