Module:Rank-n scale

From Xenharmonic Wiki
Revision as of 09:01, 19 April 2024 by Akselai (talk | contribs) (Created page with "local infobox = require('Module:Infobox') local p = {} function p.rotate_word(str, n) -- rotate word s by n steps return string.sub(str, n+1, #str) .. string.sub(str, 1,...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
Module documentation[view] [edit] [history] [purge]
This module should not be invoked directly; use its corresponding template instead: Template:Rank-n scale.

This module generates an information table for scales of 3- or higher arity.


Introspection summary for Module:Rank-n scale 
Functions provided (8)
Line Function Params
5 rotate_word (str, n)
9 rotate_word_full (str)
17 bright_dark_chiral (str)
48 table_length (T)
54 abelianize (str)
60 list_step_varieties (str)
74 max_variety (str)
90 create_infobox (str)
Lua modules required (1)
Variable Module Functions used
infobox Module:Infobox build_multilink

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


local infobox = require('Module:Infobox')

local p = {}

function p.rotate_word(str, n) -- rotate word s by n steps
    return string.sub(str, n+1, #str) .. string.sub(str, 1, n)
end    

function p.rotate_word_full(str)
	local full = {}
	for i = 1, #str do
		full[i] = p.rotate_word(str, i-1)
	end
	return full
end

function p.bright_dark_chiral(str)
	local full = p.rotate_word_full(str)
	local bright, dark = str, str
	for i = 2, #str do
		if bright > full[i] then
			bright = full[i]
		end
		if dark < full[i] then 
			dark = full[i]
		end
	end
	
	local bright2, dark2 = string.reverse(str), string.reverse(str)
	for i = 2, #str do
		local rev = string.reverse(full[i])
		if bright2 > rev then
			bright2 = rev
		end
		if dark2 < rev then 
			dark2 = rev
		end
	end
	if bright2 == bright then
		return {["blh"] = bright, ["brh"] = bright, ["dlh"] = dark, ["drh"] = dark, ["chiral"] = "no"}
	elseif bright2 < bright then
		return {["blh"] = bright, ["brh"] = bright2, ["dlh"] = dark, ["drh"] = dark2, ["chiral"] = "yes"}
	else
		return {["blh"] = bright2, ["brh"] = bright, ["dlh"] = dark2, ["drh"] = dark, ["chiral"] = "yes"}
	end
end

function p.table_length(T)
	local count = 0
	for _ in pairs(T) do count = count + 1 end
	return count
end

function p.abelianize(str) -- sorts string by letter. from rosetta code because I'm lazy.
	local t = {} str:gsub("(%S)", function(c) t[#t+1]=c end) -- use "(.)" as pattern to preserve whitespace
    table.sort(t, function(a,b) return a<b end) -- implicitly
    return table.concat(t)
end

function p.list_step_varieties(str)
	local strstr = str .. str
	local step_vars = {}
	for i = 1, math.floor(#str/2) do
		local r = {}
		for j = 1, #str do
			local u = p.abelianize(string.sub(strstr, j, j+i-1))
			r[u] = true
		end
		step_vars[i] = r
	end
	return step_vars
end

function p.max_variety(str)
	local lsv = p.list_step_varieties(str)
	local max_var = 0
	local is_strict = "yes"
	for i = 1, math.floor(#str/2) do
		i_step_var = p.table_length(lsv[i])
		if i_step_var > max_var then
			if max_var ~= 0 then
				is_strict = "no"
			end
			max_var = i_step_var
		end
	end
	return {["max variety"] = max_var, ["is strict?"] = is_strict}
end

function p.create_infobox(str)
	local mv = p.max_variety(str)
	local bdc = p.bright_dark_chiral(str)
	
	local brightest_mode
	local darkest_mode
	
	if bdc["chiral"] == "yes" then
		brightest_mode = {"Brightest mode", "LH " .. bdc["blh"] .. "\nRH ".. bdc["brh"]}
		darkest_mode = {"Darkest mode", "LH " .. bdc["dlh"] .. "\nRH ".. bdc["drh"]}
	else
		brightest_mode = {"Brightest mode", bdc["brh"]}
		darkest_mode = {"Darkest mode", bdc["drh"]}
	end
	
	local entries = {
		{"Scale structure"},
		
		{"Step pattern"},
		brightest_mode,
		darkest_mode,
		
		{"Is chiral?", bdc["chiral"]},
		
		{"Maximum variety", mv["max variety"]},
		{"Has strict variety?", mv["is strict?"]},
	}
	return infobox.build_multilink(str, entries)
end

-- {"Mean variety", " "}
-- {"Is generator-offset?", " "},
-- {"Tuning ranges"},
-- {"Parent scales"},
-- {"Descendant scales"},

return p