モジュール:Infobox MOS
ナビゲーションに移動
検索に移動
このモジュールについての説明文ページを モジュール:Infobox MOS/doc に作成できます
local p = {}
local utils = require('Module:Utils')
local rat = require('Module:Rational')
local mos = require('Module:MOS')
local et = require('Module:ET')
local infobox = require('Module:Infobox')
local kbvis = require('Module:Keyboard vis')
local tip = require('Module:Template input parse')
local tamnams = require('Module:TAMNAMS')
-- TODO:
-- Adopt new functions
-- Add back xenpaper links (low priority)
-- Helper function
-- Concatenates the contents of two tables into one
-- This doesn't have a return value; rather, the first table passed has the
-- second table's contents added to it.
function p.concatenate_tables(t1, t2)
for i=1, #t2 do
t1[#t1+1] = t2[i]
end
end
-- Helper function
-- Create a keyboard visualization, based on the Halberstadt keyboard layout
function p.kb_vis(input_mos)
local input_mos = input_mos or mos.new(5, 2)
local brightest_mode = mos.brightest_mode(input_mos)
local vis = ""
if input_mos.nL + input_mos.ns < 40 then
vis = kbvis.vis_small(brightest_mode)
end
return {{vis}}
end
-- Helper function
-- Adds categories
function p.categorize(tuning)
local tuning = tuning or "5L 2s"
local input_mos = mos.parse(tuning)
-- Add to category of abstact mosses
local categories = "[[Category:抽象MOSパターン]]"
-- Add notecount category if the notecount is greater than 3
local notecount = input_mos.nL + input_mos.ns
if notecount > 3 then
categories = categories .. string.format('[[Category:%d音音階]]', notecount)
end
-- If the mos is octave-equivalent, add appropriate tamnams-named categories
-- Otherwise, add to nonoctave category
if rat.eq(input_mos.equave, rat.new(2)) then
-- Caveats:
-- - Only octave-equivalent mos names are used as categories.
-- - Monowood and biwood are excluded (for now).
-- - Mosses whose notecounts > 10 and periods < 5 are categorized under
-- the closest tamnams-named ancestor.
local ancestor_mos = mos.find_ancestor(input_mos)
local tamnams_name = tamnams.lookup_name(ancestor_mos)
if tamnams_name ~= nil then
categories = categories .. string.format('[[Category:%s]]', tamnams_name)
end
else
categories = categories .. '[[Category:非オクターブ]]'
end
return categories
end
-- Helper function
-- Creates adjacent links for mos, found by +/-1 large or +/- small steps
function p.adjacent_links(input_mos)
local input_mos = input_mos or mos.new(5, 2)
local equave_as_long_string = ""
local equave_as_string = ""
if not rat.eq(input_mos.equave, 2) then
equave_as_long_string = string.format(" (%s-equivalent)", rat.as_ratio(input_mos.equave))
equave_as_string = string.format("⟨%s⟩", rat.as_ratio(input_mos.equave))
end
local adjacent_links = {
string.format("[[%dL %ds%s | ↖ %dL %ds%s]]", input_mos.nL-1, input_mos.ns-1, equave_as_long_string, input_mos.nL-1, input_mos.ns-1, equave_as_string),
string.format("[[%dL %ds%s | ↑%dL %ds%s]]", input_mos.nL , input_mos.ns-1, equave_as_long_string, input_mos.nL , input_mos.ns-1, equave_as_string),
string.format("[[%dL %ds%s | %dL %ds%s ↗]]", input_mos.nL+1, input_mos.ns-1, equave_as_long_string, input_mos.nL+1, input_mos.ns-1, equave_as_string),
string.format("[[%dL %ds%s | ← %dL %ds%s]]", input_mos.nL-1, input_mos.ns , equave_as_long_string, input_mos.nL-1, input_mos.ns , equave_as_string),
string.format("[[%dL %ds%s | %dL %ds%s →]]", input_mos.nL+1, input_mos.ns , equave_as_long_string, input_mos.nL+1, input_mos.ns , equave_as_string),
string.format("[[%dL %ds%s | ↙ %dL %ds%s]]", input_mos.nL-1, input_mos.ns+1, equave_as_long_string, input_mos.nL-1, input_mos.ns+1, equave_as_string),
string.format("[[%dL %ds%s | ↓%dL %ds%s]]", input_mos.nL , input_mos.ns+1, equave_as_long_string, input_mos.nL , input_mos.ns+1, equave_as_string),
string.format("[[%dL %ds%s | %dL %ds%s ↘]]", input_mos.nL+1, input_mos.ns+1, equave_as_long_string, input_mos.nL+1, input_mos.ns+1, equave_as_string),
}
-- Links that contain either "0L" or "0s" when the parent's L/s-count is 1
-- refer to degenerate mosses (either 0L or 0s), whose links should be made
-- blank instead.
for i = 1, #adjacent_links do
local number_of_periods = utils._gcd(input_mos.nL, input_mos.ns)
local is_null_large = string.find(adjacent_links[i], "0L") and input_mos.nL == 1
local is_null_small = string.find(adjacent_links[i], "0s") and input_mos.ns == 1
if is_null_large or is_null_small then
adjacent_links[i] = ""
end
end
return adjacent_links
end
-- Helper function
-- Produces section entries for scale sturcture
-- Section is returned as a jagged array and return value must be merged into
-- a larger array.
function p.scale_structure(input_mos)
local input_mos = input_mos or mos.new(5, 2)
local equave_as_string = rat.as_ratio(input_mos.equave)
local equave_in_cents = rat.cents(input_mos.equave)
local number_of_periods = utils._gcd(input_mos.nL, input_mos.ns)
local period_as_string = ""
if number_of_periods == 1 then
period_as_string = equave_as_string
else
local ed = et.new(number_of_periods, input_mos.equave)
period_as_string = et.backslash_display(ed, 1)
end
local period_in_cents = equave_in_cents / number_of_periods
local step_pattern = string.format("...%d steps...", input_mos.nL+input_mos.ns)
if input_mos.nL + input_mos.ns <= 40 then
local brightest_mode = mos.brightest_mode(input_mos)
step_pattern = string.format('<abbr title="Brightest mode">%s</abbr><br><abbr title="Darkest mode">%s</abbr>', brightest_mode, string.reverse(brightest_mode))
end
local section_header = "構造"
local section_entries = {
{string.format("<b>%s</b>", section_header)},
{"[[音程パターン]]", step_pattern},
{"[[オクターブ]]", string.format("%s (%.1f¢)", equave_as_string, equave_in_cents)},
{"[[ジェネレーターとピリオド|周期]]", string.format("%s (%.1f¢)", period_as_string, period_in_cents)}
}
return section_entries
end
-- Helper function
-- Produces generator ranges for scale
-- Section is returned as a jagged array and return value must be merged into
-- a larger array.
function p.generator_sizes(input_mos)
local input_mos = input_mos or mos.new(5, 2)
local number_of_periods = utils._gcd(input_mos.nL, input_mos.ns)
local bright_gen = mos.bright_gen(input_mos)
local dark_gen = mos.dark_gen (input_mos)
local equalized_ed = et.new(input_mos.nL + input_mos.ns, input_mos.equave, "")
local collapsed_ed = et.new(input_mos.nL, input_mos.equave, "")
local bright_min_in_steps = et.backslash_display(equalized_ed, bright_gen['L'] + bright_gen['s'])
local bright_max_in_steps = et.backslash_display(collapsed_ed, bright_gen['L'])
local dark_min_in_steps = et.backslash_display(collapsed_ed, dark_gen['L'])
local dark_max_in_steps = et.backslash_display(equalized_ed, dark_gen['L'] + dark_gen['s'])
local bright_min_in_cents = et.cents(equalized_ed, bright_gen['L'] + bright_gen['s'])
local bright_max_in_cents = et.cents(collapsed_ed, bright_gen['L'])
local dark_min_in_cents = et.cents(collapsed_ed, dark_gen['L'])
local dark_max_in_cents = et.cents(equalized_ed, dark_gen['L'] + dark_gen['s'])
local section_header = "ジェネレーター"
local equave_annotation = ""
if rat.eq(input_mos.equave, 3) then
equave_annotation = '<sup><abbr title="In steps of edt">(edt)</sup>'
elseif rat.eq(input_mos.equave, rat.new(3,2)) then
equave_annotation = '<sup><abbr title="In steps of edf">(edf)</sup>'
elseif not rat.eq(input_mos.equave, 2) then
local equave_as_ratio = rat.as_ratio(input_mos.equave)
equave_annotation = string.format('<sup><abbr title="In steps of ed%s">(ed%s)</sup>', equave_as_ratio, equave_as_ratio)
end
local section_entries = {
{string.format("<b>%s</b>%s", section_header, equave_annotation)},
{"[[高輝度]]", string.format("%s - %s (%.1f¢ - %.1f¢)", bright_min_in_steps, bright_max_in_steps, bright_min_in_cents, bright_max_in_cents)},
{"[[低輝度]]", string.format("%s - %s (%.1f¢ - %.1f¢)", dark_min_in_steps, dark_max_in_steps, dark_min_in_cents, dark_max_in_cents)},
}
return section_entries
end
-- Helper function
-- Produces ranges small and large steps (currently unused)
-- Section is returned as a jagged array and return value must be merged into
-- a larger array.
function p.step_sizes(input_mos)
local input_mos = input_mos or mos.new(5, 2)
local equalized_ed = et.new(input_mos.nL + input_mos.ns, input_mos.equave, "")
local collapsed_ed = et.new(input_mos.nL, input_mos.equave, "")
-- Large and small steps
-- The small step lower bound is basically zero (when collapsed).
-- The upper bound for a small step and the lower bound for a large step
-- are the same.
-- The upper bound of a large step is when the step ratio is collapsed.
local small_step_min_in_steps = et.backslash_display(collapsed_ed, 0)
local large_step_min_in_steps = et.backslash_display(equalized_ed, 1)
local large_step_max_in_steps = et.backslash_display(collapsed_ed, 1)
local small_step_min_in_cents = et.cents(collapsed_ed, 0)
local large_step_min_in_cents = et.cents(equalized_ed, 1)
local large_step_max_in_cents = et.cents(collapsed_ed, 1)
local section_header = "音程"
local equave_annotation = ""
if rat.eq(input_mos.equave, 3) then
equave_annotation = '<sup><abbr title="In steps of edt">(edt)</sup>'
elseif rat.eq(input_mos.equave, rat.new(3,2)) then
equave_annotation = '<sup><abbr title="In steps of edf">(edf)</sup>'
elseif not rat.eq(input_mos.equave, 2) then
local equave_as_ratio = rat.as_ratio(input_mos.equave)
equave_annotation = string.format('<sup><abbr title="In steps of ed%s">(ed%s)</sup>', equave_as_ratio, equave_as_ratio)
end
local section_entries = {
{string.format("<b>%s</b>%s", section_header, equave_annotation)},
{"[[Step pattern | 最大]]", string.format("%s to %s (%.1f¢ to %.1f¢)", large_step_min_in_steps, large_step_max_in_steps, large_step_min_in_cents, large_step_max_in_cents)},
{"[[Step pattern | 最小]]", string.format("%s to %s (%.1f¢ to %.1f¢)", small_step_min_in_steps, large_step_min_in_steps, small_step_min_in_cents, large_step_min_in_cents)}
}
return section_entries
end
-- Helper function for a helper function
-- Determines what mos the given mos descends from
-- as well as what step ratio that produces this scale
-- Mosses within the "named range" passed here will return itself
function p.find_mos_ancestor(input_mos)
local input_mos = input_mos or mos.new(5, 2)
local z = input_mos.nL
local w = input_mos.ns
local generations = 0
-- For an ancestral mos zU wv and descendant xL ys, how many steps of size
-- L and s can fit inside U and v? (basically the chunking operation)
local lg_chunk = { nL = 1, ns = 0 }
local sm_chunk = { nL = 0, ns = 1 }
while (z ~= w) and (z + w > 10) do
local m1 = math.max(z, w)
local m2 = math.min(z, w)
-- For use with updating ancestor mos chunks
local z_prev = z
-- Count how many generations
generations = generations + 1
-- Update step ratios
z = m2
w = m1 - m2
-- Update large chunk
local prev_lg_chunk = { nL = lg_chunk.nL, ns = lg_chunk.ns }
lg_chunk.nL = lg_chunk.nL + sm_chunk.nL
lg_chunk.ns = lg_chunk.ns + sm_chunk.ns
-- Update small chunk
if z ~= z_prev then
sm_chunk = prev_lg_chunk
end
end
return mos.new(z, w, input_mos.equave), lg_chunk, sm_chunk, generations
end
-- Helper function
-- Produces section entries for tamnams info
-- Conditions for tamnams info inclusion:
-- - Scale is octave-equivalent.
-- - Scales within the "named range" (6-10 notes, or is 1L 1s or 2L 2s) have
-- a tamnams name.
-- - Scales with a notecount greater than 10 and no more than 5 periods have
-- a tamnams-named ancestor.
-- - Scales with a notecount greater than 10 and more than 5 periods don't have
-- a tamnams-named ancestor, but will report what nL ns mos they descend from.
-- Section is returned as a jagged array and return value must be merged into
-- a larger array.
function p.tamnams_information(input_mos)
local input_mos = input_mos or mos.new(5, 2)
local scalesig = string.format("%dL %ds", input_mos.nL, input_mos.ns)
local notecount = input_mos.nL + input_mos.ns
local number_of_periods = utils._gcd(input_mos.nL, input_mos.ns)
local tamnams_name = tamnams.lookup_name (input_mos)
local tamnams_prefix = tamnams.lookup_prefix(input_mos)
local tamnams_abbrev = tamnams.lookup_abbrev(input_mos)
local is_octave_equivalent = rat.eq(input_mos.equave, 2)
local is_within_named_range = tamnams_name ~= nil and notecount <= 10
local is_root_mos = input_mos.nL == input_mos.ns
local section_header = "TAMNAMS"
local section_entries = nil
if is_octave_equivalent then
if is_within_named_range then
-- Mos has a tamnams name
section_entries = {
{string.format("<b>%s</b>", section_header)},
{"[[TAMNAMS#Mos_pattern_names | 名称]]", tamnams_name},
{"[[TAMNAMS#Mos_pattern_names | 接頭辞]]", tamnams_prefix .. "-"},
{"[[TAMNAMS#Mos_pattern_names | 略記]]", tamnams_abbrev}
}
elseif not is_within_named_range and notecount > 10 and not is_root_mos then
-- Mos is a non-root mos and has a tamnams-named ancestor
local ancestor_mos, lg_chunk, sm_chunk, generations = p.find_mos_ancestor(input_mos)
local ancestor_scalesig = mos.as_string(ancestor_mos)
local ancestor_long_scalesig = mos.as_long_string(ancestor_mos)
local ancestor_name = tamnams.lookup_name(ancestor_mos)
-- Helper code for finding mos ancestor and relation to it
local num1 = lg_chunk.nL + lg_chunk.ns
local den1 = sm_chunk.nL + sm_chunk.ns
local num2 = lg_chunk.nL
local den2 = sm_chunk.nL
local first_ancestor_step_ratio = ""
local second_ancestor_step_ratio = ""
if num1/den1 < num2/den2 then
first_ancestor_step_ratio = string.format("%d:%d", num1, den1)
second_ancestor_step_ratio = string.format("%d:%d", num2, den2)
else
first_ancestor_step_ratio = string.format("%d:%d", num2, den2)
second_ancestor_step_ratio = string.format("%d:%d", num1, den1)
end
-- Step ratio range as text
local step_ratio_range = string.format("%s to %s", first_ancestor_step_ratio, second_ancestor_step_ratio)
-- Step ratio range as a named range
local named_range = step_ratio_range
if step_ratio_range == "1:1 to 2:1" then
named_range = named_range .. " (soft-of-basic)"
elseif step_ratio_range == "2:1 to 1:0" then
named_range = named_range .. " (hard-of-basic)"
elseif step_ratio_range == "1:1 to 3:2" then
named_range = named_range .. " (soft)"
elseif step_ratio_range == "3:2 to 2:1" then
named_range = named_range .. " (hyposoft)"
elseif step_ratio_range == "2:1 to 3:1" then
named_range = named_range .. " (hypohard)"
elseif step_ratio_range == "3:1 to 1:0" then
named_range = named_range .. " (hard)"
elseif step_ratio_range == "1:1 to 4:3" then
named_range= named_range .. " (ultrasoft)"
elseif step_ratio_range == "4:3 to 3:2" then
named_range = named_range .. " (parasoft)"
elseif step_ratio_range == "3:2 to 5:3" then
named_range = named_range .. " (quasisoft)"
elseif step_ratio_range == "5:3 to 2:1" then
named_range = named_range .. " (minisoft)"
elseif step_ratio_range == "2:1 to 5:2" then
named_range = named_range .. " (minihard)"
elseif step_ratio_range == "5:2 to 3:1" then
named_range = named_range .. " (quasihard)"
elseif step_ratio_range == "3:1 to 4:1" then
named_range = named_range .. " (parahard)"
elseif step_ratio_range == "4:1 to 1:0" then
named_range = named_range .. " (ultrahard)"
end
local ancestor_entry = string.format("[[%s | %s]]", ancestor_long_scalesig, ancestor_scalesig)
if ancestor_name ~= nil then
ancestor_entry = ancestor_entry .. string.format(" (%s)", ancestor_name)
end
section_entries = {
{string.format("<b>%s</b>", section_header)},
{"Descends from", ancestor_entry};
{"Required step ratio range", string.format("%s", named_range)}
}
end
end
return section_entries
end
-- Helper function
-- Adds a section for scale names
function p.other_names(other_names)
local other_names = other_names or { "p-chromatic", "hard diatonic" }
local section_header = "別名"
if #other_names == 0 then
return nil
else
local scale_names = ""
for i=1, #other_names do
scale_names = scale_names .. other_names[i]
if i ~= #other_names then
scale_names = scale_names .. "<br>"
end
end
local section_entries = {
{string.format("<b>%s</b>", section_header)},
{"Name(s)", scale_names}
}
return section_entries
end
end
-- Helper function
-- Produces section for related scales
-- Section is returned as a jagged array and return value must be merged into
-- a larger array.
function p.related_scales(input_mos)
local input_mos = input_mos or mos.new(5, 2)
local parent_mos = mos.new(math.min(input_mos.nL, input_mos.ns), math.abs(input_mos.nL-input_mos.ns), input_mos.equave)
local sister_mos = mos.new(input_mos.ns, input_mos.nL, input_mos.equave)
local soft_child_mos = mos.new(input_mos.nL+input_mos.ns, input_mos.nL, input_mos.equave)
local hard_child_mos = mos.new(input_mos.nL, input_mos.nL+input_mos.ns, input_mos.equave)
local neutral_mos = input_mos.nL>input_mos.ns and mos.new(input_mos.nL-input_mos.ns, input_mos.ns*2, input_mos.equave) or mos.new(input_mos.nL*2, input_mos.ns-input_mos.nL, input_mos.equave)
local soft_floght_mos = mos.new(input_mos.nL*2+input_mos.ns, input_mos.ns, input_mos.equave)
local hard_floght_mos = mos.new(input_mos.nL, input_mos.ns*2+input_mos.nL, input_mos.equave)
local parent_scalesig = string.format("[[%s | %s]]", mos.as_long_string(parent_mos ), mos.as_string(parent_mos ))
local sister_scalesig = string.format("[[%s | %s]]", mos.as_long_string(sister_mos ), mos.as_string(sister_mos ))
local soft_scalesig = string.format("[[%s | %s]]", mos.as_long_string(soft_child_mos), mos.as_string(soft_child_mos))
local hard_scalesig = string.format("[[%s | %s]]", mos.as_long_string(hard_child_mos), mos.as_string(hard_child_mos))
local neutral_scalesig = string.format("[[%s | %s]]", mos.as_long_string(neutral_mos), mos.as_string(neutral_mos))
local soft_floght_scalesig = string.format("[[%s | %s]]", mos.as_long_string(soft_floght_mos), mos.as_string(soft_floght_mos))
local hard_floght_scalesig = string.format("[[%s | %s]]", mos.as_long_string(hard_floght_mos), mos.as_string(hard_floght_mos))
local number_of_periods = utils._gcd(input_mos.nL, input_mos.ns)
local is_nL_ns = input_mos.nL == number_of_periods and input_mos.ns == number_of_periods
if is_nL_ns then
parent_scalesig = "none"
sister_scalesig = sister_scalesig .. " (self)"
equave_suffix = ""
if rat.eq(input_mos.equave, 2) then
equave_suffix = "o"
elseif rat.eq(input_mos.equave, 3) then
equave_suffix = "t"
elseif rat.eq(input_mos.equave, rat.new(3, 2)) then
equave_suffix = "f"
elseif rat.is_harmonic(input_mos.equave) then
local a, b = rat.as_pair(input_mos.equave)
equave_suffix = a
else
equave_suffix = rat.as_ratio(input_mos.equave)
end
neutral_scalesig = string.format("[[%ded%s]]", input_mos.nL*2, equave_suffix)
end
local section_header = "関連する音律"
local section_entries = {
{string.format("<b>%s</b>", section_header)},
{"[[Operations_on_MOSes#Parent_MOS | 親]]", parent_scalesig},
{"[[Operations_on_MOSes#Sister_MOS | 姉妹]]", sister_scalesig},
{"[[Operations_on_MOSes#Daughter_MOS | 娘]]", soft_scalesig .. ", " .. hard_scalesig},
{"[[Operations_on_MOSes#Neutralization | 平滑化]]", neutral_scalesig},
{"[[Flought_scale | 分割]]", soft_floght_scalesig .. ", " .. hard_floght_scalesig}
}
return section_entries
end
-- Helper function
-- Produces simple equal tunings
function p.equal_tunings(input_mos)
local input_mos = input_mos or mos.new(5, 2)
local bright_gen = mos.bright_gen(input_mos)
local mos_as_vector = {
['L'] = input_mos.nL,
['s'] = input_mos.ns
}
local step_ratios = {
{ 1, 1 },
{ 4, 3 },
{ 3, 2 },
{ 5, 3 },
{ 2, 1 },
{ 5, 2 },
{ 3, 1 },
{ 4, 1 },
{ 1, 0 }
}
local step_ratio_names = {
"Equalized",
"Supersoft",
"Soft",
"Semisoft",
"Basic",
"Semihard",
"Hard",
"Superhard",
"Collapsed"
}
local section_header = "平均律チューニング"
local equave_annotation = ""
if rat.eq(input_mos.equave, 3) then
equave_annotation = '<sup><abbr title="In steps of edt">(edt)</sup>'
elseif rat.eq(input_mos.equave, rat.new(3,2)) then
equave_annotation = '<sup><abbr title="In steps of edf">(edf)</sup>'
elseif not rat.eq(input_mos.equave, 2) then
local equave_as_ratio = rat.as_ratio(input_mos.equave)
equave_annotation = string.format('<sup><abbr title="In steps of ed%s">(ed%s)</sup>', equave_as_ratio, equave_as_ratio)
end
local section_entries = {
{string.format("<b>%s</b>%s", section_header, equave_annotation)},
}
for i = 1, #step_ratios do
local step_ratio = step_ratios[i]
local ed_size = mos_as_vector['L'] * step_ratio[1] + mos_as_vector['s'] * step_ratio[2]
local gen_size = bright_gen['L'] * step_ratio[1] + bright_gen['s'] * step_ratio[2]
local ed = et.new(ed_size, input_mos.equave)
local ed_as_string = et.as_string(ed)
local ed_no_prefix = et.new(ed_size, input_mos.equave, "")
local ed_as_string_no_prefix = et.as_string(ed_no_prefix)
local gen_in_steps = et.backslash_display(ed_no_prefix, gen_size)
local gen_in_cents = et.cents(ed, gen_size)
local caption = string.format("[[%s]] (L:s = %d:%d)", step_ratio_names[i], step_ratio[1], step_ratio[2])
local text = string.format("[[%s | %s]] (%.1f¢)", ed_as_string, gen_in_steps, gen_in_cents)
table.insert(section_entries, { caption, text })
end
return section_entries
end
-- New "main" function
function p._infobox_mos(tuning, other_names_unparsed)
local tuning = tuning or "5L 2s"
local other_names_unparsed = other_names_unparsed or ""
local tuning_parsed = mos.parse(tuning)
local other_names_parsed = tip.parse_entries(other_names_unparsed) or tip.parse_entries(other_names_unparsed, ',')
local sections = {}
-- Keyboard visualization
local kb_vis = p.kb_vis(tuning_parsed)
p.concatenate_tables(sections, kb_vis)
-- Scale structure section
local scale_structure = p.scale_structure(tuning_parsed)
p.concatenate_tables(sections, scale_structure)
-- Interval range section
--local step_sizes = p.step_sizes(tuning_parsed)
--p.concatenate_tables(sections, step_sizes)
-- Generator sizes section
local gen_sizes = p.generator_sizes(tuning_parsed)
p.concatenate_tables(sections, gen_sizes)
-- Tamnams info section, if applicable
local tamnams_info = p.tamnams_information(tuning_parsed)
if tamnams_info ~= nil then
p.concatenate_tables(sections, tamnams_info)
end
-- Other names section, if applicable
local other_names_section = p.other_names(other_names_parsed)
if other_names_section ~= nil then
p.concatenate_tables(sections, other_names_section)
end
-- Related scales section
local related_scales = p.related_scales(tuning_parsed)
p.concatenate_tables(sections, related_scales)
-- Equal tunings section
local equal_tunings = p.equal_tunings(tuning_parsed)
p.concatenate_tables(sections, equal_tunings)
-- Adjacent links
local adjacent_links = p.adjacent_links(tuning_parsed)
return infobox.build_multilink(tuning, sections, adjacent_links)
--return sections
end
-- Wrapper function
function p.infobox_MOS(frame)
local tuning = frame.args['Tuning']
local other_names = frame.args['othernames'] or nil
local debug_mode = tonumber(frame.args['debug']) == 1
local result = p._infobox_mos(tuning, other_names)
if not debug_mode then
result = result .. p.categorize(tuning)
end
return result
end
function p.tester()
local prev_link = "5L 1s"
local next_link = "5L 3s"
local entries = {
{"構造"},
{"最も明るいモード", "LLLsLLs"},
{"周期", "2\1 (1200¢)"},
{"Bright generator range", "4\7 (685.7¢) to 3\5 (720¢)"},
{"Dark generator range", "2\5 (480¢) to 3\7 (514.3¢)"},
{"TAMNAMS"},
{"音階名", "diatonic"},
{"プレフィックス", "dia-"},
{"略称", "dia."},
{"関連する音律"},
{"親MOS", "2L 3s"},
{"姉妹MOS", "2L 5s"},
{"子MOSes", "7L 5s, 5L 7s"},
{"平滑MOS", "3L 4s"},
{"2分割MOS", "12L 2s, 5L 9s"},
{"平均律チューニング"},
{"Supersoft (L:s = 4:3)", "15\\26 (692.3¢)"},
{"Soft (L:s = 3:2)", "11\\19 (694.7¢)"},
{"Semisoft (L:s = 5:3)", "18\\31 (696.8¢)"},
{"Basic (L:s = 2:1)", "7\\12 (700¢)"},
{"Semihard (L:s = 5:2)", "17\\29 (703.4¢)"},
{"Hard (L:s = 3:1)", "10\\17 (705.9¢)"},
{"Superhard (L:s = 4:1)", "13\\22 (709.1¢)"},
}
return infobox.build_multilink("5L 2s (2/1-equivalent)", entries)
end
return p