Module:Infobox ET: Difference between revisions

From Xenharmonic Wiki
Jump to navigation Jump to search
Move special properties to the last, move octave before fifth. Add "dual" marker to sharp and flat fifths
ArrowHead294 (talk | contribs)
mNo edit summary
 
(102 intermediate revisions by 9 users not shown)
Line 1: Line 1:
local p = {}
local p = {}
local i = require('Module:Interval')
 
local u = require('Module:Utils')
local ET = require("Module:ET")
local rat = require('Module:Rational')
local getArgs = require("Module:Arguments").getArgs
local l = require('Module:Limits')
local infobox = require("Module:Infobox")
local ET = require('Module:ET')
local limits = require("Module:Limits")
local infobox = require('Module:Infobox')
local rat = require("Module:Rational")
local utils = require("Module:Utils")
local yesno = require("Module:Yesno")
 
-- check whether the input is a non-empty string
local function value_provided(s)
return type(s) == "string" and #s > 0
end


-- towards is one of: -1 (floor), 0 (nearest), 1 (ceil)
-- towards is one of: -1 (floor), 0 (nearest), 1 (ceil)
local function approximation(et, interval, towards, precomputed_approx)
local function approximation(et, interval, towards, precomputed_approx)
local approx = precomputed_approx or ET.approximate(et, interval, towards or 0)
local approx = precomputed_approx or ET.approximate(et, interval, towards or 0)
 
-- string for backslash notation
-- "edo" is omitted
local tuning = et.size
local tuning = et.size
if not rat.eq(et.equave, 2) then
if not rat.eq(et.equave, 2) then
tuning = tuning .. et.suffix
tuning = tuning .. et.suffix
end
end
 
local ratio = rat.new(approx, et.size)
local ratio = rat.new(approx, et.size)
 
local convergement_notice = ''
-- convergence notice, suppressed for 1ed's
local convergement_notice = ""
local converges = rat.converges(ratio, math.log(interval) / math.log(rat.as_float(et.equave)))
local converges = rat.converges(ratio, math.log(interval) / math.log(rat.as_float(et.equave)))
if converges then
if et.size > 1 and converges then
convergement_notice = '<br/>(' .. converges .. ')'
convergement_notice = "<br>(" .. converges .. ")"
end
end
 
if rat.as_table(ratio)[1] ~= approx then
if rat.as_table(ratio)[1] ~= approx then
convergement_notice = ''
convergement_notice = ""
local link = rat.as_table(ratio)[2] .. et.suffix
local link = rat.as_table(ratio)[2] .. et.suffix
ratio = ' ([[' .. link .. '|' .. rat.as_ratio(ratio, '\\')
ratio = string.format(" (&rarr;&nbsp;[[%s|%s%s]])",
if not rat.eq(et.equave, 2) then
link, rat.as_ratio(ratio, "\\"), (rat.eq(et.equave, 2) == false and et.suffix or ""))
ratio = ratio .. et.suffix
end
ratio = ratio .. ']])'
else
else
ratio = ''
ratio = ""
end
end
 
local cents = u._round(ET.cents(et, approx), 6)
local cents = utils._round(ET.cents(et, approx), 6)
 
return approx .. '\\' .. tuning .. ' (' .. cents .. '¢)' .. ratio .. convergement_notice
return string.format("%s\\%s (%s{{c}})%s%s",
approx, tuning, utils._round(ET.cents(et, approx), 6), ratio, convergement_notice)
end
end


function p.infobox_ET(frame)
function p.infobox_ET(frame)
-- debug mode
local args = getArgs(frame)
local debug_mode = frame.args['debug'] ~= nil
local categories = ''
local tuning = frame.args['tuning']
local et = ET.parse(tuning) or ET.parse('12edo')
-- debug mode will disable the categories
local debug_mode = yesno(frame.args["debug"] or args["debug"], false)
local wtext = yesno(frame.args["wtext"] or args["wtext"])
local tuning = frame.args["tuning"]
local et = ET.parse(tuning) or ET.parse(tuning .. "edo") or ET.parse("12edo")
-- category of the main article
-- category of the main article
categories = categories .. '[[Category:' .. tuning .. '| ]]'
local categories = string.format(" {{#ifexist: Category:%s|[[Category:%s| ]]|}}", tuning, tuning)
-- category of the equal division
-- category of the equal division
if rat.eq(et.equave, 2) then
if rat.eq(et.equave, 2) then
categories = categories .. '[[Category:Equal divisions of the octave|' .. string.rep ('#', string.len (et.size)) .. ']]'
categories = categories
.. string.format(" [[Category:Equal divisions of the octave|%s]]",
string.rep("#", string.len(et.size)))
elseif rat.eq(et.equave, 3) then
categories = categories .. string.format(" [[Category:Edts|%s]]",
string.rep("#", string.len(et.size)))
elseif rat.eq(et.equave, rat.new (3, 2)) then
categories = categories .. string.format(" [[Category:Edfs|%s]]",
string.rep("#", string.len(et.size)))
else
else
categories = categories .. '[[Category:' .. et.suffix .. '|' .. string.rep ('#', string.len (et.size)) .. ']]'
categories = categories .. string.format(" [[Category:%s's|%s]]",
et.suffix, string.rep("#", string.len(et.size)))
end
end
 
-- prime test
-- prime factorization
local prime = ""
local prime_factorization_override = frame.args["Prime factorization"]
if u.is_prime(et.size) then
local prime_factorization
prime = " (prime)"
if not value_provided(prime_factorization_override) then
if rat.eq(et.equave, 2) then
prime_factorization = utils._prime_factorization(et.size)
categories = categories .. '[[Category:Prime EDO]]'
if utils.is_prime(et.size) then
prime_factorization = prime_factorization .. " (prime)"
if rat.eq(et.equave, 2) then
categories = categories
.. string.format(" [[Category:Prime EDOs|%s]]",
string.rep("#", string.len(et.size)))
end
end
if ET.is_highly_composite(et) and et.size > 1 then
prime_factorization = prime_factorization .. " (highly composite)"
if rat.eq(et.equave, 2) then
categories = categories  
.. string.format(" [[Category:Highly composite EDOs|%s]]",
string.rep("#", string.len(et.size)))
end
end
end
else
prime_factorization = prime_factorization_override
end
end
 
-- zeta test
-- zeta test
local zeta_override = frame.args['Zeta']
local zeta_override = frame.args["Zeta"]
local zeta_switch = nil
local zeta_switch
if type(zeta_override) == 'string' and #zeta_override > 0 then
if value_provided(zeta_override) then
zeta_switch = not zeta_override:match('^[Nn][Oo]$')
zeta_switch = zeta_override:match("^[Yy][Ee][Ss]$") and ET.is_zeta(et)
else
else
zeta_switch = rat.eq(et.equave, 2) and ET.is_zeta(et)
zeta_switch = false
end
 
-- navigation arrows
local increment = 1
if rat.eq(et.equave, rat.new(9, 4)) or rat.eq(et.equave, 4) or rat.eq(et.equave, 9) then
increment = 2
end
end
local prev_one = ""
local prev_one = ''
if et.size >= increment then
if et.size > 0 then
prev_one = string.format("[[%s|&larr;&nbsp;%s]]",
prev_one = '[[' .. (et.size - 1) .. et.suffix .. '|← ' .. (et.size - 1) .. et.suffix .. ']]'
(et.size - increment) .. et.suffix, (et.size - increment) .. et.suffix)
end
end
local next_one = '[[' .. (et.size + 1) .. et.suffix .. '|' .. (et.size + 1) .. et.suffix .. ' →]]'
local next_one = string.format("[[%s|%s&nbsp;&rarr;]]",
(et.size + increment) .. et.suffix, (et.size + increment) .. et.suffix)
 
-- step size in cents
local step_size = ET.cents(et, 1)
local step_size = ET.cents(et, 1)
local note_12edo = ''
if step_size > 100 then
categories = categories .. string.format(" [[Category:Macrotonal|%s]]",
string.rep("#", string.len(et.size)))
end
local note_12edo = ""
if rat.eq(et.equave, 2) and et.size == 12 then
if rat.eq(et.equave, 2) and et.size == 12 then
note_12edo = '<sup>by definition</sup>'
note_12edo = " (by&nbsp;definition)"
end
end
 
-- octave, twelfth, and fifth in steps
local octave = ET.approximate(et, 2)
local octave = ET.approximate(et, 2)
local twelfth = ET.approximate(et, 3)
local twelfth = ET.approximate(et, 3)
 
local fifth = -octave + twelfth -- 3/2 = [-1 1>
local fifth = -octave + twelfth -- 3/2 = [-1 1>
local fifth_error = ET.cents(et, fifth) - i._to_cents(3/2)
local fifth_error = ET.cents(et, fifth) - rat.cents(rat.new(3, 2))
local dual_fifth = math.abs(fifth_error) > step_size / 3
local is_dual_fifth = math.abs(fifth_error) > step_size / 3


local A1 = -11 * octave + 7 * twelfth -- 2187/2048 = [-11 7>
local A1 = -11 * octave + 7 * twelfth -- 2187/2048 = [-11 7>
local m2 = 8 * octave - 5 * twelfth -- 256/243 = [8 -5>
local m2 = 8 * octave - 5 * twelfth -- 256/243 = [8 -5>
local A1_cents = u._round(ET.cents(et, A1), 4)
local A1_cents = utils._round(ET.cents(et, A1), 4)
local m2_cents = u._round(ET.cents(et, m2), 4)
local m2_cents = utils._round(ET.cents(et, m2), 4)


-- display
local infobox_data = {}
local infobox_data = {}
table.insert(infobox_data, {
table.insert(infobox_data, {
'Prime factorization',
"Prime factorization",
u._prime_factorization(et.size) .. prime
prime_factorization,
})
})


table.insert(infobox_data, {
table.insert(infobox_data, {
'Step size',
"Step size",
u._round(step_size, 6) .. '¢' .. note_12edo
string.format("%s{{c}}%s&nbsp;",
utils._round(step_size, 6), note_12edo)
})
})


if not rat.eq(et.equave, 2) then
if not rat.eq(et.equave, 2) then
table.insert(infobox_data, {
table.insert(infobox_data, {
'Octave',
"Octave",
approximation(et, 2)
approximation(et, 2),
})
})
end
if not rat.eq(et.equave, 3) then
table.insert(infobox_data, {
if not rat.eq(et.equave, rat.new(3, 2)) then
"Twelfth",
approximation(et, 3),
})
end
else
table.insert(infobox_data, {
table.insert(infobox_data, {
'Fifth',
"Fifth",
approximation(et, 3/2)
approximation(et, 3 / 2),
})
})
end
table.insert(infobox_data, {
'Semitones (A1:m2)',
A1 .. ':' .. m2 .. ' (' .. A1_cents .. '¢ : ' .. m2_cents .. '¢)'
})
if dual_fifth and et.size > 0 then
table.insert(infobox_data, {
table.insert(infobox_data, {
'Dual sharp fifth',
"Semitones (A1:m2)",
approximation(et, 3/2, 1)
string.format("%s:%s (%s{{c}}&nbsp;:&nbsp;%s{{c}})",
})
A1, m2, A1_cents, m2_cents)
table.insert(infobox_data, {
'Dual flat fifth',
approximation(et, 3/2, -1)
})
local sharp = ET.approximate(et, 3/2, 1)
local flat = ET.approximate(et, 3/2, -1)
table.insert(infobox_data, {
'Dual major 2nd',
approximation(et, 9/8, 0, sharp + flat - octave)
})
})
if is_dual_fifth and et.size > 0 then
table.insert(infobox_data, {
"Dual sharp fifth",
approximation(et, 3 / 2, 1),
})
table.insert(infobox_data, {
"Dual flat fifth",
approximation(et, 3 / 2, -1),
})
local sharp = ET.approximate(et, 3 / 2, 1)
local flat = ET.approximate(et, 3 / 2, -1)
table.insert(infobox_data, {
"Dual major 2nd",
approximation(et, 9 / 8, 0, sharp + flat - octave),
})
categories = categories
.. string.format(" [[Category:Dual-fifth temperaments|%s]]",
string.rep("#", string.len(et.size)))
end
end
end
 
local consistency = tonumber(frame.args['Consistency'])
-- consistency and distinct consistency
-- max_limit is used to prevent timeout
local consistency = tonumber(frame.args["Consistency"])
local max_limit = rat.eq(et.equave, 2) and 43 or 32
if consistency == nil then
if consistency == nil then
consistency = l.consistency_limit(et, false, 43)
consistency = limits.consistency_limit(et, false, max_limit)
end
end
if consistency == nil then
if consistency == nil then
consistency = 'at least 43'
consistency = "at least " .. max_limit
end
end
if consistency ~= nil then
if consistency ~= nil then
table.insert(infobox_data, {
table.insert(infobox_data, {
'Consistency limit',
"Consistency limit",
consistency
consistency,
})
})
end
end
local distinct_consistency = tonumber(frame.args['Distinct consistency'])
local distinct_consistency = tonumber(frame.args["Distinct consistency"])
if distinct_consistency == nil then
if distinct_consistency == nil then
distinct_consistency = l.consistency_limit(et, consistency or true, 43)
distinct_consistency = limits.consistency_limit(et, consistency or true, max_limit)
end
end
if distinct_consistency == nil then
if distinct_consistency == nil then
distinct_consistency = 'at least 43'
distinct_consistency = "at least " .. max_limit
end
end
if distinct_consistency ~= nil then
if distinct_consistency ~= nil then
table.insert(infobox_data, {
table.insert(infobox_data, {
'Distinct consistency limit',
"Distinct consistency limit",
distinct_consistency
distinct_consistency,
})
})
end
end


-- special properties
-- special properties
if ET.is_highly_composite(et) or zeta_switch then
if ET.is_zeta(et) then
local text = ''
local text = ""
if ET.is_highly_composite(et) then
if rat.eq(et.equave, 2) then
text = text .. '[[Highly composite equal division|highly composite]]'
categories = categories
if rat.eq(et.equave, 2) then
.. string.format(" [[Category:Zeta record EDOs|%s]]",
categories = categories .. '[[Category:Highly composite EDO|' .. string.rep ('#', string.len (et.size)) .. ']]'
string.rep("#", string.len(et.size)))
end
if zeta_switch then
end
if zeta_switch then
if #text > 0 then text = text .. '<br>' end
if not (type(zeta_override) == 'string' and #zeta_override > 0) then
text = text .. ET.why_zeta(et)
text = text .. ET.why_zeta(et)
else
text = text .. zeta_override
end
end
categories = categories .. '[[Category:Zeta|' .. string.rep ('#', string.len (et.size)) .. ']]'
end
if #text > 0 then
table.insert(infobox_data, {
"Special properties",
"<div style=\"max-width: 300px;\">" .. text .. "</div>",
})
end
end
table.insert(infobox_data, {
'Special properties',
'<div style="max-width: 270px;">' .. text .. '</div>'
})
end
end


result = infobox.build(
local result = infobox.build(string.format("[[%s|%s]]", et.suffix, tuning), infobox_data, prev_one, next_one)
'[[' .. et.suffix .. '|' .. tuning .. ']]',
infobox_data,
prev_one,
next_one
)
if not debug_mode then
if not debug_mode then
result = result .. categories
result = result .. categories
end
end
return result
if wtext then
result = "<syntaxhighlight lang=\"wikitext\">" .. result .. "</syntaxhighlight>"
end
return frame:preprocess(result)
end
end


return p
return p

Latest revision as of 15:14, 5 December 2025

Module documentation[view] [edit] [history] [purge]
This module should not be invoked directly; use its corresponding template instead: Template:Infobox ET.

This module automatically fills in information about a specified equal temperament tuning.

Introspection summary for Module:Infobox ET 
Functions provided (1)
Line Function Params
51 infobox_ET (invokable) (frame)
Lua modules required (7)
Variable Module Functions used
getArgs Module:Arguments getArgs
ET Module:ET approximate
cents
parse
is_highly_composite
is_zeta
why_zeta
infobox Module:Infobox build
limits Module:Limits consistency_limit
rat Module:Rational eq
new
converges
as_float
as_table
as_ratio
cents
utils Module:Utils _round
_prime_factorization
is_prime
yesno Module:Yesno yesno

No function descriptions were provided. The Lua code may have further information.


local p = {}

local ET = require("Module:ET")
local getArgs = require("Module:Arguments").getArgs
local infobox = require("Module:Infobox")
local limits = require("Module:Limits")
local rat = require("Module:Rational")
local utils = require("Module:Utils")
local yesno = require("Module:Yesno")

-- check whether the input is a non-empty string
local function value_provided(s)
	return type(s) == "string" and #s > 0
end

-- towards is one of: -1 (floor), 0 (nearest), 1 (ceil)
local function approximation(et, interval, towards, precomputed_approx)
	local approx = precomputed_approx or ET.approximate(et, interval, towards or 0)

	-- string for backslash notation
	-- "edo" is omitted
	local tuning = et.size
	if not rat.eq(et.equave, 2) then
		tuning = tuning .. et.suffix
	end

	local ratio = rat.new(approx, et.size)

	-- convergence notice, suppressed for 1ed's
	local convergement_notice = ""
	local converges = rat.converges(ratio, math.log(interval) / math.log(rat.as_float(et.equave)))
	if et.size > 1 and converges then
		convergement_notice = "<br>(" .. converges .. ")"
	end

	if rat.as_table(ratio)[1] ~= approx then
		convergement_notice = ""
		local link = rat.as_table(ratio)[2] .. et.suffix
		ratio = string.format(" (&rarr;&nbsp;[[%s|%s%s]])",
			link, rat.as_ratio(ratio, "\\"), (rat.eq(et.equave, 2) == false and et.suffix or ""))
	else
		ratio = ""
	end

	local cents = utils._round(ET.cents(et, approx), 6)

	return string.format("%s\\%s (%s{{c}})%s%s",
		approx, tuning, utils._round(ET.cents(et, approx), 6), ratio, convergement_notice)
end

function p.infobox_ET(frame)
	local args = getArgs(frame)
	
	-- debug mode will disable the categories
	local debug_mode = yesno(frame.args["debug"] or args["debug"], false)
	local wtext = yesno(frame.args["wtext"] or args["wtext"])

	local tuning = frame.args["tuning"]
	local et = ET.parse(tuning) or ET.parse(tuning .. "edo") or ET.parse("12edo")

	-- category of the main article
	local categories = string.format(" {{#ifexist: Category:%s|[[Category:%s| ]]|}}", tuning, tuning)
	-- category of the equal division
	if rat.eq(et.equave, 2) then
		categories = categories
			.. string.format(" [[Category:Equal divisions of the octave|%s]]",
				string.rep("#", string.len(et.size)))
	elseif rat.eq(et.equave, 3) then
		categories = categories .. string.format(" [[Category:Edts|%s]]",
			string.rep("#", string.len(et.size)))
	elseif rat.eq(et.equave, rat.new (3, 2)) then
		categories = categories .. string.format(" [[Category:Edfs|%s]]",
			string.rep("#", string.len(et.size)))
	else
		categories = categories .. string.format(" [[Category:%s's|%s]]",
			et.suffix, string.rep("#", string.len(et.size)))
	end

	-- prime factorization
	local prime_factorization_override = frame.args["Prime factorization"]
	local prime_factorization
	if not value_provided(prime_factorization_override) then
		prime_factorization = utils._prime_factorization(et.size)
		if utils.is_prime(et.size) then
			prime_factorization = prime_factorization .. " (prime)"
			if rat.eq(et.equave, 2) then
				categories = categories 
					.. string.format(" [[Category:Prime EDOs|%s]]",
						string.rep("#", string.len(et.size)))
			end
		end
		if ET.is_highly_composite(et) and et.size > 1 then
			prime_factorization = prime_factorization .. " (highly composite)"
			if rat.eq(et.equave, 2) then
				categories = categories 
					.. string.format(" [[Category:Highly composite EDOs|%s]]",
						string.rep("#", string.len(et.size)))
			end
		end
	else
		prime_factorization = prime_factorization_override
	end

	-- zeta test
	local zeta_override = frame.args["Zeta"]
	local zeta_switch
	if value_provided(zeta_override) then
		zeta_switch = zeta_override:match("^[Yy][Ee][Ss]$") and ET.is_zeta(et)
	else
		zeta_switch = false
	end

	-- navigation arrows
	local increment = 1
	if rat.eq(et.equave, rat.new(9, 4)) or rat.eq(et.equave, 4) or rat.eq(et.equave, 9) then
		increment = 2
	end
	local prev_one = ""
	if et.size >= increment then
		prev_one = string.format("[[%s|&larr;&nbsp;%s]]",
			(et.size - increment) .. et.suffix, (et.size - increment) .. et.suffix)
	end
	local next_one = string.format("[[%s|%s&nbsp;&rarr;]]",
		(et.size + increment) .. et.suffix, (et.size + increment) .. et.suffix)

	-- step size in cents
	local step_size = ET.cents(et, 1)
	if step_size > 100 then
		categories = categories .. string.format(" [[Category:Macrotonal|%s]]",
			string.rep("#", string.len(et.size)))
	end
	local note_12edo = ""
	if rat.eq(et.equave, 2) and et.size == 12 then
		note_12edo = " (by&nbsp;definition)"
	end

	-- octave, twelfth, and fifth in steps
	local octave = ET.approximate(et, 2)
	local twelfth = ET.approximate(et, 3)

	local fifth = -octave + twelfth -- 3/2 = [-1 1>
	local fifth_error = ET.cents(et, fifth) - rat.cents(rat.new(3, 2))
	local is_dual_fifth = math.abs(fifth_error) > step_size / 3

	local A1 = -11 * octave + 7 * twelfth -- 2187/2048 = [-11 7>
	local m2 = 8 * octave - 5 * twelfth -- 256/243 = [8 -5>
	local A1_cents = utils._round(ET.cents(et, A1), 4)
	local m2_cents = utils._round(ET.cents(et, m2), 4)

	-- display
	local infobox_data = {}

	table.insert(infobox_data, {
		"Prime factorization",
		prime_factorization,
	})

	table.insert(infobox_data, {
		"Step size",
		string.format("%s{{c}}%s&nbsp;",
			utils._round(step_size, 6), note_12edo)
	})

	if not rat.eq(et.equave, 2) then
		table.insert(infobox_data, {
			"Octave",
			approximation(et, 2),
		})
		if not rat.eq(et.equave, 3) then
			table.insert(infobox_data, {
				"Twelfth",
				approximation(et, 3),
			})
		end
	else
		table.insert(infobox_data, {
			"Fifth",
			approximation(et, 3 / 2),
		})
		table.insert(infobox_data, {
			"Semitones (A1:m2)",
			string.format("%s:%s (%s{{c}}&nbsp;:&nbsp;%s{{c}})",
				A1, m2, A1_cents, m2_cents)
		})
		if is_dual_fifth and et.size > 0 then
			table.insert(infobox_data, {
				"Dual sharp fifth",
				approximation(et, 3 / 2, 1),
			})
			table.insert(infobox_data, {
				"Dual flat fifth",
				approximation(et, 3 / 2, -1),
			})
			local sharp = ET.approximate(et, 3 / 2, 1)
			local flat = ET.approximate(et, 3 / 2, -1)
			table.insert(infobox_data, {
				"Dual major 2nd",
				approximation(et, 9 / 8, 0, sharp + flat - octave),
			})
			categories = categories
				.. string.format(" [[Category:Dual-fifth temperaments|%s]]",
					string.rep("#", string.len(et.size)))
		end
	end

	-- consistency and distinct consistency
	-- max_limit is used to prevent timeout
	local consistency = tonumber(frame.args["Consistency"])
	local max_limit = rat.eq(et.equave, 2) and 43 or 32
	if consistency == nil then
		consistency = limits.consistency_limit(et, false, max_limit)
	end
	if consistency == nil then
		consistency = "at least " .. max_limit
	end
	if consistency ~= nil then
		table.insert(infobox_data, {
			"Consistency limit",
			consistency,
		})
	end
	local distinct_consistency = tonumber(frame.args["Distinct consistency"])
	if distinct_consistency == nil then
		distinct_consistency = limits.consistency_limit(et, consistency or true, max_limit)
	end
	if distinct_consistency == nil then
		distinct_consistency = "at least " .. max_limit
	end
	if distinct_consistency ~= nil then
		table.insert(infobox_data, {
			"Distinct consistency limit",
			distinct_consistency,
		})
	end

	-- special properties
	if ET.is_zeta(et) then
		local text = ""
		if rat.eq(et.equave, 2) then
			categories = categories
				.. string.format(" [[Category:Zeta record EDOs|%s]]",
					string.rep("#", string.len(et.size)))
			if zeta_switch then
				text = text .. ET.why_zeta(et)
			end
		end	
		if #text > 0 then
			table.insert(infobox_data, {
				"Special properties",
				"<div style=\"max-width: 300px;\">" .. text .. "</div>",
			})
		end
	end

	local result = infobox.build(string.format("[[%s|%s]]", et.suffix, tuning), infobox_data, prev_one, next_one)
	
	if not debug_mode then
		result = result .. categories
	end
	
	if wtext then
		result = "<syntaxhighlight lang=\"wikitext\">" .. result .. "</syntaxhighlight>"
	end
	
	return frame:preprocess(result)
end

return p