Module:ED intro: Difference between revisions

From Xenharmonic Wiki
Jump to navigation Jump to search
Ganaram inukshuk (talk | contribs)
Work-in-progress
 
Ganaram inukshuk (talk | contribs)
Still work-in-progress; includes todo on what to bugfix
Line 1: Line 1:
local ord = require('Module:Ordinal')
local ord = require('Module:Ordinal')
local utils = require('Module:Utils')
local utils = require('Module:Utils')
local rat = require('Module:Rational')
local p = {}
local p = {}
-- TODO:
-- - Enforce ED types: edo, edt, edf, edh, edr, edc for octave, tritave/twelfth,
--  fifth, arbitrary harmonic h, arbitrary ratio r, and arbitrary cent value c.
--  Note that EDs of named constants, like pi, are currently not included, as
--  they probably need their own typing (ednc) separate from edc.
-- - Bugfix edr not reporting the correct equave


function p.parse_ed(unparsed)
function p.parse_ed(unparsed)
local unparsed = unparsed or "12edpi"
local unparsed = unparsed or "12edo"
-- If the unparsed ed is only a numeric value, default to edo
-- If the unparsed ed is only a numeric value, default to edo
Line 12: Line 20:
-- Parse
-- Parse
local steps, suffix, equave = unparsed:match('^(%d+)([Ee][Dd](.+))$')
local steps, equave = unparsed:match('^(%d+)[Ee][Dd](.+)$')
steps = tonumber(steps)
-- If the equave is text, then the equave is:
-- If the equave is text, then the equave is:
Line 18: Line 27:
-- t: tritave or twelfth, 3/1 (3rd harmonic)
-- t: tritave or twelfth, 3/1 (3rd harmonic)
-- f: fifth, 3/2
-- f: fifth, 3/2
-- For irrational/transcendental constants:
local ed_type = ""
-- pi or π: 3.141593
local ratio = "n/a"
-- phi or φ: 1.618034
local cents = 0
-- n (typically used for e): 2.718282
if equave == "o" or equave == "O" or equave == "2" then
if equave == "o" or equave == "O" then
equave = "2"
equave = "2"
elseif equave == "t" or equave == "T" then
ratio = "2/1"
cents = 1200
ed_type = "edo"
elseif equave == "t" or equave == "T" or equave == "3" then
equave = "3"
equave = "3"
elseif equave == "f" or equave == "F" then
ratio = "3/1"
cents = math.log(3) * 1200 / math.log(2)
ed_type = "edt"
elseif equave == "f" or equave == "F" or equave == "3/2" then
equave = "3/2"
equave = "3/2"
elseif equave == "pi" or equave == "π" then
ratio = "3/2"
equave = "" .. math.pi
cents = math.log(3/2) * 1200 / math.log(2)
elseif equave == "phi" or equave == "φ" then
ed_type = "edf"
equave = "1.6180339887499"
end
elseif equave == "n" or equave == "N" then
equave = "" .. math.exp(1)
-- For equaves not 2/1, 3/1, or 3/2
if ed_type == "" then
-- If the equave is a number or ratio, convert it to cents
-- If the equave is already a cent value, extract it
local is_cents = string.match(equave, '^(.+)c') ~= nil
local is_numeric = tonumber(equave) ~= nil
local is_ratio = string.match(equave, '^%d+/%d+$') ~= nil
if is_cents then
cents = tonumber(equave:match('^(.+)c'))
ed_type = "edc"
elseif is_numeric then
cents = math.log(tonumber(equave)) * 1200 / math.log(2)
-- Classify ed type as either ed of a constant (if not a whole number)
-- or ed of a harmonic (if it's a whole number); if it is a harmonic,
-- write it as a ratio (h/1)
if math.floor(tonumber(equave)) ~= tonumber(equave) then
ed_type = "edc"
else
ed_type = "edh"
ratio = equave .. "/1"
end
elseif is_ratio then
local ratio = rat.parse(equave)
cents = rat.cents(ratio)
equave = rat.as_ratio(ratio) -- Ensures ratio is simplified
ratio = equave
ed_type = "edr"
end
end
end


return { ['steps'] = steps, ['suffix'] = suffix, ['equave'] = equave }
return { ['cents'] = cents, ['equave'] = equave, ['steps'] = steps, ['ratio'] = ratio, ['type'] = ed_type }
end
end


function p.ed_intro(ed)
function p.ed_intro(ed)
 
local ed = ed or "12ed19/13"
local parsed_ed = p.parse_ed(ed)
local ed_type = parsed_ed['type']
-- Intro formats for each possible case
-- Intro formats for each possible case
-- - Common abbrevs: edo, edt, edf
-- - Common abbrevs: edo, edt, edf; these have specially written intros
-- - General harmonic: edh (h-th harmonic)
-- - General harmonic: edh (h-th harmonic)
-- - Arbitrary JI ratio: edp/q
-- - Arbitrary JI ratio: edr (ratio of p/q)
-- - Arbitrary constant: edc
-- - Arbitrary constant: edc
-- - Equal-step tunings: 1edo, 1edt, 1edf, 1edh, 1edp/q, 1edc
-- - Equal-step tunings: 1edo, 1edt, 1edf, 1edh, 1edp/q, 1edc
local intro_text = ""
local intro_text = ""
if is_est then
if is_est then
if is_edo then
if ed_type == "edo" 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 [[octave]], or exactly/about s [[¢]], from each other.\n"
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 [[octave]], or exactly/about ''s'' [[¢]], from each other."
elseif is_edt then
elseif ed_type == "edt" then
intro_text = "'''1 equal division of the tritave''' (abbreviated '''1edt''' or '''1ed3''') is the [[non-octave]] [[tuning system]] where adjacent pitches are one tritave ([[3/1]]), or exactly/about s [[¢]], apart from each other.\n"
intro_text = "'''1 equal division of the tritave''' (abbreviated '''1edt''' or '''1ed3''') is the [[non-octave]] [[tuning system]] where adjacent pitches are one tritave ([[3/1]]), or exactly/about ''s'' [[¢]], apart from each other."
elseif is_edf then
elseif ed_type == "edf" then
intro_text = "'''1 equal division of the fifth''' (abbreviated '''1edf''' or '''1ed3/2''') is the [[non-octave]] [[tuning system]] where adjacent pitches are one perfect fifth ([[3/2]]), or exactly/about s [[¢]], apart from each other.\n"
intro_text = "'''1 equal division of the fifth''' (abbreviated '''1edf''' or '''1ed3/2''') is the [[non-octave]] [[tuning system]] where adjacent pitches are one perfect fifth ([[3/2]]), or exactly/about ''s'' [[¢]], apart from each other."
elseif is_harmonic then
elseif ed_type == "edh" then
intro_text = "'''1 equal division of the ''h''th harmonic''' (abbreviated '''1ed''h''''') is the [[non-octave]] [[tuning system]] where adjacent pitches are one interval of [[''h''/1]], or exactly/about s [[¢]], apart from each other.\n"
intro_text = "'''1 equal division of the ''hth'' harmonic''' (abbreviated '''1ed''h''''') is the [[non-octave]] [[tuning system]] where adjacent pitches are one interval of [[''h''/1]], or exactly/about ''s'' [[¢]], apart from each other."
elseif is_edpq then
elseif ed_type == "edr" then
intro_text = "'''1 equal division of ''p''/''q''''' (abbreviated '''1ed''p''/''q''''') is the [[non-octave]] [[tuning system]] where adjacent pitches are one interval of [[''p''/''q'']], or exactly/about s [[¢]], apart from each other.\n"
intro_text = "'''1 equal division of ''p''/''q''''' (abbreviated '''1ed''p''/''q''''') is the [[non-octave]] [[tuning system]] where adjacent pitches are one interval of [[''p''/''q'']], or exactly/about ''s'' [[¢]], apart from each other."
elseif is_edc then
elseif ed_type == "edc" then
intro_text = "'''1 equal division of ''c''¢''' (abbreviated '''1ed''c''''') is the [[non-octave]] [[tuning system]] where adjacent pitches are s [[¢]], apart from each other.\n"
intro_text = "'''1 equal division of ''c''¢''' (abbreviated '''1ed''c''''') is the [[non-octave]] [[tuning system]] where adjacent pitches are ''s'' [[¢]], apart from each other."
end
end
else
else
if is_edo then
if ed_type == "edo" then
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 of ''k''edo represents a [[frequency ratio]] of 2<sup>1/''k''</sup>, or the ''k''th root of 2.\n"
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 of ''k''edo represents a [[frequency ratio]] of 2<sup>1/''k''</sup>, or the ''kth'' root of 2."
elseif is_edt then
elseif ed_type == "edt" then
intro_text = "'''''k'' equal divisions of the tritave''' (abbreviated '''''k''edt''' or '''''k''ed3''') is the [[non-octave]] [[tuning system]] that divides the interval [[3/1]] – also called the [[tritave]] or perfect twelfth – into ''k'' equal parts of exactly/about s [[¢]] each. Each step of ''k''edt represents a [[frequency ratio]] of 3<sup>1/''k''</sup>, or the ''k''th root of 3.\n"
intro_text = "'''''k'' equal divisions of the tritave''' (abbreviated '''''k''edt''' or '''''k''ed3''') is the [[non-octave]] [[tuning system]] that divides the interval [[3/1]] – also called the [[tritave]] or perfect twelfth – into ''k'' equal parts of exactly/about ''s'' [[¢]] each. Each step of ''k''edt represents a [[frequency ratio]] of 3<sup>1/''k''</sup>, or the ''kth'' root of 3."
elseif is_edf then
elseif ed_type == "edf" then
intro_text = "'''''k'' equal divisions of the fifth''' (abbreviated '''''k''edf''' or '''''k''ed3/2''') is the [[non-octave]] [[tuning system]] that divides the interval [[3/2]], or perfect fifth, into ''k'' equal parts of exactly/about s [[¢]] each. Each step of ''k''edf represents a [[frequency ratio]] of (3/2)<sup>1/''k''</sup>, or the ''k''th root of 3/2.\n"
intro_text = "'''''k'' equal divisions of the fifth''' (abbreviated '''''k''edf''' or '''''k''ed3/2''') is the [[non-octave]] [[tuning system]] that divides the interval [[3/2]], or perfect fifth, into ''k'' equal parts of exactly/about ''s'' [[¢]] each. Each step of ''k''edf represents a [[frequency ratio]] of (3/2)<sup>1/''k''</sup>, or the ''kth'' root of 3/2."
elseif is_harmonic then
elseif ed_type == "edh" then
intro_text = "'''''k'' equal divisions of the ''h''th harmonic''' (abbreviated '''''k''ed''h''''') is the [[non-octave]] [[tuning system]] that divides the interval [[''h''/1]], or the ''h''th harmonic, into ''k'' equal parts of exactly/about s [[¢]] each. Each step of ''k''ed''h'' represents a [[frequency ratio]] of ''h''<sup>1/''k''</sup>, or the ''k''th root of ''h''.\n"
intro_text = "'''''k'' equal divisions of the ''hth'' harmonic''' (abbreviated '''''k''ed''h''''') is the [[non-octave]] [[tuning system]] that divides the interval [[''h''/1]], or the ''hth'' harmonic, into ''k'' equal parts of exactly/about ''s'' [[¢]] each. Each step of ''k''ed''h'' represents a [[frequency ratio]] of ''h''<sup>1/''k''</sup>, or the ''kth'' root of ''h''."
elseif is_edpq then
elseif ed_type == "edr" then
intro_text = "'''''k'' equal divisions of ''p''/''q''''' (abbreviated '''''k''ed''p''/''q''''') is the [[non-octave]] [[tuning system]] that divides the interval [[''p''/''q'']] into ''k'' [[equal]] pieces of exactly/about s [[¢]] each. Each step of ''k''ed''p''/''q'' represents the [[frequency ratio]] of (''p''/''q'')<sup>1/''k''</sup>, or the ''k''th root of ''p''/''q''.\n"
intro_text = "'''''k'' equal divisions of ''p''/''q''''' (abbreviated '''''k''ed''p''/''q''''') is the [[non-octave]] [[tuning system]] that divides the interval [[''p''/''q'']] into ''k'' [[equal]] pieces of exactly/about ''s'' [[¢]] each. Each step of ''k''ed''p''/''q'' represents the [[frequency ratio]] of (''p''/''q'')<sup>1/''k''</sup>, or the ''kth'' root of ''p''/''q''."
elseif is_edc then
elseif ed_type == "edc" then
intro_text = "'''''k'' equal divisions of ''c''¢''' (abbreviated '''''k''ed''c''c''' or '''''k''ed''c''¢''') is the [[non-octave]] [[tuning system]] that divides interval of is divided into ''k'' [[equal]] pieces of exactly/about s [[¢]] each. Each step of ''k''ed''c'' represents the [[frequency ratio]] of ''c''<sup>1/''k''</sup>, or the ''k''th root of ''c''.\n"
intro_text = "'''''k'' equal divisions of ''c''¢''' (abbreviated '''''k''ed''c''c''' or '''''k''ed''c''¢''') is the [[non-octave]] [[tuning system]] that divides interval of ''c''¢ is divided into ''k'' [[equal]] pieces of exactly/about ''s'' [[¢]] each."
end
end
end
end
-- Produce a map of text to replace
-- - ''k'': number of steps in ed
-- - ''s'': size of a step
-- - ''p''/''q'': equave as a ratio
-- - ''h'': equave as a harmonic
-- - ''c'': equave as a cent value
-- - ''hth'': harmonic as an ordinal
-- - ''kth'': step count as an ordinal
local step_size = parsed_ed['cents'] / parsed_ed['steps']
local text_replace_map = {
["''k''"] = parsed_ed['steps'],
["''s''"] = utils._round(step_size, 3),
["''c''"] = utils._round(parsed_ed['cents'], 3),
["''p''/''q''"] = parsed_ed['ratio'],
["''h''"] = parsed_ed['equave'],
["''hth''"] = ord._ordinal(parsed_ed['equave']),
["''kth''"] = ord._ordinal(parsed_ed['steps']),
["exactly/about"] = (utils._round(step_size, 3) == step_size and "exactly" or "about")
}
for key, value in pairs(text_replace_map) do
intro_text = string.gsub(intro_text, key, value)
end
return intro_text
end
end


return p
return p

Revision as of 10:12, 28 January 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 (2)
Line Function Params
13 parse_ed (unparsed)
84 ed_intro (ed)
Lua modules required (3)
Variable Module Functions used
ord Module:Ordinal _ordinal
rat Module:Rational parse
cents
as_ratio
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:
-- - Enforce ED types: edo, edt, edf, edh, edr, edc for octave, tritave/twelfth,
--   fifth, arbitrary harmonic h, arbitrary ratio r, and arbitrary cent value c.
--   Note that EDs of named constants, like pi, are currently not included, as
--   they probably need their own typing (ednc) separate from edc.
-- - Bugfix edr not reporting the correct equave

function p.parse_ed(unparsed)
	local unparsed = unparsed or "12edo"
	
	-- If the unparsed ed is only a numeric value, default to edo
	if tonumber(unparsed) ~= nil then
		unparsed = unparsed .. "edo"
	end
	
	-- Parse
	local steps, equave = unparsed:match('^(%d+)[Ee][Dd](.+)$')
	steps = tonumber(steps)
	
	-- If the equave is text, then the equave is:
	-- o: octave, 2/1 (2nd harmonic)
	-- t: tritave or twelfth, 3/1 (3rd harmonic)
	-- f: fifth, 3/2
	local ed_type = ""
	local ratio = "n/a"
	local cents = 0
	if equave == "o" or equave == "O" or equave == "2" then
		equave = "2"
		ratio = "2/1"
		cents = 1200
		ed_type = "edo"
	elseif equave == "t" or equave == "T" or equave == "3" then
		equave = "3"
		ratio = "3/1"
		cents = math.log(3) * 1200 / math.log(2)
		ed_type = "edt"
	elseif equave == "f" or equave == "F" or equave == "3/2" then
		equave = "3/2"
		ratio = "3/2"
		cents = math.log(3/2) * 1200 / math.log(2)
		ed_type = "edf"
	end
	
	-- For equaves not 2/1, 3/1, or 3/2
	if ed_type == "" then
		-- If the equave is a number or ratio, convert it to cents
		-- If the equave is already a cent value, extract it
		local is_cents = string.match(equave, '^(.+)c') ~= nil
		local is_numeric = tonumber(equave) ~= nil
		local is_ratio = string.match(equave, '^%d+/%d+$') ~= nil
		
		if is_cents then
			cents = tonumber(equave:match('^(.+)c'))
			ed_type = "edc"
		elseif is_numeric then
			cents = math.log(tonumber(equave)) * 1200 / math.log(2)
			
			-- Classify ed type as either ed of a constant (if not a whole number)
			-- or ed of a harmonic (if it's a whole number); if it is a harmonic,
			-- write it as a ratio (h/1)
			if math.floor(tonumber(equave)) ~= tonumber(equave) then
				ed_type = "edc"
			else
				ed_type = "edh"
				ratio = equave .. "/1"
			end
		elseif is_ratio then
			local ratio = rat.parse(equave)
			cents = rat.cents(ratio)
			equave = rat.as_ratio(ratio)		-- Ensures ratio is simplified
			ratio = equave
			ed_type = "edr"
		end
	end

	return { ['cents'] = cents, ['equave'] = equave, ['steps'] = steps, ['ratio'] = ratio, ['type'] = ed_type }
end

function p.ed_intro(ed)
	local ed = ed or "12ed19/13"
	
	local parsed_ed = p.parse_ed(ed)
	local ed_type = parsed_ed['type']
	
	-- Intro formats for each possible case
	-- - Common abbrevs: edo, edt, edf; these have specially written intros
	-- - General harmonic: edh (h-th harmonic)
	-- - Arbitrary JI ratio: edr (ratio of p/q)
	-- - Arbitrary constant: edc
	-- - Equal-step tunings: 1edo, 1edt, 1edf, 1edh, 1edp/q, 1edc
	local intro_text = ""
	if is_est then
		if ed_type == "edo" 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 [[octave]], or exactly/about ''s'' [[¢]], from each other."
		elseif ed_type == "edt" then
			intro_text = "'''1 equal division of the tritave''' (abbreviated '''1edt''' or '''1ed3''') is the [[non-octave]] [[tuning system]] where adjacent pitches are one tritave ([[3/1]]), or exactly/about ''s'' [[¢]], apart from each other."
		elseif ed_type == "edf" then
			intro_text = "'''1 equal division of the fifth''' (abbreviated '''1edf''' or '''1ed3/2''') is the [[non-octave]] [[tuning system]] where adjacent pitches are one perfect fifth ([[3/2]]), or exactly/about ''s'' [[¢]], apart from each other."
		elseif ed_type == "edh" then
			intro_text = "'''1 equal division of the ''hth'' harmonic''' (abbreviated '''1ed''h''''') is the [[non-octave]] [[tuning system]] where adjacent pitches are one interval of [[''h''/1]], or exactly/about ''s'' [[¢]], apart from each other."
		elseif ed_type == "edr" then
			intro_text = "'''1 equal division of ''p''/''q''''' (abbreviated '''1ed''p''/''q''''') is the [[non-octave]] [[tuning system]] where adjacent pitches are one interval of [[''p''/''q'']], or exactly/about ''s'' [[¢]], apart from each other."
		elseif ed_type == "edc" then
			intro_text = "'''1 equal division of ''c''¢''' (abbreviated '''1ed''c''''') is the [[non-octave]] [[tuning system]] where adjacent pitches are ''s'' [[¢]], apart from each other."
		end
	else
		if ed_type == "edo" then
			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 of ''k''edo represents a [[frequency ratio]] of 2<sup>1/''k''</sup>, or the ''kth'' root of 2."
		elseif ed_type == "edt" then
			intro_text = "'''''k'' equal divisions of the tritave''' (abbreviated '''''k''edt''' or '''''k''ed3''') is the [[non-octave]] [[tuning system]] that divides the interval [[3/1]] – also called the [[tritave]] or perfect twelfth – into ''k'' equal parts of exactly/about ''s'' [[¢]] each. Each step of ''k''edt represents a [[frequency ratio]] of 3<sup>1/''k''</sup>, or the ''kth'' root of 3."
		elseif ed_type == "edf" then
			intro_text = "'''''k'' equal divisions of the fifth''' (abbreviated '''''k''edf''' or '''''k''ed3/2''') is the [[non-octave]] [[tuning system]] that divides the interval [[3/2]], or perfect fifth, into ''k'' equal parts of exactly/about ''s'' [[¢]] each. Each step of ''k''edf represents a [[frequency ratio]] of (3/2)<sup>1/''k''</sup>, or the ''kth'' root of 3/2."
		elseif ed_type == "edh" then
			intro_text = "'''''k'' equal divisions of the ''hth'' harmonic''' (abbreviated '''''k''ed''h''''') is the [[non-octave]] [[tuning system]] that divides the interval [[''h''/1]], or the ''hth'' harmonic, into ''k'' equal parts of exactly/about ''s'' [[¢]] each. Each step of ''k''ed''h'' represents a [[frequency ratio]] of ''h''<sup>1/''k''</sup>, or the ''kth'' root of ''h''."
		elseif ed_type == "edr" then
			intro_text = "'''''k'' equal divisions of ''p''/''q''''' (abbreviated '''''k''ed''p''/''q''''') is the [[non-octave]] [[tuning system]] that divides the interval [[''p''/''q'']] into ''k'' [[equal]] pieces of exactly/about ''s'' [[¢]] each. Each step of ''k''ed''p''/''q'' represents the [[frequency ratio]] of (''p''/''q'')<sup>1/''k''</sup>, or the ''kth'' root of ''p''/''q''."
		elseif ed_type == "edc" then
			intro_text = "'''''k'' equal divisions of ''c''¢''' (abbreviated '''''k''ed''c''c''' or '''''k''ed''c''¢''') is the [[non-octave]] [[tuning system]] that divides interval of ''c''¢ is divided into ''k'' [[equal]] pieces of exactly/about ''s'' [[¢]] each."
		end
	end
	
	-- Produce a map of text to replace
	-- - ''k'': number of steps in ed
	-- - ''s'': size of a step
	-- - ''p''/''q'': equave as a ratio
	-- - ''h'': equave as a harmonic
	-- - ''c'': equave as a cent value
	-- - ''hth'': harmonic as an ordinal
	-- - ''kth'': step count as an ordinal
	local step_size = parsed_ed['cents'] / parsed_ed['steps']
	local text_replace_map = {
		["''k''"] = parsed_ed['steps'],
		["''s''"] = utils._round(step_size, 3),
		["''c''"] = utils._round(parsed_ed['cents'], 3),
		["''p''/''q''"] = parsed_ed['ratio'],
		["''h''"] = parsed_ed['equave'],
		["''hth''"] = ord._ordinal(parsed_ed['equave']),
		["''kth''"] = ord._ordinal(parsed_ed['steps']),
		["exactly/about"] = (utils._round(step_size, 3) == step_size and "exactly" or "about")
	}
	
	for key, value in pairs(text_replace_map) do
		intro_text = string.gsub(intro_text, key, value)
	end
	
	return intro_text
end

return p