Module:Infobox regtemp: Difference between revisions

From Xenharmonic Wiki
Jump to navigation Jump to search
Lériendil (talk | contribs)
copied from infobox AFDO
 
Xenllium (talk | contribs)
No edit summary
Tags: Mobile edit Mobile web edit
 
(63 intermediate revisions by 5 users not shown)
Line 1: Line 1:
local p = {}
local p = {}
local infobox = require("Module:Infobox")
local u = require("Module:Utils")
local u = require("Module:Utils")
local infobox = require("Module:Infobox")
local yesno = require("Module:Yesno")


function p.infobox_RT(frame)
function p.infobox_RT(frame)
-- no real math functionality... yet
local name = frame.args["tempname"]
local name = frame.args["tempname"]
Line 11: Line 12:
local basis = frame.args["commas"]
local basis = frame.args["commas"]
local edo_first = frame.args["edo_first"]
local et1 = frame.args["edo_first"]
local edo1 = tonumber(edo_first)
local et2 = frame.args["edo_second"]
local edo_second = frame.args["edo_second"]
local et3 = frame.args["edo_third"]
local edo2 = tonumber(edo_second)
local et4 = frame.args["edo_fourth"]
local tuning = frame.args["tuning"]
local tuning = frame.args["tuning"]
local genfrac = frame.args["genfrac"]
local genfrac = frame.args["genfrac"]
local method = frame.args["method"]
local method = frame.args["method"]
local mapping = frame.args["mapping"]
local mos_override = frame.args["mosses"]
local ploidacot_override = frame.args["ploidacot"]
local colorname = frame.args["colorname"]
local pergen = frame.args["pergen"]
local mos = frame.args["mosses"]
local ploidacot = frame.args["ploidacot"]
local limit1 = frame.args["lim1"]
local limit1 = frame.args["lim1"]
local comp1 = frame.args["comp1"]
local comp1 = frame.args["comp1"]
Line 28: Line 33:
local comp2 = frame.args["comp2"]
local comp2 = frame.args["comp2"]
local acc2 = frame.args["acc2"]
local acc2 = frame.args["acc2"]
local limit3 = frame.args["lim3"]
local comp3 = frame.args["comp3"]
local acc3 = frame.args["acc3"]
local limit4 = frame.args["lim4"]
local comp4 = frame.args["comp4"]
local acc4 = frame.args["acc4"]
local debugg = frame.args["debug"]
local data = {}
-- process mapping
local rank = p.count_matches(mapping, ";") + 1
local period = string.match(mapping, "(-?%d+);")
local genchain_mapping = {}
for str in mapping:gmatch("(-?%d+)") do
table.insert(genchain_mapping, str)
end
local infobox_data = {}
-- interpret subgroup
table.insert(infobox_data, {
local subgroup_basis = {}
for str in subgroup:gmatch("(%d+/?%d*)") do
table.insert(subgroup_basis, str)
end
local equave = u.eval_num_arg(subgroup_basis[1])
-- process et join
function process_et_join(et)
local et_eq, et_num = p.warts2ed(et)
local et_eq_letter = p.equave2letter (et_eq)
return "[[" .. et_num .. "ed" .. et_eq_letter .. "|" .. et .. "]]"
end
local et_table = {}
for _, et in ipairs({et1, et2, et3, et4}) do
if u.value_provided(et) then
table.insert(et_table, process_et_join (et))
end
end
local et_join = table.concat(et_table, " & ")
-- process generators
function process_generators(genfrac_item, tuning_item)
return "~" .. genfrac_item .. " = " .. tuning_item .. "{{c}}"
end
local genfrac_table = {}
for str in genfrac:gmatch("(%d+/?%d*)") do
table.insert(genfrac_table, str)
end
local tuning_table = {}
for str in tuning:gmatch("(-?%d+%.?%d*)") do
table.insert(tuning_table, str)
end
local generators_table = {}
for i = 1, math.min(#genfrac_table, #tuning_table) do
table.insert(generators_table,
process_generators (genfrac_table[i], tuning_table[i]))
end
local generators = table.concat (generators_table, ", ")
-- default value for mos
local mos = "n/a"
-- autocalculating ploidacot
if rank == 2 then
local ploid = tonumber(period)
local referent = u.eval_num_arg(subgroup_basis[2])
local cot = tonumber(genchain_mapping[2])
local suffix = "cleft"
if equave == 2 then -- octave-based temp
if referent == 3 then
suffix = "cot"
elseif referent == 5 then
suffix = "seph"
end
elseif equave == 3 then -- twelfth-based temp
if referent == 5 then
referent_candidate = u.eval_num_arg(subgroup_basis[3])
if referent_candidate == 7 then
referent = referent_candidate
cot = tonumber(genchain_mapping[3])
suffix = "gem"
end
end
end
if suffix == "cleft" then
suffix = referent .. suffix
end
local equave_size = 1200 * u.log2(equave)
local referent_size = 1200 * u.log2(referent)
local period_size = equave_size / ploid
local generator_size = tonumber(tuning_table[1])
if cot < 0 then
generator_size = equave_size - generator_size
cot = -cot
end
-- find the shear
local shear
if cot ~= 0 then
shear = (math.floor(generator_size * cot / period_size)
- math.floor(referent_size % equave_size / period_size)) % cot
else
shear = 0
end
-- omega extension
if ploid == 1 and cot > 2 and shear == cot - ploid then
shear = shear - cot
end
-- construct the ploidacot signature
local MAX_GREEK_NUMERAL = 12 -- max number to convert to greek letters/numerals
local ploid_sig
if ploid == 1 then
ploid_sig = "" -- omit the ploid part
elseif ploid <= MAX_GREEK_NUMERAL then
ploid_sig = p.num2greek(tostring(ploid), "ploid") .. "ploid "
else
ploid_sig = tostring (ploid) .. "-ploid "
end
local shear_sig
if shear <= MAX_GREEK_NUMERAL then
shear_sig = p.num2greeklet(tostring(shear))
else
shear_sig = tostring(shear) .. "-sheared "
end
local cot_sig
if cot <= MAX_GREEK_NUMERAL then
cot_sig = p.num2greek(tostring(cot), "cot") .. suffix
else
cot_sig = tostring(cot) .. "-" .. suffix
end
ploidacot = ploid_sig .. shear_sig .. cot_sig
else
ploidacot = "n/a"
end
-- user override
if u.value_provided (mos_override) then
mos = mos_override
end
if u.value_provided (ploidacot_override) then
ploidacot = ploidacot_override
end
-- construct the table
table.insert(data, {
"Subgroups",
"Subgroups",
subgroup
subgroup
})
})


table.insert(infobox_data, {
table.insert(data, {
"Comma basis",
"Comma basis",
commas
basis
})
})


table.insert(infobox_data, {
table.insert(data, {
"Edo join",
"Reduced mapping",
"[[" .. edo_first .. "edo|" .. edo_first .. "]] & [[" .. edo_second .. "edo|" .. edo_second .. "]]"
"" .. mapping .. "]"
})
})


table.insert(infobox_data, {
table.insert(data, {
"ET join",
et_join
})
 
table.insert(data, {
"Generators ([[" .. method .. "]])",
generators
})
 
table.insert(data, {
"MOS scales",
"MOS scales",
mos
mos
})
})


table.insert(infobox_data, {
table.insert(data, {
"Ploidacot",
"Ploidacot",
ploidacot
ploidacot
})
})
if u.value_provided (pergen) then
table.insert(data, {
"Pergen",
pergen
})
end
if u.value_provided (colorname) then
table.insert(data, {
"Color name",
colorname
})
end
-- error and stuff
local limit_text
if equave == 2 then
limit_text = "-odd-limit"
elseif equave == 3 then
limit_text = "-throdd-limit"
else
limit_text = "-integer-limit"
end
local string1 = limit1 .. limit_text .. ": " .. acc1 .. "{{c}}"
local string2 = limit1 .. limit_text .. ": " .. comp1 .. " notes"
if u.value_provided (limit2) then
string1 = string1 .. "; <br>" .. limit2 .. limit_text .. ": " .. acc2 .. "{{c}}"
string2 = string2 .. "; <br>" .. limit2 .. limit_text .. ": " .. comp2 .. " notes"
end
if u.value_provided (limit3) then
string1 = string1 .. "; <br>" .. limit3 .. limit_text .. ": " .. acc3 .. "{{c}}"
string2 = string2 .. "; <br>" .. limit3 .. limit_text .. ": " .. comp3 .. " notes"
end
if u.value_provided (limit4) then
string1 = string1 .. "; <br>" .. limit4 .. limit_text .. ": " .. acc4 .. "{{c}}"
string2 = string2 .. "; <br>" .. limit4 .. limit_text .. ": " .. comp4 .. " notes"
end


table.insert(infobox_data, {
table.insert(data, {
"Minmax error",
"Minimax error",
"(" .. limit1 .. ") " .. acc1 .. "c; <br> (" .. limit2 .. ") " .. acc2 .. "c"
string1
})
})


table.insert(infobox_data, {
table.insert(data, {
"Target scale size",
"Target scale size",
"(" .. limit1 .. ") " .. comp1 .. " notes; <br> (" .. limit2 .. ") " .. comp2 .. " notes"
string2
})
})


local result = infobox.build(
local result = infobox.build(
name,
name,
infobox_data
data
)
)
return result
return frame:preprocess(debugg == true and "<pre>" .. result .. "</pre>" or result)
end
 
function p.count_matches(base, pattern)
    return select(2, string.gsub(base, pattern, ""))
end
 
function p.digit2greek(number, purpose)
 
local greek
if number == "1" then
if purpose == "ploid" then
greek = "ha"
elseif purpose == "cot" then
greek = "mono"
elseif purpose == "decade" then
greek = "deca"
else
greek = "hen"
end
elseif number == "2" then
if purpose == "decade" then
greek = "icosa"
elseif purpose == "unit" then
greek = "do"
else
greek = "di"
end
elseif number == "0" then
if purpose == "unit" then
greek = ""
else
greek = "a"
end
else
if number == "3" then
if purpose == "decade" then
greek = "tria"
else
greek = "tri"
end
elseif number == "4" then
if purpose == "decade" then
greek = "tessera"
else
greek = "tetra"
end
elseif number == "5" then
if purpose == "decade" then
greek = "pente"
else
greek = "penta"
end
elseif number == "6" then
if purpose == "decade" then
greek = "hexe"
else
greek = "hexa"
end
elseif number == "7" then
if purpose == "decade" then
greek = "hebdome"
else
greek = "hepta"
end
elseif number == "8" then
if purpose == "decade" then
greek = "ogdoe"
elseif purpose == "unit" then
greek = "octo"
else
greek = "octa"
end
elseif number == "9" then
if purpose == "decade" then
greek = "enene"
else
greek = "ennea"
end
end
if purpose == "decade" then
greek = greek .. "conta"
end
end
 
return greek
end
 
function p.num2greek(number, purpose)
 
local greek
if string.len(number) == 1 then
greek = p.digit2greek(number, purpose)
elseif string.len(number) == 2 then
local unit = string.char(string.byte(number, 2))
local decade = string.char(string.byte(number, 1))
greek = p.digit2greek(unit, "unit") .. p.digit2greek(decade, "decade")
end
return greek
end
 
function p.digit2greeklet(number, purpose)
 
local greek
if number == "1" then
if purpose == "decade" then
greek = "iota-"
elseif purpose == "unit" then
greek = "alpha-"
end
elseif number == "2" then
if purpose == "decade" then
greek = "kappa-"
elseif purpose == "unit" then
greek = "beta-"
end
elseif number == "3" then
if purpose == "decade" then
greek = "lambda-"
elseif purpose == "unit" then
greek = "gamma-"
end
elseif number == "4" then
if purpose == "decade" then
greek = "mu-"
elseif purpose == "unit" then
greek = "delta-"
end
elseif number == "5" then
if purpose == "decade" then
greek = "nu-"
elseif purpose == "unit" then
greek = "epsilon-"
end
elseif number == "6" then
if purpose == "decade" then
greek = "xi-"
elseif purpose == "unit" then
greek = "wau-"
end
elseif number == "7" then
if purpose == "decade" then
greek = "omicron-"
elseif purpose == "unit" then
greek = "zeta-"
end
elseif number == "8" then
if purpose == "decade" then
greek = "pi-"
elseif purpose == "unit" then
greek = "eta-"
end
elseif number == "9" then
if purpose == "decade" then
greek = "qoppa-"
elseif purpose == "unit" then
greek = "theta-"
end
elseif number == "0" then
greek = ""
elseif number == "-1" then
greek = "omega-"
end
 
return greek
end
 
function p.num2greeklet(number)
 
local greek
if string.len(string.match(number, "(%d+)")) == 1 then
greek = p.digit2greeklet(number, "unit")
elseif string.len(string.match(number, "(%d+)")) == 2 then
local unit = string.char(string.byte(number, 2))
local decade = string.char(string.byte(number, 1))
greek = p.digit2greeklet(decade, "decade") .. p.digit2greeklet(unit, "unit")
end
return greek
end
 
function p.equave2letter(et_eq)
-- converts an equave string to a letter
local et_eq_letter
if et_eq == "2" then
et_eq_letter = "o"
elseif et_eq == "3" then
et_eq_letter = "t"
elseif et_eq == "3/2" then
et_eq_letter = "f"
else
et_eq_letter = et_eq
end
return et_eq_letter
end
 
function p.warts2ed(warts)
-- converts a wart notation to an equal division
local wart_prefix, et_num = warts:match ("(%a?)(%d+)")
local et_eq = "2"
if wart_prefix == "a" then
et_eq = "2"
elseif wart_prefix == "b" then
et_eq = "3"
elseif wart_prefix == "c" then
et_eq = "5"
elseif wart_prefix == "d" then
et_eq = "7"
elseif wart_prefix == "e" then
et_eq = "11"
elseif wart_prefix == "f" then
et_eq = "13"
elseif wart_prefix == "g" then
et_eq = "17"
elseif wart_prefix == "h" then
et_eq = "19"
elseif wart_prefix == "i" then
et_eq = "23"
elseif wart_prefix == "j" then
et_eq = "29"
elseif wart_prefix == "k" then
et_eq = "31"
end
return et_eq, et_num
end
end


return p
return p

Latest revision as of 08:12, 4 May 2026

Module documentation[view] [edit] [history] [purge]
This module should not be invoked directly; use its corresponding template instead: Template:Infobox regtemp.
Module:Infobox regtemp is a draft module. It is incomplete and may not be in active development. If possible, editors are encouraged to help with its development. In the meantime, editors should avoid using this module across the Xenharmonic Wiki, except for testing.

This module generates an infobox providing information about a given regular temperament.

Introspection summary for Module:Infobox regtemp 
Functions provided (8)
Line Function Params
7 infobox_RT (invokable) (frame)
280 count_matches (base, pattern)
284 digit2greek (number, purpose)
366 num2greek (number, purpose)
381 digit2greeklet (number, purpose)
448 num2greeklet (number)
463 equave2letter (et_eq)
478 warts2ed (warts)
Lua modules required (3)
Variable Module Functions used
infobox Module:Infobox build
u Module:Utils eval_num_arg
value_provided
log2
yesno Module:Yesno dependency not used

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


local p = {}

local infobox = require("Module:Infobox")
local u = require("Module:Utils")
local yesno = require("Module:Yesno")

function p.infobox_RT(frame)
	
	local name = frame.args["tempname"]
	
	local subgroup = frame.args["subgroup"]
	local basis = frame.args["commas"]
	
	local et1 = frame.args["edo_first"]
	local et2 = frame.args["edo_second"]
	local et3 = frame.args["edo_third"]
	local et4 = frame.args["edo_fourth"]
	
	local tuning = frame.args["tuning"]
	local genfrac = frame.args["genfrac"]
	local method = frame.args["method"]
	local mapping = frame.args["mapping"]
	
	local mos_override = frame.args["mosses"]
	local ploidacot_override = frame.args["ploidacot"]
	local colorname = frame.args["colorname"]
	local pergen = frame.args["pergen"]
	
	local limit1 = frame.args["lim1"]
	local comp1 = frame.args["comp1"]
	local acc1 = frame.args["acc1"]
	local limit2 = frame.args["lim2"]
	local comp2 = frame.args["comp2"]
	local acc2 = frame.args["acc2"]
	local limit3 = frame.args["lim3"]
	local comp3 = frame.args["comp3"]
	local acc3 = frame.args["acc3"]
	local limit4 = frame.args["lim4"]
	local comp4 = frame.args["comp4"]
	local acc4 = frame.args["acc4"]
	local debugg = frame.args["debug"]
	
	local data = {}
	
	-- process mapping
	local rank = p.count_matches(mapping, ";") + 1
	local period = string.match(mapping, "(-?%d+);")
	local genchain_mapping = {}
	for str in mapping:gmatch("(-?%d+)") do
		table.insert(genchain_mapping, str)
	end
	
	-- interpret subgroup
	local subgroup_basis = {}
	for str in subgroup:gmatch("(%d+/?%d*)") do
		table.insert(subgroup_basis, str)
	end
	
	local equave = u.eval_num_arg(subgroup_basis[1])
	
	-- process et join
	function process_et_join(et)
		local et_eq, et_num = p.warts2ed(et)
		local et_eq_letter = p.equave2letter (et_eq)
		return "[[" .. et_num .. "ed" .. et_eq_letter .. "|" .. et .. "]]"
	end
	
	local et_table = {}
	for _, et in ipairs({et1, et2, et3, et4}) do
		if u.value_provided(et) then
			table.insert(et_table, process_et_join (et))
		end
	end
	local et_join = table.concat(et_table, " & ")
	
	-- process generators
	function process_generators(genfrac_item, tuning_item)
		return "~" .. genfrac_item .. " = " .. tuning_item .. "{{c}}"
	end
	
	local genfrac_table = {}
	for str in genfrac:gmatch("(%d+/?%d*)") do
		table.insert(genfrac_table, str)
	end
	local tuning_table = {}
	for str in tuning:gmatch("(-?%d+%.?%d*)") do
		table.insert(tuning_table, str)
	end
	local generators_table = {}
	for i = 1, math.min(#genfrac_table, #tuning_table) do
		table.insert(generators_table, 
			process_generators (genfrac_table[i], tuning_table[i]))
	end
	local generators = table.concat (generators_table, ", ")
	
	-- default value for mos
	local mos = "n/a"
	
	-- autocalculating ploidacot
	if rank == 2 then
		local ploid = tonumber(period)
		local referent = u.eval_num_arg(subgroup_basis[2])
		local cot = tonumber(genchain_mapping[2])
		local suffix = "cleft"
		if equave == 2 then -- octave-based temp
			if referent == 3 then
				suffix = "cot"
			elseif referent == 5 then
				suffix = "seph"
			end
		elseif equave == 3 then -- twelfth-based temp
			if referent == 5 then
				referent_candidate = u.eval_num_arg(subgroup_basis[3])
				if referent_candidate == 7 then
					referent = referent_candidate
					cot = tonumber(genchain_mapping[3])
					suffix = "gem"
				end
			end
		end
		
		if suffix == "cleft" then
			suffix = referent .. suffix
		end
		
		local equave_size = 1200 * u.log2(equave)
		local referent_size = 1200 * u.log2(referent)
		local period_size = equave_size / ploid
		local generator_size = tonumber(tuning_table[1])
		if cot < 0 then
			generator_size = equave_size - generator_size
			cot = -cot
		end
		
		-- find the shear
		local shear
		if cot ~= 0 then
			shear = (math.floor(generator_size * cot / period_size) 
				- math.floor(referent_size % equave_size / period_size)) % cot
		else
			shear = 0
		end
		
		-- omega extension
		if ploid == 1 and cot > 2 and shear == cot - ploid then
			shear = shear - cot
		end
		
		-- construct the ploidacot signature
		local MAX_GREEK_NUMERAL = 12 -- max number to convert to greek letters/numerals
		
		local ploid_sig
		if ploid == 1 then
			ploid_sig = "" -- omit the ploid part
		elseif ploid <= MAX_GREEK_NUMERAL then
			ploid_sig = p.num2greek(tostring(ploid), "ploid") .. "ploid "
		else
			ploid_sig = tostring (ploid) .. "-ploid "
		end
		
		local shear_sig
		if shear <= MAX_GREEK_NUMERAL then
			shear_sig = p.num2greeklet(tostring(shear))
		else
			shear_sig = tostring(shear) .. "-sheared "
		end
		
		local cot_sig
		if cot <= MAX_GREEK_NUMERAL then
			cot_sig = p.num2greek(tostring(cot), "cot") .. suffix
		else
			cot_sig = tostring(cot) .. "-" .. suffix
		end
		
		ploidacot = ploid_sig .. shear_sig .. cot_sig
	else
		ploidacot = "n/a"
	end
		
	-- user override
	if u.value_provided (mos_override) then
		mos = mos_override
	end
	if u.value_provided (ploidacot_override) then
		ploidacot = ploidacot_override
	end
	
	-- construct the table
	table.insert(data, {
		"Subgroups",
		subgroup
	})

	table.insert(data, {
		"Comma basis",
		basis
	})

	table.insert(data, {
		"Reduced mapping",
		"⟨" .. mapping .. "]"
	})

	table.insert(data, {
		"ET join",
		et_join
	})

	table.insert(data, {
		"Generators ([[" .. method .. "]])",
		generators
	})

	table.insert(data, {
		"MOS scales",
		mos
	})

	table.insert(data, {
		"Ploidacot",
		ploidacot
	})
	
	if u.value_provided (pergen) then
		table.insert(data, {
			"Pergen",
			pergen
		})
	end

	if u.value_provided (colorname) then
		table.insert(data, {
			"Color name",
			colorname
		})
	end
	
	-- error and stuff
	local limit_text
	if equave == 2 then
		limit_text = "-odd-limit"
	elseif equave == 3 then
		limit_text = "-throdd-limit"
	else
		limit_text = "-integer-limit"
	end
	local string1 = limit1 .. limit_text .. ": " .. acc1 .. "{{c}}"
	local string2 = limit1 .. limit_text .. ": " .. comp1 .. " notes"
	if u.value_provided (limit2) then
		string1 = string1 .. "; <br>" .. limit2 .. limit_text .. ": " .. acc2 .. "{{c}}"
		string2 = string2 .. "; <br>" .. limit2 .. limit_text .. ": " .. comp2 .. " notes"
	end
	if u.value_provided (limit3) then
		string1 = string1 .. "; <br>" .. limit3 .. limit_text .. ": " .. acc3 .. "{{c}}"
		string2 = string2 .. "; <br>" .. limit3 .. limit_text .. ": " .. comp3 .. " notes"
	end
	if u.value_provided (limit4) then
		string1 = string1 .. "; <br>" .. limit4 .. limit_text .. ": " .. acc4 .. "{{c}}"
		string2 = string2 .. "; <br>" .. limit4 .. limit_text .. ": " .. comp4 .. " notes"
	end

	table.insert(data, {
		"Minimax error",
		string1
	})

	table.insert(data, {
		"Target scale size",
		string2
	})

	local result = infobox.build(
		name,
		data
	)
	
	return frame:preprocess(debugg == true and "<pre>" .. result .. "</pre>" or result)
end

function p.count_matches(base, pattern)
    return select(2, string.gsub(base, pattern, ""))
end

function p.digit2greek(number, purpose)

	local greek
	
	if number == "1" then
		if purpose == "ploid" then
			greek = "ha"
		elseif purpose == "cot" then
			greek = "mono"
		elseif purpose == "decade" then
			greek = "deca"
		else
			greek = "hen"
		end
	elseif number == "2" then
		if purpose == "decade" then
			greek = "icosa"
		elseif purpose == "unit" then
			greek = "do"
		else
			greek = "di"
		end
	elseif number == "0" then
		if purpose == "unit" then
			greek = ""
		else
			greek = "a"
		end
	else
		if number == "3" then
			if purpose == "decade" then
				greek = "tria"
			else
				greek = "tri"
			end
		elseif number == "4" then
			if purpose == "decade" then
				greek = "tessera"
			else
				greek = "tetra"
			end
		elseif number == "5" then
			if purpose == "decade" then
				greek = "pente"
			else
				greek = "penta"
			end
		elseif number == "6" then
			if purpose == "decade" then
				greek = "hexe"
			else
				greek = "hexa"
			end
		elseif number == "7" then
			if purpose == "decade" then
				greek = "hebdome"
			else
				greek = "hepta"
			end
		elseif number == "8" then
			if purpose == "decade" then
				greek = "ogdoe"
			elseif purpose == "unit" then
				greek = "octo"
			else
				greek = "octa"
			end
		elseif number == "9" then
			if purpose == "decade" then
				greek = "enene"
			else
				greek = "ennea"
			end
		end
		if purpose == "decade" then
			greek = greek .. "conta"
		end
	end

	return greek
end

function p.num2greek(number, purpose)

	local greek
	
	if string.len(number) == 1 then
		greek = p.digit2greek(number, purpose)
	elseif string.len(number) == 2 then
		local unit = string.char(string.byte(number, 2))
		local decade = string.char(string.byte(number, 1))
		
		greek = p.digit2greek(unit, "unit") .. p.digit2greek(decade, "decade")
	end
	return greek
end

function p.digit2greeklet(number, purpose)

	local greek
	
	if number == "1" then
		if purpose == "decade" then
			greek = "iota-"
		elseif purpose == "unit" then
			greek = "alpha-"
		end
	elseif number == "2" then
		if purpose == "decade" then
			greek = "kappa-"
		elseif purpose == "unit" then
			greek = "beta-"
		end
	elseif number == "3" then
		if purpose == "decade" then
			greek = "lambda-"
		elseif purpose == "unit" then
			greek = "gamma-"
		end
	elseif number == "4" then
		if purpose == "decade" then
			greek = "mu-"
		elseif purpose == "unit" then
			greek = "delta-"
		end
	elseif number == "5" then
		if purpose == "decade" then
			greek = "nu-"
		elseif purpose == "unit" then
			greek = "epsilon-"
		end
	elseif number == "6" then
		if purpose == "decade" then
			greek = "xi-"
		elseif purpose == "unit" then
			greek = "wau-"
		end
	elseif number == "7" then
		if purpose == "decade" then
			greek = "omicron-"
		elseif purpose == "unit" then
			greek = "zeta-"
		end
	elseif number == "8" then
		if purpose == "decade" then
			greek = "pi-"
		elseif purpose == "unit" then
			greek = "eta-"
		end
	elseif number == "9" then
		if purpose == "decade" then
			greek = "qoppa-"
		elseif purpose == "unit" then
			greek = "theta-"
		end	
	elseif number == "0" then
		greek = ""
	elseif number == "-1" then
		greek = "omega-"
	end

	return greek
end

function p.num2greeklet(number)

	local greek
	
	if string.len(string.match(number, "(%d+)")) == 1 then
		greek = p.digit2greeklet(number, "unit")
	elseif string.len(string.match(number, "(%d+)")) == 2 then
		local unit = string.char(string.byte(number, 2))
		local decade = string.char(string.byte(number, 1))
		
		greek = p.digit2greeklet(decade, "decade") .. p.digit2greeklet(unit, "unit")
	end
	return greek
end

function p.equave2letter(et_eq)
	-- converts an equave string to a letter
	local et_eq_letter
	if et_eq == "2" then
		et_eq_letter = "o"
	elseif et_eq == "3" then
		et_eq_letter = "t"
	elseif et_eq == "3/2" then
		et_eq_letter = "f"
	else
		et_eq_letter = et_eq
	end
	return et_eq_letter
end

function p.warts2ed(warts)
	-- converts a wart notation to an equal division
	local wart_prefix, et_num = warts:match ("(%a?)(%d+)")
	local et_eq = "2"
	if wart_prefix == "a" then
		et_eq = "2"
	elseif wart_prefix == "b" then
		et_eq = "3"
	elseif wart_prefix == "c" then
		et_eq = "5"
	elseif wart_prefix == "d" then
		et_eq = "7"
	elseif wart_prefix == "e" then
		et_eq = "11"
	elseif wart_prefix == "f" then
		et_eq = "13"
	elseif wart_prefix == "g" then
		et_eq = "17"
	elseif wart_prefix == "h" then
		et_eq = "19"
	elseif wart_prefix == "i" then
		et_eq = "23"
	elseif wart_prefix == "j" then
		et_eq = "29"
	elseif wart_prefix == "k" then
		et_eq = "31"
	end
	return et_eq, et_num
end

return p