Module:MOS intro: Difference between revisions
m Minor rewording to meet current (personal) coding standards |
Broke up the function that generates the intro into several helper functions to make it easier to add additional info |
||
| Line 14: | Line 14: | ||
end | end | ||
-- | -- Helper function | ||
function p. | -- Lists out names, with each name being bold | ||
local | function p.mos_intro_list_names(mos_names, conjunction) | ||
local | local mos_names = mos_names or { "name1", "name2", "name3" } | ||
local conjunction = conjunction or "and" | |||
-- | -- List the names | ||
local | local names_list = "" | ||
if #mos_names == 1 then | |||
-- Only one mos name | |||
names_list = string.format("'''%s'''", mos_names[1]) | |||
elseif #mos_names == 2 then | |||
-- Two mos names (name and alternate-name) | |||
names_list = string.format("'''%s''' %s '''%s'''", mos_names[1], conjunction, mos_names[2]) | |||
elseif #mos_names > 2 then | |||
-- Three or more mos names | |||
for i = 1, #mos_names - 1 do | |||
names_list = names_list .. string.format("'''%s''', ", mos_names[i]) | |||
end | |||
names_list = names_list .. string.format("%s '''%s'''", conjunction, mos_names[#mos_names]) | |||
else | |||
-- No names | |||
names_list = "" | |||
end | |||
return names_list | |||
end | |||
-- Helper function | |||
local | -- Introduces the mos by its scale sig and names | ||
function p.mos_intro_scalesig_and_tamnams_names(input_mos, tamnams_name, other_names) | |||
local input_mos = input_mos or mos.new(5, 2) | |||
local tamnams_name = tamnams_name or "diatonic" | |||
local other_names = other_names or "other-name" | |||
-- Get the scalesig | -- Get the scalesig | ||
| Line 37: | Line 53: | ||
-- Get all the mos's names, starting with tamnams names if applicable | -- Get all the mos's names, starting with tamnams names if applicable | ||
local tamnams_names_list = p.mos_intro_list_names(p.parse_entries(tamnams_name), "and") | |||
local | local other_names_list = p.mos_intro_list_names(p.parse_entries(other_names), "or") | ||
local | |||
-- Construct the sentence | |||
local sentence = string.format("'''%s''' ", scale_sig) | |||
-- | -- Add names | ||
if tamnams_names_list ~= "" and if_others_names_list ~= "" then | |||
-- There are both tamnams names and alternate names | |||
sentence = sentence .. string.format("([[TAMNAMS]] name %s; also called %s)", tamnams_names_list, other_names_list) | |||
elseif tamnams_names_list ~= "" and if_others_names_list == "" then | |||
-- There are only tamnams names | |||
sentence = sentence .. string.format("([[TAMNAMS]] name %s)", tamnams_names_list) | |||
elseif tamnams_names_list == "" and if_others_names_list ~= "" then | |||
-- There are no tamnams names but there are alternate names | |||
sentence = sentence .. string.format("(also called %s)", other_names_list) | |||
end | end | ||
-- | return sentence | ||
end | |||
local | |||
-- Helper function | |||
-- Introduces the mos by its step counts and number of periods | |||
-- This is meant to immediately follow the sentence provided by: | |||
-- - mos_intro_tamnams_names() | |||
function p.mos_intro_steps_and_periods(input_mos) | |||
local input_mos = input_mos or mos.new(3, 6, 3) | |||
-- Get the | -- Get the equave and the equave in cents | ||
local equave = input_mos.equave | |||
local | local equave_in_cents = rat.cents(equave) | ||
local | local equave_as_ratio = rat.as_ratio(equave) | ||
-- | -- Get the step counts and number of periods | ||
local | local nL = input_mos.nL -- Number of large steps per equave | ||
local ns = input_mos.ns -- Number of small steps per equave | |||
local n = utils._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 | |||
-- | -- Construct the sentence | ||
sentence = " is " | |||
-- | -- Is the scale nonoctave? | ||
if equave_in_cents == 1200 then | |||
sentence = sentence .. string.format("an [[octave-equivalent]] [[moment of symmetry]] scale") | |||
if | |||
else | else | ||
sentence = sentence .. string.format("a [[non-octave]], [[%s]]-equivalent [[moment_of_symmetry]] scale", equave_as_ratio) | |||
end | end | ||
-- | -- What are the step counts? Should the word "step" contain an s? | ||
if | local s_nl = "" | ||
local s_ns = "" | |||
if nL ~= 1 then | |||
s_nl = "s" | |||
end | |||
if ns ~= 1 then | |||
s_ns = "s" | |||
end | end | ||
sentence = sentence .. string.format(" containing %d large step%s and %d small step%s", nL, s_nl, ns, s_ns) | |||
-- | -- How does it repeat? | ||
local s_x = "" | |||
if | local s_y = "" | ||
local repetition = "" | |||
if x ~= 1 then | |||
s_x = "s" | |||
end | |||
if y ~= 1 then | |||
s_y = "s" | |||
end | |||
if n == 2 then | |||
repetition = "twice" | |||
elseif n > 2 then | |||
repetition = string.format("%d times", n) | |||
end | end | ||
if | if n == 1 and equave_in_cents == 1200 then | ||
sentence = sentence .. string.format(" and repeating every [[octave]].") | |||
elseif n == 1 and equave_in_cents ~= 1200 then | |||
sentence = sentence .. string.format(" and repeating every interval of %s (%.3f¢).", equave_as_ratio, equave_in_cents) | |||
elseif n ~= 1 and equave_in_cents == 1200 then | |||
sentence = sentence .. string.format(", with a [[period]] of %d large step%s and %d small step%s", x, s_x, y, s_y) | |||
sentence = sentence .. string.format(" that repeats every %.3f¢, or %s every [[octave]].", equave_in_cents / n, repetition) | |||
elseif n ~= 1 and equave_in_cents ~= 1200 then | |||
sentence = sentence .. string.format(", with a [[period]] of %d large step%s and %d small step%s", x, s_x, y, s_y) | |||
sentence = sentence .. string.format(" that repeats every %.3f¢, or %s every interval of %s (%.3f¢).", equave_in_cents / n, repetition, equave_as_ratio, equave_in_cents) | |||
end | end | ||
-- | return sentence | ||
-- | end | ||
-- Helper function | |||
-- Calculates the generator ranges of the mos | |||
function p.mos_intro_generator_ranges(input_mos) | |||
local input_mos = input_mos or mos.new(5, 2) | |||
-- 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 = utils._gcd(nL, ns) -- Number of periods | |||
-- Get the equave as a ratio and in cents | |||
local equave = input_mos.equave | |||
local equave_in_cents = rat.cents(equave) | |||
-- 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 bright generator for the collapsed and equalized et in steps | |||
-- These are used to calculate cent values for the generators | |||
-- The values for the dark generator are the period complements | |||
local generator = mos.bright_gen(input_mos) | |||
local gen_collapsed_in_steps = generator["L"] | |||
local gen_equalized_in_steps = generator["L"] + generator["s"] | |||
local bright_gen_max = et.cents(collapsed_et, gen_collapsed_in_steps) | |||
local bright_gen_min = et.cents(equalized_et, gen_equalized_in_steps) | |||
local dark_gen_min = equave_in_cents / n - bright_gen_max | |||
local dark_gen_max = equave_in_cents / n - bright_gen_min | |||
local sentence = string.format("[[Generating intervals|generator]] that produce this scale range from %.3f¢ to %.3f¢, or from %.3f¢ to %.3f¢.", bright_gen_min, bright_gen_max, dark_gen_min, dark_gen_max) | |||
-- | return sentence | ||
end | |||
-- Function that creates a mos intro, given a mos and any other names | |||
-- Intro (or lead section) consists of multiple sentences, and each is called individually | |||
function p.mos_intro(input_mos, other_names) | |||
local input_mos = input_mos or mos.new(5, 2) | |||
local other_names = other_names or "name1; name2; name3" | |||
-- | -- Get tamnams names | ||
local | local tamnams_name = mos.tamnams_name[scale_sig] or "" | ||
-- | -- Construct the sentence | ||
local scalesig_and_names = p.mos_intro_scalesig_and_tamnams_names(input_mos, tamnams_name, other_names) | |||
local steps_and_periods = p.mos_intro_steps_and_periods(input_mos) | |||
local gens = p.mos_intro_generator_ranges(input_mos) | |||
return | return string.format("%s %s %s", scalesig_and_names, steps_and_periods, gens) | ||
end | end | ||