Module:ED intro: Difference between revisions

From Xenharmonic Wiki
Jump to navigation Jump to search
Ganaram inukshuk (talk | contribs)
m parentheses
Ganaram inukshuk (talk | contribs)
Added back edc (equal divisions of cent value)
Line 30: Line 30:
local intro_text = ""
local intro_text = ""
if ed == 1 then
if ed == 1 then
intro_text = "'''1 equal division of the octave''' (abbreviated '''1edo''' or '''1ed2'''), also called '''1-tone equal temperament''' ('''1tet''') or '''1 equal temperament''' ('''1et''') when viewed under a [[regular temperament]] perspective, is the [[tuning system]] where adjacent pitches are one interval of 2/1 (one [[octave]]) apart, or exactly/about ''s'' [[¢]]."
intro_text = "'''1 equal division of the octave''' (abbreviated '''1edo''' or '''1ed2'''), also called '''1-tone equal temperament''' ('''1tet''') or '''1 equal temperament''' ('''1et''') when viewed under a [[regular temperament]] perspective, is the [[tuning system]] that uses equal steps of 2/1 (one [[octave]]), or exactly/about ''s'' [[¢]]."
else
else
intro_text = "'''''k'' equal divisions of the octave''' (abbreviated '''''k''edo''' or '''''k''ed2'''), also called '''''k''-tone equal temperament''' ('''''k''tet''') or '''''k'' equal temperament''' ('''''k''et''') when viewed under a [[regular temperament]] perspective, is the [[tuning system]] that divides the [[octave]] into ''k'' [[equal]] parts of exactly/about ''s'' [[¢]] each. Each step represents a [[frequency ratio]] of 2<sup>1/''k''</sup>, or the ''kth'' root of 2."
intro_text = "'''''k'' equal divisions of the octave''' (abbreviated '''''k''edo''' or '''''k''ed2'''), also called '''''k''-tone equal temperament''' ('''''k''tet''') or '''''k'' equal temperament''' ('''''k''et''') when viewed under a [[regular temperament]] perspective, is the [[tuning system]] that divides the [[octave]] into ''k'' [[equal]] parts of exactly/about ''s'' [[¢]] each. Each step represents a [[frequency ratio]] of 2<sup>1/''k''</sup>, or the ''kth'' root of 2."
Line 57: Line 57:
local intro_text = ""
local intro_text = ""
if ed == 1 then
if ed == 1 then
intro_text = "'''1 equal division of the tritave''', '''perfect twelfth''', or '''3rd harmonic''' (abbreviated '''1edt''' or '''1ed3'''), is the [[nonoctave]] [[tuning system]] where adjacent pitches are one interval of 3/1 (one [[tritave]]) apart, or exactly/about ''s'' [[¢]]."
intro_text = "'''1 equal division of the tritave''', '''perfect twelfth''', or '''3rd harmonic''' (abbreviated '''1edt''' or '''1ed3'''), is a [[nonoctave]] [[tuning system]] that uses equal steps of 3/1 (one [[tritave]]), or exactly/about ''s'' [[¢]]."
else
else
intro_text = "'''''k'' equal divisions of the tritave''', '''perfect twelfth''', or '''3rd harmonic''' (abbreviated '''''k''edt''' or '''''k''ed3'''), is the [[nonoctave]] [[tuning system]] that divides the interval of [[3/1]] into ''k'' [[equal]] parts of exactly/about ''s'' [[¢]] each. Each step represents a [[frequency ratio]] of 3<sup>1/''k''</sup>, or the ''kth'' root of 3."
intro_text = "'''''k'' equal divisions of the tritave''', '''perfect twelfth''', or '''3rd harmonic''' (abbreviated '''''k''edt''' or '''''k''ed3'''), is a [[nonoctave]] [[tuning system]] that divides the interval of [[3/1]] into ''k'' [[equal]] parts of exactly/about ''s'' [[¢]] each. Each step represents a [[frequency ratio]] of 3<sup>1/''k''</sup>, or the ''kth'' root of 3."
end
end


Line 84: Line 84:
local intro_text = ""
local intro_text = ""
if ed == 1 then
if ed == 1 then
intro_text = "'''1 equal division of the perfect fifth''' (abbreviated '''1edf''' or '''1ed3/2''') is the [[nonoctave]] [[tuning system]] where adjacent pitches are one interval of 3/2 (one perfect fifth) apart, or exactly/about ''s'' [[¢]]."
intro_text = "'''1 equal division of the perfect fifth''' (abbreviated '''1edf''' or '''1ed3/2''') is a [[nonoctave]] [[tuning system]] that uses equal steps of 3/2 (one perfect fifth), or exactly/about ''s'' [[¢]]."
else
else
intro_text = "'''''k'' equal divisions of the perfect fifth''' (abbreviated '''''k''edf''' or '''''k''ed3/2''') is the [[nonoctave]] [[tuning system]] that divides the interval of [[3/2]] into ''k'' [[equal]] parts of exactly/about ''s'' [[¢]] each. Each step represents a [[frequency ratio]] of (3/2)<sup>1/''k''</sup>, or the ''kth'' root of 3/2."
intro_text = "'''''k'' equal divisions of the perfect fifth''' (abbreviated '''''k''edf''' or '''''k''ed3/2''') is a [[nonoctave]] [[tuning system]] that divides the interval of [[3/2]] into ''k'' [[equal]] parts of exactly/about ''s'' [[¢]] each. Each step represents a [[frequency ratio]] of (3/2)<sup>1/''k''</sup>, or the ''kth'' root of 3/2."
end
end


Line 112: Line 112:
local intro_text = ""
local intro_text = ""
if ed == 1 then
if ed == 1 then
intro_text = "'''1 equal division of the hth harmonic''' (abbreviated '''1ed''h''''') is the [[nonoctave]] [[tuning system]] where adjacent pitches are one interval of [[''h''/1]] apart, or exactly/about ''s'' [[¢]]."
intro_text = "'''1 equal division of the hth harmonic''' (abbreviated '''1ed''h''''') is a [[nonoctave]] [[tuning system]] that uses equal steps of [[''h''/1]], or exactly/about ''s'' [[¢]]."
else
else
intro_text = "'''''k'' equal divisions of the hth harmonic''' (abbreviated '''''k''ed''h''''') is the [[nonoctave]] [[tuning system]] that divides the interval of [[''h''/1]] into ''k'' [[equal]] parts of exactly/about ''s'' [[¢]] each. Each step represents a [[frequency ratio]] of ''h''<sup>1/''k''</sup>, or the ''kth'' root of ''h''."
intro_text = "'''''k'' equal divisions of the hth harmonic''' (abbreviated '''''k''ed''h''''') is a [[nonoctave]] [[tuning system]] that divides the interval of [[''h''/1]] into ''k'' [[equal]] parts of exactly/about ''s'' [[¢]] each. Each step represents a [[frequency ratio]] of ''h''<sup>1/''k''</sup>, or the ''kth'' root of ''h''."
end
end


Line 142: Line 142:
local intro_text = ""
local intro_text = ""
if ed == 1 then
if ed == 1 then
intro_text = "'''1 equal division of ''p/q''''' (abbreviated '''1ed''p/q''''') is the [[nonoctave]] [[tuning system]] where adjacent pitches are one interval of [[''p/q'']] apart, or exactly/about ''s'' [[¢]]."
intro_text = "'''1 equal division of ''p/q''''' (abbreviated '''1ed''p/q''''') is a [[nonoctave]] [[tuning system]] that uses equal steps of [[''p/q'']], or exactly/about ''s'' [[¢]]."
else
else
intro_text = "'''''k'' equal divisions of ''p/q''''' (abbreviated '''''k''ed''p/q''''') is the [[nonoctave]] [[tuning system]] that divides the interval of [[''p/q'']] into ''k'' [[equal]] parts of exactly/about ''s'' [[¢]] each. Each step represents a [[frequency ratio]] of (''p/q'')<sup>1/''k''</sup>, or the ''kth'' root of ''p/q''."
intro_text = "'''''k'' equal divisions of ''p/q''''' (abbreviated '''''k''ed''p/q''''') is a [[nonoctave]] [[tuning system]] that divides the interval of [[''p/q'']] into ''k'' [[equal]] parts of exactly/about ''s'' [[¢]] each. Each step represents a [[frequency ratio]] of (''p/q'')<sup>1/''k''</sup>, or the ''kth'' root of ''p/q''."
end
end


Line 157: Line 157:
end
end


function p.edc_intro(ed, cents, constant_symbol)
-- Separate function for edc (arbitrary cent value)
return "Equal divisions of an arbitrary cent value currently not supported."
function p.edcent_intro(ed, cents)
local ed = ed or 1
local cents = cents or 97.5
-- Exactly or about? Round to 3 DPs
local edstep_size = cents / ed
local edstep_size_rounded = utils._round(edstep_size, 3)
local is_exact = edstep_size - edstep_size_rounded == 0
local ordinal = ord._ordinal(ed)
local intro_text = ""
if ed == 1 then
intro_text = "'''1 equal division of ''c''¢''' (abbreviated '''1ed''c''¢''') is a [[nonoctave]] [[tuning system]] that uses equal steps of ''c'' [[¢]]."
else
intro_text = "'''''k'' equal divisions of ''c''¢''' (abbreviated '''''k''ed''c''¢''') is a [[nonoctave]] [[tuning system]] that divides the interval of ''c''¢ into ''k'' [[equal]] parts of exactly/about ''s'' [[¢]] each."
end
 
-- Replace certain strings with the intended final versions
intro_text = string.gsub(intro_text, "''k''", ed)
intro_text = string.gsub(intro_text, "exactly/about", (is_exact and "exactly" or "about"))
intro_text = string.gsub(intro_text, "''s''", string.format("%.3f", edstep_size))
intro_text = string.gsub(intro_text, "''c''", cents)
return intro_text
end
end


Line 173: Line 197:
local steps, equave = unparsed:match('^(%d+)[Ee][Dd](.+)$')
local steps, equave = unparsed:match('^(%d+)[Ee][Dd](.+)$')
-- Determine if the ed is for a cent value
local is_cents = string.match(equave, '%d*%.?%d+[Cc¢]$') ~= nil
-- Parse equave
local parsed_equave
local parsed_equave
if equave == "o" or equave == "O" or equave == "2" or equave == "2/1" then
if equave == "o" or equave == "O" or equave == "2" or equave == "2/1" then
Line 190: Line 218:
local num, den = equave:match('^(%d+)/(%d+)$')
local num, den = equave:match('^(%d+)/(%d+)$')
parsed_equave = rat.new(tonumber(num), tonumber(den))
parsed_equave = rat.new(tonumber(num), tonumber(den))
elseif is_cents then
-- Equave is arbitrary cent value
parsed_equave = tonumber(equave:match('^(%d*%.?%d+)[Cc¢]$'))
else
else
-- Equave is unsupported
-- Equave is unsupported
Line 195: Line 226:
end
end
return tonumber(steps), parsed_equave
return tonumber(steps), parsed_equave, is_cents
end
end


-- Primary function
-- Primary function
function p._ed_intro(ed)
function p._ed_intro(ed)
local ed = ed or "12ed4/3"
local ed = ed or "12"
local parsed_ed, parsed_equave = p.parse(ed)
local parsed_ed, parsed_equave, is_cent_value = p.parse(ed)
if rat.eq(0, parsed_equave) then
if rat.eq(0, parsed_equave) then
Line 212: Line 243:
elseif rat.eq(rat.new(3,2), parsed_equave) then
elseif rat.eq(rat.new(3,2), parsed_equave) then
return p.edf_intro(parsed_ed)
return p.edf_intro(parsed_ed)
elseif rat.is_harmonic(parsed_equave) then
elseif rat.is_harmonic(parsed_equave) and not is_cent_value then
return p.edh_intro(parsed_ed, parsed_equave)
return p.edh_intro(parsed_ed, parsed_equave)
elseif not rat.is_harmonic(parsed_equave) then
elseif not rat.is_harmonic(parsed_equave) then
return p.edr_intro(parsed_ed, parsed_equave)
return p.edr_intro(parsed_ed, parsed_equave)
elseif is_cent_value then
return p.edcent_intro(parsed_ed, parsed_equave)
else
else
return "Invalid input."
return "Invalid input."

Revision as of 09:38, 3 April 2024

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

This module automatically fills in an introduction for an equal-step tuning. It has presets for the most common equivalences (octave, tritave, and perfect fifth) and also supports arbitrary equivalences and arithmetic pitch sequences such as 88cET.

Introspection summary for Module:ED intro 
Functions provided (9)
Line Function Params
20 edo_intro (ed)
47 edt_intro (ed)
74 edf_intro (ed)
101 edh_intro (ed, harmonic)
131 edr_intro (ed, ratio)
160 edcent_intro (ed, cents)
188 parse (unparsed)
232 _ed_intro (main) (ed)
257 ed_intro (invokable) (frame)
Lua modules required (3)
Variable Module Functions used
ord Module:Ordinal _ordinal
rat Module:Rational new
cents
as_ratio
eq
is_harmonic
utils Module:Utils _round

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


local ord = require('Module:Ordinal')
local utils = require('Module:Utils')
local rat = require('Module:Rational')
local p = {}

-- TODO: Add support for the following
-- - edc - equal divisions of a non-integer constant or cent value

-- Notes:
-- - Edo and edt are technically edh's, and edf an edr; these are their own
--   types because their intros have specific wording.
-- - Edh is a special case of edr, where the ratio is h/1.
-- - Under harmonotonic tuning, edc and edr are also called ASp and APSp
--   (ambitonal sequence and arithmetic pitch sequence, respectively). These
--   were formerly called equal-step tunings but were reclassified as 1ed.
-- - Equal divisions of irrational constants (such as pi and e) are not very
--   common, but count as equal divisions of arbitrary cent values.

-- Separate function for edo intro
function p.edo_intro(ed)
	local ed = ed or 12
	
	-- Exactly or about? Round to 3 DPs
	local edstep_size = 1200 / ed
	local edstep_size_rounded = utils._round(edstep_size, 3)
	local is_exact = edstep_size - edstep_size_rounded == 0
	
	local ordinal = ord._ordinal(ed)
	
	local intro_text = ""
	if ed == 1 then
		intro_text = "'''1 equal division of the octave''' (abbreviated '''1edo''' or '''1ed2'''), also called '''1-tone equal temperament''' ('''1tet''') or '''1 equal temperament''' ('''1et''') when viewed under a [[regular temperament]] perspective, is the [[tuning system]] that uses equal steps of 2/1 (one [[octave]]), or exactly/about ''s'' [[¢]]."	
	else
		intro_text = "'''''k'' equal divisions of the octave''' (abbreviated '''''k''edo''' or '''''k''ed2'''), also called '''''k''-tone equal temperament''' ('''''k''tet''') or '''''k'' equal temperament''' ('''''k''et''') when viewed under a [[regular temperament]] perspective, is the [[tuning system]] that divides the [[octave]] into ''k'' [[equal]] parts of exactly/about ''s'' [[¢]] each. Each step represents a [[frequency ratio]] of 2<sup>1/''k''</sup>, or the ''kth'' root of 2."	
	end

	-- Replace certain strings with the intended final versions
	intro_text = string.gsub(intro_text, "''k''", ed)
	intro_text = string.gsub(intro_text, "exactly/about", (is_exact and "exactly" or "about"))
	intro_text = string.gsub(intro_text, "''s''", string.format("%.3f", edstep_size))
	intro_text = string.gsub(intro_text, "''kth''", ord._ordinal(ed))
	
	return intro_text
end

-- Separate function for edt intro
function p.edt_intro(ed)
	local ed = ed or 13
	
	-- Exactly or about? Round to 3 DPs
	local edstep_size = math.log(3) * 1200 / math.log(2) / ed
	local edstep_size_rounded = utils._round(edstep_size, 3)
	local is_exact = edstep_size - edstep_size_rounded == 0
	
	local ordinal = ord._ordinal(ed)
	
	local intro_text = ""
	if ed == 1 then
		intro_text = "'''1 equal division of the tritave''', '''perfect twelfth''', or '''3rd harmonic''' (abbreviated '''1edt''' or '''1ed3'''), is a [[nonoctave]] [[tuning system]] that uses equal steps of 3/1 (one [[tritave]]), or exactly/about ''s'' [[¢]]."	
	else
		intro_text = "'''''k'' equal divisions of the tritave''', '''perfect twelfth''', or '''3rd harmonic''' (abbreviated '''''k''edt''' or '''''k''ed3'''), is a [[nonoctave]] [[tuning system]] that divides the interval of [[3/1]] into ''k'' [[equal]] parts of exactly/about ''s'' [[¢]] each. Each step represents a [[frequency ratio]] of 3<sup>1/''k''</sup>, or the ''kth'' root of 3."	
	end

	-- Replace certain strings with the intended final versions
	intro_text = string.gsub(intro_text, "''k''", ed)
	intro_text = string.gsub(intro_text, "exactly/about", (is_exact and "exactly" or "about"))
	intro_text = string.gsub(intro_text, "''s''", string.format("%.3f", edstep_size))
	intro_text = string.gsub(intro_text, "''kth''", ord._ordinal(ed))
	
	return intro_text
end

-- Separate function for edf intro
function p.edf_intro(ed)
	local ed = ed or 7
	
	-- Exactly or about? Round to 3 DPs
	local edstep_size = math.log(3/2) * 1200 / math.log(2) / ed
	local edstep_size_rounded = utils._round(edstep_size, 3)
	local is_exact = edstep_size - edstep_size_rounded == 0
	
	local ordinal = ord._ordinal(ed)
	
	local intro_text = ""
	if ed == 1 then
		intro_text = "'''1 equal division of the perfect fifth''' (abbreviated '''1edf''' or '''1ed3/2''') is a [[nonoctave]] [[tuning system]] that uses equal steps of 3/2 (one perfect fifth), or exactly/about ''s'' [[¢]]."	
	else
		intro_text = "'''''k'' equal divisions of the perfect fifth''' (abbreviated '''''k''edf''' or '''''k''ed3/2''') is a [[nonoctave]] [[tuning system]] that divides the interval of [[3/2]] into ''k'' [[equal]] parts of exactly/about ''s'' [[¢]] each. Each step represents a [[frequency ratio]] of (3/2)<sup>1/''k''</sup>, or the ''kth'' root of 3/2."	
	end

	-- Replace certain strings with the intended final versions
	intro_text = string.gsub(intro_text, "''k''", ed)
	intro_text = string.gsub(intro_text, "exactly/about", (is_exact and "exactly" or "about"))
	intro_text = string.gsub(intro_text, "''s''", string.format("%.3f", edstep_size))
	intro_text = string.gsub(intro_text, "''kth''", ord._ordinal(ed))
	
	return intro_text
end

-- Separate function for edh intro (arbitrary harmonic)
function p.edh_intro(ed, harmonic)
	local ed = ed or 12
	local harmonic = harmonic or 4
	
	-- Exactly or about? Round to 3 DPs
	local edstep_size = math.log(harmonic) * 1200 / math.log(2) / ed
	local edstep_size_rounded = utils._round(edstep_size, 3)
	local is_exact = edstep_size - edstep_size_rounded == 0
	
	local ordinal = ord._ordinal(ed)
	
	local intro_text = ""
	if ed == 1 then
		intro_text = "'''1 equal division of the hth harmonic''' (abbreviated '''1ed''h''''') is a [[nonoctave]] [[tuning system]] that uses equal steps of [[''h''/1]], or exactly/about ''s'' [[¢]]."	
	else
		intro_text = "'''''k'' equal divisions of the hth harmonic''' (abbreviated '''''k''ed''h''''') is a [[nonoctave]] [[tuning system]] that divides the interval of [[''h''/1]] into ''k'' [[equal]] parts of exactly/about ''s'' [[¢]] each. Each step represents a [[frequency ratio]] of ''h''<sup>1/''k''</sup>, or the ''kth'' root of ''h''."	
	end

	-- Replace certain strings with the intended final versions
	intro_text = string.gsub(intro_text, "''k''", ed)
	intro_text = string.gsub(intro_text, "exactly/about", (is_exact and "exactly" or "about"))
	intro_text = string.gsub(intro_text, "''s''", string.format("%.3f", edstep_size))
	intro_text = string.gsub(intro_text, "''kth''", ord._ordinal(ed))
	intro_text = string.gsub(intro_text, "hth", ord._ordinal(harmonic))
	intro_text = string.gsub(intro_text, "''h''", harmonic)
	
	return intro_text
end

-- Separate function for edr intro (arbitrary ratio)
function p.edr_intro(ed, ratio)
	local ed = ed or 12
	local ratio = ratio or rat.new(9,4)
	
	-- Exactly or about? Round to 3 DPs
	local edstep_size = rat.cents(ratio) / ed
	local edstep_size_rounded = utils._round(edstep_size, 3)
	local is_exact = edstep_size - edstep_size_rounded == 0
	
	local ordinal = ord._ordinal(ed)
	
	local intro_text = ""
	if ed == 1 then
		intro_text = "'''1 equal division of ''p/q''''' (abbreviated '''1ed''p/q''''') is a [[nonoctave]] [[tuning system]] that uses equal steps of [[''p/q'']], or exactly/about ''s'' [[¢]]."	
	else
		intro_text = "'''''k'' equal divisions of ''p/q''''' (abbreviated '''''k''ed''p/q''''') is a [[nonoctave]] [[tuning system]] that divides the interval of [[''p/q'']] into ''k'' [[equal]] parts of exactly/about ''s'' [[¢]] each. Each step represents a [[frequency ratio]] of (''p/q'')<sup>1/''k''</sup>, or the ''kth'' root of ''p/q''."	
	end

	-- Replace certain strings with the intended final versions
	intro_text = string.gsub(intro_text, "''k''", ed)
	intro_text = string.gsub(intro_text, "exactly/about", (is_exact and "exactly" or "about"))
	intro_text = string.gsub(intro_text, "''s''", string.format("%.3f", edstep_size))
	intro_text = string.gsub(intro_text, "''kth''", ord._ordinal(ed))
	intro_text = string.gsub(intro_text, "''p/q''", rat.as_ratio(ratio))
	
	return intro_text
end

-- Separate function for edc (arbitrary cent value)
function p.edcent_intro(ed, cents)
	local ed = ed or 1
	local cents = cents or 97.5
	
	-- Exactly or about? Round to 3 DPs
	local edstep_size = cents / ed
	local edstep_size_rounded = utils._round(edstep_size, 3)
	local is_exact = edstep_size - edstep_size_rounded == 0
	
	local ordinal = ord._ordinal(ed)
	
	local intro_text = ""
	if ed == 1 then
		intro_text = "'''1 equal division of ''c''¢''' (abbreviated '''1ed''c''¢''') is a [[nonoctave]] [[tuning system]] that uses equal steps of ''c'' [[¢]]."	
	else
		intro_text = "'''''k'' equal divisions of ''c''¢''' (abbreviated '''''k''ed''c''¢''') is a [[nonoctave]] [[tuning system]] that divides the interval of ''c''¢ into ''k'' [[equal]] parts of exactly/about ''s'' [[¢]] each."	
	end

	-- Replace certain strings with the intended final versions
	intro_text = string.gsub(intro_text, "''k''", ed)
	intro_text = string.gsub(intro_text, "exactly/about", (is_exact and "exactly" or "about"))
	intro_text = string.gsub(intro_text, "''s''", string.format("%.3f", edstep_size))
	intro_text = string.gsub(intro_text, "''c''", cents)
	
	return intro_text
end

-- Parse function
function p.parse(unparsed)
	local unparsed = unparsed or "12"
	
	-- If the unparsed ed is only a numeric value, default to edo
	if tonumber(unparsed) ~= nil then
		unparsed = unparsed .. "edo"
	end
	
	-- Parse the step count, the suffix, and the equave
	local steps, equave = unparsed:match('^(%d+)[Ee][Dd](.+)$')
	
	-- Determine if the ed is for a cent value
	local is_cents = string.match(equave, '%d*%.?%d+[Cc¢]$') ~= nil
	
	-- Parse equave
	local parsed_equave
	if equave == "o" or equave == "O" or equave == "2" or equave == "2/1" then
		-- Equave is octave
		parsed_equave = 2
	elseif equave == "t" or equave == "T" or equave == "3" or equave == "3/1" then
		-- Equave is tritave/twelfth
		parsed_equave = 3
	elseif equave == "f" or equave == "F" or equave == "3/2" then
		-- Equave is fifth
		parsed_equave = rat.new(3,2)
	elseif string.match(equave, '^%d+$') ~= nil then
		-- Equave is arbitrary harmonic (not 2/1 or 3/1)
		parsed_equave = tonumber(equave)
	elseif string.match(equave, '^%d+/%d+$') ~= nil then
		-- Equave is arbitrary ratio (not 3/2)
		local num, den = equave:match('^(%d+)/(%d+)$')
		parsed_equave = rat.new(tonumber(num), tonumber(den))
	elseif is_cents then
		-- Equave is arbitrary cent value
		parsed_equave = tonumber(equave:match('^(%d*%.?%d+)[Cc¢]$'))
	else
		-- Equave is unsupported
		parsed_equave = 0
	end
	
	return tonumber(steps), parsed_equave, is_cents
end

-- Primary function
function p._ed_intro(ed)
	local ed = ed or "12"
	
	local parsed_ed, parsed_equave, is_cent_value = p.parse(ed)
	
	if rat.eq(0, parsed_equave) then
		return "Equave not supported."
	elseif rat.eq(2, parsed_equave) then
		return p.edo_intro(parsed_ed)
	elseif rat.eq(3, parsed_equave) then
		return p.edt_intro(parsed_ed)
	elseif rat.eq(rat.new(3,2), parsed_equave) then
		return p.edf_intro(parsed_ed)
	elseif rat.is_harmonic(parsed_equave) and not is_cent_value then
		return p.edh_intro(parsed_ed, parsed_equave)
	elseif not rat.is_harmonic(parsed_equave) then
		return p.edr_intro(parsed_ed, parsed_equave)
	elseif is_cent_value then
		return p.edcent_intro(parsed_ed, parsed_equave)
	else
		return "Invalid input."
	end
end

-- Wrapper function; for use with a template
function p.ed_intro(frame)
	local ed = frame.args['ED']

	return p._ed_intro(ed)
end

return p