Module:MOS mode degrees: Difference between revisions
Jump to navigation
Jump to search
Added cell coloring to indicate which cells are perfect intervals (default color), the large size (light yellow), the small size (light blue), or an altered size (light red) |
ArrowHead294 (talk | contribs) mNo edit summary |
||
| (118 intermediate revisions by 3 users not shown) | |||
| Line 1: | Line 1: | ||
local p = {} | local p = {} | ||
local mos = require("Module:MOS") | |||
local tamnams = require("Module:TAMNAMS") | |||
local tip = require("Module:Template input parse") | |||
local yesno = require("Module:Yesno") | |||
-- | -- TODO | ||
-- | -- - Split off modmos mode degrees as a separate template | ||
- | |||
-- | -- Global variables for cell colors | ||
-- | -- Colors are as follows: | ||
-- - Orange and blue for small and large sizes, respectively | |||
-- - Darker colors for altered scale degrees | |||
-- - No color for period intervals | |||
p.cell_color_none = "NONE" -- For cells that don't have a color (default cell color applies) | |||
p.cell_color_perfect_size = "NONE" -- Only applies for periods, including the root and equave | |||
p.cell_color_lg_altered_size = "#BDD7EE" | |||
p.cell_color_large_size = "#DDEBF7" | |||
p.cell_color_small_size = "#FCE4D6" | |||
p.cell_color_sm_altered_size = "#F8CBAD" | |||
-- Finds the row color for a single cell | |||
function p.cell_color(interval, input_mos) | |||
local interval = interval or {["L"] = 3, ["s"] = 1} | |||
-- | |||
function p. | |||
local | |||
local input_mos = input_mos or mos.new(5, 2) | local input_mos = input_mos or mos.new(5, 2) | ||
local period_step_count = mos.period_step_count(input_mos) | |||
local interval_step_count = mos.interval_step_count(interval) | |||
local chroma_count = mos.interval_chroma_count(interval, input_mos) | |||
local | |||
local | |||
local is_period_interval = interval_step_count % period_step_count == 0 | |||
local | |||
local color = p.cell_color_none | |||
if is_period_interval then | |||
if chroma_count > 0 then | |||
color = p.cell_color_lg_altered_size | |||
elseif chroma_count == 0 then | |||
color = p.cell_color_none | |||
elseif chroma_count < 0 then | |||
color = p.cell_color_sm_altered_size | |||
if | |||
if | |||
elseif | |||
elseif | |||
end | end | ||
else | else | ||
if chroma_count > 0 then | |||
color = p.cell_color_lg_altered_size | |||
elseif chroma_count == 0 then | |||
color = p.cell_color_large_size | |||
elseif chroma_count == -1 then | |||
color = p.cell_color_small_size | |||
if | elseif chroma_count < -1 then | ||
color = p.cell_color_sm_altered_size | |||
elseif | |||
end | end | ||
end | end | ||
return color | |||
return | |||
end | end | ||
-- Create a table of a mos's degrees | -- Create a table of a mos's degrees | ||
function p. | -- If a step pattern is provided, it's assumed to be that of a modmos | ||
function p._mos_mode_degrees(input_mos, mos_prefix, is_collapsed, step_pattern) | |||
local is_true_mos = step_pattern == nil | |||
local input_mos = input_mos or mos.new(5, 2) | local input_mos = input_mos or mos.new(5, 2) | ||
local mos_prefix = mos_prefix or "mos" | local mos_prefix = mos_prefix or "mos" | ||
local | local is_collapsed = is_collapsed == true | ||
-- Get the modes | -- Get the modes as strings and step vectors | ||
local | local step_patterns = {} | ||
local step_matrices = {} | |||
if is_true_mos then | |||
step_patterns = mos.modes_by_brightness(input_mos) | |||
step_matrices = mos.modes_to_step_matrices(input_mos) | |||
else | |||
step_patterns = mos.mode_rotations(step_pattern) | |||
step_matrices = mos.mode_rotations_to_step_matrices(step_pattern) | |||
end | |||
-- Get the scale sig | -- Get the scale sig | ||
local scale_sig = mos.as_string(input_mos) | local scale_sig = mos.as_string(input_mos) | ||
-- Equave step count; needed for degree column count | |||
local equave_step_count = mos.equave_step_count(input_mos) | |||
-- Get the brightness and rotational orderings | -- Get the brightness (UDP) and rotational orderings (CPOs). | ||
-- Also produce default mode names if set to do so. | |||
local udps = {} | |||
local cpos = {} | |||
-- | if is_true_mos then | ||
local | -- Get UDPs and CPOs | ||
udps = tamnams.mos_mode_udps(input_mos) | |||
-- Get | cpos = tamnams.mos_mode_cpos(input_mos) | ||
else | |||
-- Modmos udps require a mosabbrev; this is forced to be "m" since some | |||
-- abbrevs are tooo long. Get both the names for the closest-bright and | |||
-- closest-dark mode. If they're the same, only one name will be used; | |||
-- if not, both are used. | |||
-- The CPOs of a modmos are simply 1 to n (n is the mode count). | |||
local udps_closest_bright = tamnams.mode_rotation_udps(step_pattern, input_mos, "m", true) | |||
local udps_closest_dark = tamnams.mode_rotation_udps(step_pattern, input_mos, "m", false) | |||
for i = 1, #udps_closest_bright do | |||
if udps_closest_bright[i] == udps_closest_dark[i] then | |||
table.insert(udps, udps_closest_bright[i]) | |||
for | |||
if | |||
else | else | ||
table.insert(udps, string.format("%s<br />%s", udps_closest_bright[i], udps_closest_dark[i])) | |||
end | end | ||
table.insert(cpos, i) | |||
end | end | ||
end | end | ||
-- | -- Create table | ||
result = | local result = "{| class=\"wikitable sortable mw-collapsible center-2 center-3" | ||
.. (is_collapsed and " mw-collapsed\"" or "\"") .. "\n" | |||
-- | |||
-- | -- Table's title | ||
-- If it's for a modmos, add the step pattern | |||
result = result .. "|+ style=\"font-size: 105%; white-space: nowrap;\" | " .. string.format("Scale degrees of the modes of %s", scale_sig) | |||
.. (is_true_mos and "\n" or string.format(" (%s)\n", step_pattern)) | |||
.. "|-\n" | |||
-- Add table headers for first row | -- Add table headers for first row | ||
result = result .. | result = result | ||
.. "! rowspan=\"2\" | UDP" .. (is_true_mos and "\n" or " and<br />alterations\n") -- If modmos, add "and alterations" string | |||
.. "! rowspan=\"2\" | Cyclic<br />order\n" | |||
.. "! rowspan=\"2\" | Step<br />pattern\n" | |||
-- Add header for scale degrees | -- Add header for scale degrees | ||
result = result .. string.format( | result = result .. string.format("! colspan=\"%d\" class=\"unsortable\" | Scale degree (%sdegree)\n", #step_matrices[1], mos_prefix) | ||
-- Add second row of headers | -- Add second row of headers | ||
result = result .. "|-\n" | result = result .. "|- class=\"unsortable\"\n" | ||
for i = 1, | .. "! 0" | ||
result = result .. string.format( | for i = 1, #step_patterns[1] do | ||
result = result .. string.format("\n! %d", i) | |||
end | end | ||
result = result .. "\n" | |||
-- Add table contents | -- Add table contents | ||
for i = 1, # | for i = 1, #step_patterns do | ||
result = result .. "|-\n" | result = result .. "|-\n" | ||
-- Add brightness order (as UDP), rotational order, and step pattern | -- Add brightness order (as UDP), rotational order, and step pattern | ||
.. string.format("| %s\n| %s\n| %s\n", udps[i], cpos[i], step_patterns[i]) | |||
-- Add scale degrees with cell coloring | -- Add scale degrees with cell coloring | ||
for j = 1, # | for j = 1, #step_matrices[i] do | ||
local current_interval = step_matrices[i][j] | |||
local degree_quality = tamnams.decode_quality(current_interval, input_mos, "shortened") | |||
local cell_color = p.cell_color(current_interval, input_mos) | |||
local style_code = (cell_color == p.cell_color_none and "" or string.format("style=\"background: %s;\" | ", cell_color)) | |||
result = result .. string.format("| %s%s\n", style_code, degree_quality) | |||
end | end | ||
end | end | ||
| Line 711: | Line 157: | ||
return result | return result | ||
end | end | ||
-- Function to be called as part of a template | -- Function to be called as part of a template | ||
function p. | function p.mos_mode_degrees(frame) | ||
-- | -- Get args | ||
local input_mos = mos.parse(frame.args[ | local input_mos = mos.parse(frame.args["Scale Signature"]) | ||
local mos_prefix = frame.args["MOS Prefix"] | |||
local step_pattern = frame.args["MODMOS Step Pattern"] | |||
local mode_names_unparsed = frame.args["Mode Names"] | |||
-- Parse debugging option | |||
local debugg = yesno(frame.args["debug"]) | |||
-- Get the scale sig; for calculating the mos prefix | -- Get the scale sig; for calculating the mos prefix | ||
local scale_sig = mos.as_string(input_mos) | local scale_sig = mos.as_string(input_mos) | ||
-- | -- Verify mosprefix | ||
mos_prefix = tamnams.verify_prefix(input_mos, mos_prefix) | |||
-- Get the mode names | -- Get the mode names | ||
local mode_names = nil | local mode_names = nil | ||
-- Default names for 5L 2s modes | -- Default names for 5L 2s modes and select modmosses. | ||
if scale_sig == "5L 2s" | -- Names are based on whichever mode is returnd by UDP closest-mode search, | ||
-- with common names added wherever applicable. Sources include: | |||
-- - https://www.jazz-guitar-licks.com/ and likely others | |||
-- - Whatever Wikipedia has cited for the Neapolitan scales | |||
-- NOTE: these names can be overridden if they don't suffice. | |||
if scale_sig == "5L 2s" then | |||
if step_pattern == "LsLLsAs" then | |||
-- Modes of harmonic minor | |||
-- Closest-mode search always returns one name | |||
mode_names = { | |||
"Harmonic minor<br />(Aeolian ♮7)", | |||
"Locrian ♮6", | |||
"Ionian augmented<br />(Ionian ♯5)", | |||
"Dorian ♯4", | |||
"Phrygian dominant<br />(Phrygian ♮3)", | |||
"Lydian ♯2", | |||
"Altered diminished<br />(Locrian ♭4 𝄫7)", | |||
} | |||
elseif step_pattern == "LLsLsAs" then | |||
-- Modes of harmonic major | |||
-- Closest-mode search always returns one name | |||
mode_names = { | |||
"Harmonic major<br />(Ionian ♭6)", | |||
"Dorian ♭5", | |||
"Phrygian ♭4", | |||
"Lydian ♭3", | |||
"Mixolydian ♭2", | |||
"Lydian augmented ♯2<br />(Lydian ♯2 ♯5)", | |||
"Locrian 𝄫7", | |||
} | |||
elseif step_pattern == "LsLLLLs" then | |||
-- Modes of melodic minor | |||
-- Closest-mode search sometimes returns two names | |||
mode_names = { | |||
"Melodic minor<br />(Ionian ♭3, Dorian ♮7)", | |||
"Dorian ♭2, Phrygian ♮6", | |||
"Lydian augmented<br />(Lydian ♯5)", | |||
"Lydian dominant<br />(Lydian ♭7, Mixolydian ♯4)", | |||
"Mixolydian ♭6, Aeolian ♮3", | |||
"Half-diminished<br />(Aeolian ♭5, Locrian ♮2)", | |||
"Altered, Altered dominant<br />(Locrian ♭4)", | |||
} | |||
elseif step_pattern == "sLLLLLs" then | |||
-- Modes of Neapolitan major | |||
-- Closest-mode search sometimes returns two names | |||
mode_names = { | |||
"Neapolitan major<br />(Ionian ♭2 ♭3, Phrigian ♮6 ♮7)", | |||
"Lydian augmented ♯6<br />(Lydian ♯5 ♯6)", | |||
"Lydian augmented dominant<br />(Lydian ♯5 ♭7, Mixolydian ♯4 ♯5)", | |||
"Lydian minor<br />(Lydian ♭6 ♭7, Aeolian ♮3 ♯4)", | |||
"Major locrian<br />(Mixolydian ♭5 ♭6, Locrian ♮2 ♮3)", | |||
"Altered dominant ♮2<br />(Aeolian ♭4 ♭5, Locrian ♮2, ♭4)", | |||
"Altered dominant 𝄫3<br />(Locrian 𝄫3 ♭4)", | |||
} | |||
elseif step_pattern == "sLLLsAs" then | |||
-- Modes of Neapolitan minor | |||
-- Closest-mode search always returns one name | |||
mode_names = { | |||
"Neapolitan minor<br />(Phrygian ♮7)", | |||
"Lydian ♯6", | |||
"Mixolydian augmented<br />(Mixolydian ♯5)", | |||
"Aeolian ♯4", | |||
"Locrian dominant<br />(Locrian ♮3)", | |||
"Ionian ♯2", | |||
"Altered diminished 𝄫3<br />(Locrian 𝄫3 ♭4 𝄫7)", | |||
} | |||
elseif step_pattern == "sAsLsAs" then | |||
-- Modes of double harmonic | |||
-- Closest-mode search sometimes returns two names | |||
mode_names = { | |||
"Double harmonic<br />(Ionian ♭2 ♭6, Phrygian ♮3 ♮7)", | |||
"Lydian ♯2 ♯6", | |||
"Altered ♮5 𝄫6<br />(Phrygian ♭4 𝄫7)", | |||
"Double harmonic minor<br />(Lydian ♭3 ♭6, Aeolian ♯4 ♮7)", | |||
"Mixolydian ♭2 ♭5, Locrian ♮3 ♮6", | |||
"Ionian augmented ♯2<br />(Ionian ♯2 ♯5)", | |||
"Locrian 𝄫3 𝄫7", | |||
} | |||
elseif #step_pattern == 0 then | |||
-- True-mos modes | |||
mode_names = { | |||
"Lydian", | |||
"Ionian (major)", | |||
"Mixolydian", | |||
"Dorian", | |||
"Aeolian (minor)", | |||
"Phrygian", | |||
"Locrian" | |||
} | |||
end | |||
end | end | ||
-- If mode names are given, use those instead | -- If mode names are given, use those instead | ||
if # | -- If using default mode names (scalesig+udp), those names are auto-added by the relevant function | ||
mode_names = | local use_default_names = false | ||
if #mode_names_unparsed ~= 0 then | |||
if mode_names_unparsed == "Default" then | |||
use_default_names = true | |||
else | |||
mode_names = tip.parse_entries(mode_names_unparsed) | |||
end | |||
end | end | ||
-- Check if the table should start collapsed | |||
local is_collapsed = yesno(frame.args["Collapsed"], false) | |||
-- If a modmos step pattern was never provided, call the function mos_mode_degrees | -- If a modmos step pattern was never provided, call the function mos_mode_degrees | ||
| Line 759: | Line 289: | ||
local result = "" | local result = "" | ||
if step_pattern == "" then | if step_pattern == "" then | ||
result = p. | result = p._mos_mode_degrees(input_mos, mos_prefix, is_collapsed) | ||
elseif #step_pattern == input_mos.nL + input_mos.ns then | --elseif #step_pattern == input_mos.nL + input_mos.ns then | ||
result = p. | else | ||
result = p._mos_mode_degrees(input_mos, mos_prefix, is_collapsed, step_pattern) | |||
end | end | ||
return result | -- Debugger option | ||
if debugg == true then | |||
result = "<syntaxhighlight lang=\"wikitext\">" .. result .. "</syntaxhighlight>" | |||
end | |||
return frame:preprocess(result) | |||
end | end | ||
return p | return p | ||
Latest revision as of 12:43, 1 June 2025
- This module should not be invoked directly; use its corresponding template instead: Template:MOS mode degrees.
This module creates a table of the scale degrees for each mode of a MOS or MODMOS scale.
| Introspection summary for Module:MOS mode degrees | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||||||||||||||||||||
No function descriptions were provided. The Lua code may have further information.
local p = {}
local mos = require("Module:MOS")
local tamnams = require("Module:TAMNAMS")
local tip = require("Module:Template input parse")
local yesno = require("Module:Yesno")
-- TODO
-- - Split off modmos mode degrees as a separate template
-- Global variables for cell colors
-- Colors are as follows:
-- - Orange and blue for small and large sizes, respectively
-- - Darker colors for altered scale degrees
-- - No color for period intervals
p.cell_color_none = "NONE" -- For cells that don't have a color (default cell color applies)
p.cell_color_perfect_size = "NONE" -- Only applies for periods, including the root and equave
p.cell_color_lg_altered_size = "#BDD7EE"
p.cell_color_large_size = "#DDEBF7"
p.cell_color_small_size = "#FCE4D6"
p.cell_color_sm_altered_size = "#F8CBAD"
-- Finds the row color for a single cell
function p.cell_color(interval, input_mos)
local interval = interval or {["L"] = 3, ["s"] = 1}
local input_mos = input_mos or mos.new(5, 2)
local period_step_count = mos.period_step_count(input_mos)
local interval_step_count = mos.interval_step_count(interval)
local chroma_count = mos.interval_chroma_count(interval, input_mos)
local is_period_interval = interval_step_count % period_step_count == 0
local color = p.cell_color_none
if is_period_interval then
if chroma_count > 0 then
color = p.cell_color_lg_altered_size
elseif chroma_count == 0 then
color = p.cell_color_none
elseif chroma_count < 0 then
color = p.cell_color_sm_altered_size
end
else
if chroma_count > 0 then
color = p.cell_color_lg_altered_size
elseif chroma_count == 0 then
color = p.cell_color_large_size
elseif chroma_count == -1 then
color = p.cell_color_small_size
elseif chroma_count < -1 then
color = p.cell_color_sm_altered_size
end
end
return color
end
-- Create a table of a mos's degrees
-- If a step pattern is provided, it's assumed to be that of a modmos
function p._mos_mode_degrees(input_mos, mos_prefix, is_collapsed, step_pattern)
local is_true_mos = step_pattern == nil
local input_mos = input_mos or mos.new(5, 2)
local mos_prefix = mos_prefix or "mos"
local is_collapsed = is_collapsed == true
-- Get the modes as strings and step vectors
local step_patterns = {}
local step_matrices = {}
if is_true_mos then
step_patterns = mos.modes_by_brightness(input_mos)
step_matrices = mos.modes_to_step_matrices(input_mos)
else
step_patterns = mos.mode_rotations(step_pattern)
step_matrices = mos.mode_rotations_to_step_matrices(step_pattern)
end
-- Get the scale sig
local scale_sig = mos.as_string(input_mos)
-- Equave step count; needed for degree column count
local equave_step_count = mos.equave_step_count(input_mos)
-- Get the brightness (UDP) and rotational orderings (CPOs).
-- Also produce default mode names if set to do so.
local udps = {}
local cpos = {}
if is_true_mos then
-- Get UDPs and CPOs
udps = tamnams.mos_mode_udps(input_mos)
cpos = tamnams.mos_mode_cpos(input_mos)
else
-- Modmos udps require a mosabbrev; this is forced to be "m" since some
-- abbrevs are tooo long. Get both the names for the closest-bright and
-- closest-dark mode. If they're the same, only one name will be used;
-- if not, both are used.
-- The CPOs of a modmos are simply 1 to n (n is the mode count).
local udps_closest_bright = tamnams.mode_rotation_udps(step_pattern, input_mos, "m", true)
local udps_closest_dark = tamnams.mode_rotation_udps(step_pattern, input_mos, "m", false)
for i = 1, #udps_closest_bright do
if udps_closest_bright[i] == udps_closest_dark[i] then
table.insert(udps, udps_closest_bright[i])
else
table.insert(udps, string.format("%s<br />%s", udps_closest_bright[i], udps_closest_dark[i]))
end
table.insert(cpos, i)
end
end
-- Create table
local result = "{| class=\"wikitable sortable mw-collapsible center-2 center-3"
.. (is_collapsed and " mw-collapsed\"" or "\"") .. "\n"
-- Table's title
-- If it's for a modmos, add the step pattern
result = result .. "|+ style=\"font-size: 105%; white-space: nowrap;\" | " .. string.format("Scale degrees of the modes of %s", scale_sig)
.. (is_true_mos and "\n" or string.format(" (%s)\n", step_pattern))
.. "|-\n"
-- Add table headers for first row
result = result
.. "! rowspan=\"2\" | UDP" .. (is_true_mos and "\n" or " and<br />alterations\n") -- If modmos, add "and alterations" string
.. "! rowspan=\"2\" | Cyclic<br />order\n"
.. "! rowspan=\"2\" | Step<br />pattern\n"
-- Add header for scale degrees
result = result .. string.format("! colspan=\"%d\" class=\"unsortable\" | Scale degree (%sdegree)\n", #step_matrices[1], mos_prefix)
-- Add second row of headers
result = result .. "|- class=\"unsortable\"\n"
.. "! 0"
for i = 1, #step_patterns[1] do
result = result .. string.format("\n! %d", i)
end
result = result .. "\n"
-- Add table contents
for i = 1, #step_patterns do
result = result .. "|-\n"
-- Add brightness order (as UDP), rotational order, and step pattern
.. string.format("| %s\n| %s\n| %s\n", udps[i], cpos[i], step_patterns[i])
-- Add scale degrees with cell coloring
for j = 1, #step_matrices[i] do
local current_interval = step_matrices[i][j]
local degree_quality = tamnams.decode_quality(current_interval, input_mos, "shortened")
local cell_color = p.cell_color(current_interval, input_mos)
local style_code = (cell_color == p.cell_color_none and "" or string.format("style=\"background: %s;\" | ", cell_color))
result = result .. string.format("| %s%s\n", style_code, degree_quality)
end
end
-- End of table
result = result .. "|}"
return result
end
-- Function to be called as part of a template
function p.mos_mode_degrees(frame)
-- Get args
local input_mos = mos.parse(frame.args["Scale Signature"])
local mos_prefix = frame.args["MOS Prefix"]
local step_pattern = frame.args["MODMOS Step Pattern"]
local mode_names_unparsed = frame.args["Mode Names"]
-- Parse debugging option
local debugg = yesno(frame.args["debug"])
-- Get the scale sig; for calculating the mos prefix
local scale_sig = mos.as_string(input_mos)
-- Verify mosprefix
mos_prefix = tamnams.verify_prefix(input_mos, mos_prefix)
-- Get the mode names
local mode_names = nil
-- Default names for 5L 2s modes and select modmosses.
-- Names are based on whichever mode is returnd by UDP closest-mode search,
-- with common names added wherever applicable. Sources include:
-- - https://www.jazz-guitar-licks.com/ and likely others
-- - Whatever Wikipedia has cited for the Neapolitan scales
-- NOTE: these names can be overridden if they don't suffice.
if scale_sig == "5L 2s" then
if step_pattern == "LsLLsAs" then
-- Modes of harmonic minor
-- Closest-mode search always returns one name
mode_names = {
"Harmonic minor<br />(Aeolian ♮7)",
"Locrian ♮6",
"Ionian augmented<br />(Ionian ♯5)",
"Dorian ♯4",
"Phrygian dominant<br />(Phrygian ♮3)",
"Lydian ♯2",
"Altered diminished<br />(Locrian ♭4 𝄫7)",
}
elseif step_pattern == "LLsLsAs" then
-- Modes of harmonic major
-- Closest-mode search always returns one name
mode_names = {
"Harmonic major<br />(Ionian ♭6)",
"Dorian ♭5",
"Phrygian ♭4",
"Lydian ♭3",
"Mixolydian ♭2",
"Lydian augmented ♯2<br />(Lydian ♯2 ♯5)",
"Locrian 𝄫7",
}
elseif step_pattern == "LsLLLLs" then
-- Modes of melodic minor
-- Closest-mode search sometimes returns two names
mode_names = {
"Melodic minor<br />(Ionian ♭3, Dorian ♮7)",
"Dorian ♭2, Phrygian ♮6",
"Lydian augmented<br />(Lydian ♯5)",
"Lydian dominant<br />(Lydian ♭7, Mixolydian ♯4)",
"Mixolydian ♭6, Aeolian ♮3",
"Half-diminished<br />(Aeolian ♭5, Locrian ♮2)",
"Altered, Altered dominant<br />(Locrian ♭4)",
}
elseif step_pattern == "sLLLLLs" then
-- Modes of Neapolitan major
-- Closest-mode search sometimes returns two names
mode_names = {
"Neapolitan major<br />(Ionian ♭2 ♭3, Phrigian ♮6 ♮7)",
"Lydian augmented ♯6<br />(Lydian ♯5 ♯6)",
"Lydian augmented dominant<br />(Lydian ♯5 ♭7, Mixolydian ♯4 ♯5)",
"Lydian minor<br />(Lydian ♭6 ♭7, Aeolian ♮3 ♯4)",
"Major locrian<br />(Mixolydian ♭5 ♭6, Locrian ♮2 ♮3)",
"Altered dominant ♮2<br />(Aeolian ♭4 ♭5, Locrian ♮2, ♭4)",
"Altered dominant 𝄫3<br />(Locrian 𝄫3 ♭4)",
}
elseif step_pattern == "sLLLsAs" then
-- Modes of Neapolitan minor
-- Closest-mode search always returns one name
mode_names = {
"Neapolitan minor<br />(Phrygian ♮7)",
"Lydian ♯6",
"Mixolydian augmented<br />(Mixolydian ♯5)",
"Aeolian ♯4",
"Locrian dominant<br />(Locrian ♮3)",
"Ionian ♯2",
"Altered diminished 𝄫3<br />(Locrian 𝄫3 ♭4 𝄫7)",
}
elseif step_pattern == "sAsLsAs" then
-- Modes of double harmonic
-- Closest-mode search sometimes returns two names
mode_names = {
"Double harmonic<br />(Ionian ♭2 ♭6, Phrygian ♮3 ♮7)",
"Lydian ♯2 ♯6",
"Altered ♮5 𝄫6<br />(Phrygian ♭4 𝄫7)",
"Double harmonic minor<br />(Lydian ♭3 ♭6, Aeolian ♯4 ♮7)",
"Mixolydian ♭2 ♭5, Locrian ♮3 ♮6",
"Ionian augmented ♯2<br />(Ionian ♯2 ♯5)",
"Locrian 𝄫3 𝄫7",
}
elseif #step_pattern == 0 then
-- True-mos modes
mode_names = {
"Lydian",
"Ionian (major)",
"Mixolydian",
"Dorian",
"Aeolian (minor)",
"Phrygian",
"Locrian"
}
end
end
-- If mode names are given, use those instead
-- If using default mode names (scalesig+udp), those names are auto-added by the relevant function
local use_default_names = false
if #mode_names_unparsed ~= 0 then
if mode_names_unparsed == "Default" then
use_default_names = true
else
mode_names = tip.parse_entries(mode_names_unparsed)
end
end
-- Check if the table should start collapsed
local is_collapsed = yesno(frame.args["Collapsed"], false)
-- If a modmos step pattern was never provided, call the function mos_mode_degrees
-- Otherwise, call the function modmos_mode_degrees
local result = ""
if step_pattern == "" then
result = p._mos_mode_degrees(input_mos, mos_prefix, is_collapsed)
--elseif #step_pattern == input_mos.nL + input_mos.ns then
else
result = p._mos_mode_degrees(input_mos, mos_prefix, is_collapsed, step_pattern)
end
-- Debugger option
if debugg == true then
result = "<syntaxhighlight lang=\"wikitext\">" .. result .. "</syntaxhighlight>"
end
return frame:preprocess(result)
end
return p