Module:MOS intro: Difference between revisions

From Xenharmonic Wiki
Jump to navigation Jump to search
Ganaram inukshuk (talk | contribs)
mNo edit summary
Ganaram inukshuk (talk | contribs)
Intro text includes dark generator range, following the bright generator
Line 16: Line 16:
-- Function that creates a mos intro sentence, given a mos and any other names
-- Function that creates a mos intro sentence, given a mos and any other names
function p.mos_intro_sentence(input_mos, other_names)
function p.mos_intro_sentence(input_mos, other_names)
local input_mos = input_mos or mos.new(4, 8, 3)
local input_mos = input_mos or mos.new(5, 2)
local other_names = other_names or "name1; name2; name3"
local other_names = other_names or "name1; name2; name3"
Line 142: Line 142:
end
end
-- Add the generator range
-- Add the generator range (for bright generator)
local collapsed_gen_in_cents = et.cents(equalized_et, gen_equalized_in_steps)
local collapsed_gen_in_cents = et.cents(collapsed_et, gen_collapsed_in_steps)
local equalized_gen_in_cents = et.cents(collapsed_et, gen_collapsed_in_steps)
local equalized_gen_in_cents = et.cents(equalized_et, gen_equalized_in_steps)
intro = intro .. "This scale is made using a [[generator]] ranging from " .. utils._round_dec(collapsed_gen_in_cents, round)
intro = intro .. "This scale is made using a [[generator]] ranging from " .. utils._round_dec(equalized_gen_in_cents, round)
intro = intro .. "¢ to " .. utils._round_dec(equalized_gen_in_cents, round) .. "¢."
intro = intro .. "¢ to " .. utils._round_dec(collapsed_gen_in_cents, round) .. "¢, "
-- Add the generator range (for dark generator)
-- The dark generator range is the complement of the bright generator's extremes
intro = intro .. "or from " .. utils._round_dec(equave_in_cents - collapsed_gen_in_cents, round)
intro = intro .. "¢ to " .. utils._round_dec(equave_in_cents - equalized_gen_in_cents, round) .. "¢."
return intro
return intro

Revision as of 22:24, 31 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
8 parse_entries (unparsed)
17 mos_intro_sentence (input_mos, other_names)
159 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 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 and any other names
function p.mos_intro_sentence(input_mos, other_names)
	local input_mos = input_mos or mos.new(5, 2)
	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)
	
	-- Tokenize the other names passed in, then add them to the mos names
	local other_names_tokenized = p.parse_entries(other_names)
	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
		-- Only one mos name
		intro = intro .. ", also called '''" .. mos_names[1] .. "''', is a"
	elseif #mos_names == 2 then
		-- Two mos names (name and alternate-name)
		intro = intro .. ", also called '''" .. mos_names[1] .. "''' or '''" .. mos_names[2] .. "''', is a"
	elseif #mos_names > 2 then
		-- Three or more mos names (name, alternate-name, and other-alternate-name)
		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
		-- No names
		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
		intro = intro .. " with a [[period]] of "
		if x == 1 then
			intro = intro .. "1 large step and "
		else
			intro = intro .. 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 (for bright generator)
	local collapsed_gen_in_cents = et.cents(collapsed_et, gen_collapsed_in_steps)
	local equalized_gen_in_cents = et.cents(equalized_et, gen_equalized_in_steps)
	intro = intro .. "This scale is made using a [[generator]] ranging from " .. utils._round_dec(equalized_gen_in_cents, round)
	intro = intro .. "¢ to " .. utils._round_dec(collapsed_gen_in_cents, round) .. "¢, "
	
	-- Add the generator range (for dark generator)
	-- The dark generator range is the complement of the bright generator's extremes
	intro = intro .. "or from " .. utils._round_dec(equave_in_cents - collapsed_gen_in_cents, round)
	intro = intro .. "¢ to " .. utils._round_dec(equave_in_cents - equalized_gen_in_cents, round) .. "¢."
	
	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