Module:MOS intro: Difference between revisions

From Xenharmonic Wiki
Jump to navigation Jump to search
Ganaram inukshuk (talk | contribs)
Added TAMNAMS name lookup and support for entering names outside of TAMNAMS
Ganaram inukshuk (talk | contribs)
Corrected step count output for multi-period mosses
Line 110: Line 110:
intro = intro .. " with a period of 1 large step and "
intro = intro .. " with a period of 1 large step and "
else
else
intro = intro .. " with a period of " .. n .. " large steps and "
intro = intro .. " with a period of " .. x .. " large steps and "
end
end
if y == 1 then
if y == 1 then
intro = intro .. "1 small step "
intro = intro .. "1 small step "
else
else
intro = intro .. n .. " small steps "
intro = intro .. y .. " small steps "
end
end
if n == 2 then
if n == 2 then

Revision as of 06:55, 27 May 2023

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

This module automatically fills in an introduction for MOS scales. It clarifies the equave, numbers of long and short steps, and range of generators that produce it.

Introspection summary for Module:MOS intro 
Functions provided (3)
Line Function Params
9 parse_entries (unparsed)
18 mos_intro_sentence (input_mos, other_names)
150 mos_intro (invokable) (frame)
Lua modules required (4)
Variable Module Functions used
et Module:ET new
cents
mos Module:MOS new
as_string
bright_gen
parse
rat Module:Rational gcd
cents
as_ratio
utils Module:Utils _round_dec

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


local mos = require('Module:MOS')
local rat = require('Module:Rational')
local utils = require('Module:Utils')
local et = require('Module:ET')
local utils = require('Module:Utils')
local p = {}

-- Helper function that parses entries from a semicolon-delimited string and returns them in an array
function p.parse_entries(unparsed)
	local parsed = {}
	for entry in string.gmatch(unparsed, '([^;]+)') do
		table.insert(parsed, entry)		-- Add to array
	end
	return parsed
end

-- Function that creates a mos intro sentence, given a mos
function p.mos_intro_sentence(input_mos, other_names)
	local input_mos = input_mos or mos.new(4, 5, 3)
	local other_names = other_names or "name1; name2; name3"
	
	-- Get the step counts and number of periods
	local nL = input_mos.nL			-- Number of large steps per equave
	local ns = input_mos.ns			-- Number of small steps per equave
	local n = rat.gcd(nL, ns)		-- Number of periods
	local x = round(nL / n)			-- Number of large steps per period
	local y = round(ns / n)			-- Number of small steps per period
	
	-- Get the equave as a ratio and in cents
	local equave = input_mos.equave
	local equave_in_cents = rat.cents(equave)

	-- Get the period in cents
	local period_in_cents = equave_in_cents / n
	
	-- Get the scalesig
	local scale_sig = mos.as_string(input_mos)
	
	-- Get all the mos's names, starting with tamnams names if applicable
	-- Some mosses have two tamnams names, so it's necessary to tokenize it
	local tamnams_name = mos.tamnams_name[scale_sig] or ""
	local mos_names = p.parse_entries(tamnams_name)
	local other_names_tokenized = p.parse_entries(other_names)
	
	-- Combine the two arrays
	for i = 1, #other_names_tokenized do
		mos_names[#mos_names + 1] = other_names_tokenized[i]
	end
	
	-- Get the eds (ets) corresponding to the collapsed and equalized mosses
	local collapsed_et = et.new(nL, input_mos.equave)
	local equalized_et = et.new(nL + ns, input_mos.equave)
	
	-- Get the sizes of the generator for the collapsed and equalized et in steps
	-- These are used to calculate cent values for the generators
	local generator = mos.bright_gen(input_mos)
	local gen_collapsed_in_steps = generator["L"]
	local gen_equalized_in_steps = generator["L"] + generator["s"]
	
	-- Is the mos octave-equivalent or non-octave?
	local is_octave_equivalent = equave_in_cents == 1200
	
	-- How many places should cent values be rounded to?
	local round = 3
	
	-- Create the intro string starting with the scale
	local intro = "'''" .. scale_sig .. "'''"
	
	-- Add the mos names, if any
	if #mos_names == 1 then
		intro = intro .. ", also called '''" .. mos_names[1] .. "''', is a"
	elseif #mos_names == 2 then
		intro = intro .. ", also called '''" .. mos_names[1] .. "''' or '''" .. mos_names[2] .. "''', is a"
	elseif #mos_names > 2 then
		intro = intro .. ", also called "
		for i = 1, #mos_names - 1 do
			intro = intro .. "'''" .. mos_names[i] .. "''', "
		end
		intro = intro .. "or '''" .. mos_names[#mos_names] .. "''', is a"
	else
		intro = intro .. " is a"
	end
	
	-- Add whether it's non-octave
	if is_octave_equivalent then
		intro = intro .. " [[moment of symmetry]] scale consisting of "
	else
		intro = intro .. " [[non-octave]] [[moment of symmetry]] scale consisting of "
	end
	
	-- Add the step counts per period
	-- Determine where "steps" should be plural or singular, as well
	if nL == 1 then
		intro = intro .. "1 large step and "
	else
		intro = intro .. nL .. " large steps and "
	end
	if ns == 1 then
		intro = intro .. "1 small step,"
	else
		intro = intro .. ns .. " small steps,"
	end
	
	-- Add the number of repetitions
	-- If multi-period, determine whether "steps" should be plural or singular, as well
	if n == 1 then
		intro = intro .. " repating every "
	else
		if x == 1 then
			intro = intro .. " with a period of 1 large step and "
		else
			intro = intro .. " with a period of " .. x .. " large steps and "
		end
		if y == 1 then
			intro = intro .. "1 small step "
		else
			intro = intro .. y .. " small steps "
		end
		if n == 2 then
			intro = intro .. "that repeats twice every "
		else
			intro = intro .. "that repeats " .. n .. " times every "
		end
	end
	
	-- Add the equivalence interval
	if is_octave_equivalent then
		intro = intro .. "[[octave]]"
	else
		intro = intro .. "interval of [[" .. rat.as_ratio(equave) .. "]] (" .. utils._round_dec(equave_in_cents, round) .. "¢)"
	end
	
	-- Add the period (this is a pun)
	if n == 1 then
		intro = intro .. ". "
	else
		intro = intro .. ", or every " .. utils._round_dec(period_in_cents, round) .. "¢. "
	end
	
	-- Add the generator range
	local collapsed_gen_in_cents = utils._round_dec(et.cents(equalized_et, gen_equalized_in_steps), round)
	local equalized_gen_in_cents = utils._round_dec(et.cents(collapsed_et, gen_collapsed_in_steps), round)
	intro = intro .. "This scale is made using a [[generator]] ranging from " .. collapsed_gen_in_cents
	intro = intro .. "¢ to " .. equalized_gen_in_cents .. "¢."
	
	return intro
end

-- Function for use with a template
function p.mos_intro(frame)
	-- Get and parse the the mos's scale signature, in the form xL ys or xL ys <p/q>
	local input_mos = mos.parse(frame.args['Scale Signature']) or mos.new(5, 2, 2)
	local other_names = frame.args['Other Names'] or ""
	
	return p.mos_intro_sentence(input_mos, other_names)
end

return p