Module:Infobox ET: Difference between revisions
Jump to navigation
Jump to search
Undo revision 184876 by ArrowHead294 (talk). The debug mode is used in several places on the wiki where categories should be disabled Tag: Undo |
ArrowHead294 (talk | contribs) mNo edit summary |
||
| (19 intermediate revisions by 4 users not shown) | |||
| Line 1: | Line 1: | ||
local p = {} | local p = {} | ||
local ET = require("Module:ET") | local ET = require("Module:ET") | ||
local getArgs = require("Module:Arguments").getArgs | |||
local infobox = require("Module:Infobox") | 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") | local yesno = require("Module:Yesno") | ||
| Line 29: | Line 31: | ||
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 et.size > 1 and converges then | if et.size > 1 and converges then | ||
convergement_notice = "<br | convergement_notice = "<br>(" .. converges .. ")" | ||
end | end | ||
| Line 35: | Line 37: | ||
convergement_notice = "" | convergement_notice = "" | ||
local link = rat.as_table(ratio)[2] .. et.suffix | local link = rat.as_table(ratio)[2] .. et.suffix | ||
ratio = " (→ [[" | ratio = string.format(" (→ [[%s|%s%s]])", | ||
link, rat.as_ratio(ratio, "\\"), (rat.eq(et.equave, 2) == false and et.suffix or "")) | |||
else | else | ||
ratio = "" | ratio = "" | ||
| Line 46: | Line 45: | ||
local cents = utils._round(ET.cents(et, approx), 6) | local cents = utils._round(ET.cents(et, approx), 6) | ||
return | 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) | ||
local args = getArgs(frame) | |||
-- debug mode will disable the categories | -- debug mode will disable the categories | ||
local debug_mode = yesno(frame.args["debug"]) | local debug_mode = yesno(frame.args["debug"] or args["debug"], false) | ||
local | local wtext = yesno(frame.args["wtext"] or args["wtext"]) | ||
local tuning = frame.args["tuning"] | local tuning = frame.args["tuning"] | ||
local et = ET.parse(tuning) or ET.parse("12edo") | 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 = | 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 | categories = categories | ||
.. "[[Category:Equal divisions of the octave|" | .. 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:" | categories = categories .. string.format(" [[Category:%s's|%s]]", | ||
et.suffix, string.rep("#", string.len(et.size))) | |||
end | end | ||
| Line 77: | Line 85: | ||
prime_factorization = prime_factorization .. " (prime)" | prime_factorization = prime_factorization .. " (prime)" | ||
if rat.eq(et.equave, 2) then | if rat.eq(et.equave, 2) then | ||
categories = categories .. "[[Category:Prime EDOs|" | 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 | end | ||
| Line 88: | Line 106: | ||
local zeta_switch | local zeta_switch | ||
if value_provided(zeta_override) then | if value_provided(zeta_override) then | ||
zeta_switch = | zeta_switch = zeta_override:match("^[Yy][Ee][Ss]$") and ET.is_zeta(et) | ||
else | else | ||
zeta_switch = | zeta_switch = false | ||
end | end | ||
| Line 100: | Line 118: | ||
local prev_one = "" | local prev_one = "" | ||
if et.size >= increment then | if et.size >= increment then | ||
prev_one = "[[" | prev_one = string.format("[[%s|← %s]]", | ||
(et.size - increment) .. et.suffix, (et.size - increment) .. et.suffix) | |||
end | end | ||
local next_one = "[[" | local next_one = string.format("[[%s|%s →]]", | ||
(et.size + increment) .. et.suffix, (et.size + increment) .. et.suffix) | |||
-- step size in cents | -- step size in cents | ||
local step_size = ET.cents(et, 1) | local step_size = ET.cents(et, 1) | ||
if step_size > 100 then | if step_size > 100 then | ||
categories = categories .. "[[Category:Macrotonal|" | categories = categories .. string.format(" [[Category:Macrotonal|%s]]", | ||
string.rep("#", string.len(et.size))) | |||
end | end | ||
local note_12edo = "" | local note_12edo = "" | ||
| Line 137: | Line 158: | ||
table.insert(infobox_data, { | table.insert(infobox_data, { | ||
"Step size", | "Step size", | ||
string.format("%s{{c}}%s ", | |||
utils._round(step_size, 6), note_12edo) | |||
}) | }) | ||
| Line 158: | Line 180: | ||
table.insert(infobox_data, { | table.insert(infobox_data, { | ||
"Semitones (A1:m2)", | "Semitones (A1:m2)", | ||
string.format("%s:%s (%s{{c}} : %s{{c}})", | |||
A1, m2, A1_cents, m2_cents) | |||
}) | }) | ||
if is_dual_fifth and et.size > 0 then | if is_dual_fifth and et.size > 0 then | ||
| Line 176: | Line 199: | ||
}) | }) | ||
categories = categories | categories = categories | ||
.. "[[Category:Dual-fifth temperaments|" | .. string.format(" [[Category:Dual-fifth temperaments|%s]]", | ||
string.rep("#", string.len(et.size))) | |||
end | end | ||
end | end | ||
-- consistency and distinct consistency | |||
-- max_limit is used to prevent timeout | |||
local consistency = tonumber(frame.args["Consistency"]) | 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 = limits.consistency_limit(et, false, | consistency = limits.consistency_limit(et, false, max_limit) | ||
end | end | ||
if consistency == nil then | if consistency == nil then | ||
consistency = "at least | consistency = "at least " .. max_limit | ||
end | end | ||
if consistency ~= nil then | if consistency ~= nil then | ||
| Line 197: | Line 222: | ||
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 = limits.consistency_limit(et, consistency or true, | 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 | distinct_consistency = "at least " .. max_limit | ||
end | end | ||
if distinct_consistency ~= nil then | if distinct_consistency ~= nil then | ||
| Line 210: | Line 235: | ||
-- special properties | -- special properties | ||
if ET. | if ET.is_zeta(et) then | ||
local text = "" | 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) | text = text .. ET.why_zeta(et) | ||
end | end | ||
end | |||
if #text > 0 then | |||
table.insert(infobox_data, { | |||
"Special properties", | |||
"<div style=\"max-width: 300px;\">" .. text .. "</div>", | |||
}) | |||
end | end | ||
end | end | ||
local result = infobox.build("[[" | local result = infobox.build(string.format("[[%s|%s]]", et.suffix, tuning), infobox_data, prev_one, next_one) | ||
if not | if not debug_mode then | ||
result = result .. categories | result = result .. categories | ||
end | |||
if wtext then | |||
result = "<syntaxhighlight lang=\"wikitext\">" .. result .. "</syntaxhighlight>" | |||
end | end | ||
Latest revision as of 15:14, 5 December 2025
- 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 | |||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
| ||||||||||||||||||||||||||||||
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(" (→ [[%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|← %s]]",
(et.size - increment) .. et.suffix, (et.size - increment) .. et.suffix)
end
local next_one = string.format("[[%s|%s →]]",
(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 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 ",
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}} : %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