Skip to content

Commit 00770ac

Browse files
authored
Merge pull request #797 from rpatters1/latest-mss-changes
Latest mss changes
2 parents 1de1141 + 9132bc8 commit 00770ac

File tree

1 file changed

+141
-45
lines changed

1 file changed

+141
-45
lines changed

src/document_options_to_musescore.lua

Lines changed: 141 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ function plugindef()
44
finaleplugin.NoStore = true
55
finaleplugin.Author = "Robert Patterson"
66
finaleplugin.Copyright = "CC0 https://creativecommons.org/publicdomain/zero/1.0/"
7-
finaleplugin.Version = "1.0.3"
8-
finaleplugin.Date = "December 31, 2024"
7+
finaleplugin.Version = "1.1.0"
8+
finaleplugin.Date = "December 8, 2025"
99
finaleplugin.CategoryTags = "Document"
1010
finaleplugin.MinJWLuaVersion = 0.75
1111
finaleplugin.Notes = [[
@@ -59,6 +59,7 @@ local enigma_string = require("library.enigma_string")
5959
local utils = require("library.utils")
6060
local client = require("library.client")
6161
local score = require("library.score")
62+
local library = require("library.general_library")
6263

6364
do_folder = do_folder or false
6465

@@ -68,7 +69,7 @@ local MUSX_EXTENSION <const> = ".musx"
6869
local MUS_EXTENSION <const> = ".mus"
6970
local TEXT_EXTENSION <const> = ".mss"
7071
local PART_EXTENSION <const> = ".part" .. TEXT_EXTENSION
71-
local MSS_VERSION <const> = "4.50"
72+
local MSS_VERSION <const> = "4.60"
7273

7374
-- hard-coded scaling values
7475
local EVPU_PER_INCH <const> = 288
@@ -77,6 +78,8 @@ local EVPU_PER_SPACE <const> = 24
7778
local EFIX_PER_EVPU <const> = 64
7879
local EFIX_PER_SPACE <const> = EVPU_PER_SPACE * EFIX_PER_EVPU
7980
local MUSE_FINALE_SCALE_DIFFERENTIAL <const> = 20 / 24
81+
local MUSE_NUMERIC_PRECISION <const> = 5
82+
local NORMAL_STAFF_HEIGHT_SP <const> = 4
8083

8184
-- Current state
8285
local TIMER_ID <const> = 1 -- value that identifies our timer
@@ -121,6 +124,7 @@ local tie_prefs
121124
local tuplet_prefs
122125
local text_exps
123126
local music_font_name
127+
local spatium_scaling
124128

125129
function open_current_prefs()
126130
local font_prefs = finale.FCFontPrefs()
@@ -177,6 +181,13 @@ function open_current_prefs()
177181
else
178182
music_font_name = nil
179183
end
184+
local page_percent = page_prefs.PageScaling / 100
185+
local staff_percent = (page_prefs.SystemStaffHeight / (EVPU_PER_SPACE * 4 * 16)) * (page_prefs.SystemScaling / 100)
186+
spatium_scaling = page_percent * staff_percent
187+
end
188+
189+
local function format_muse_float(value)
190+
return string.format("%" .. "." .. tostring(MUSE_NUMERIC_PRECISION) .. "g", value)
180191
end
181192

182193
function set_element_text(style_element, name, value)
@@ -185,7 +196,7 @@ function set_element_text(style_element, name, value)
185196
log_message("incorrect property for " .. name, true)
186197
elseif type(value) == "number" then
187198
if math.type(value) == "float" then
188-
value = string.format("%.5g", value)
199+
value = format_muse_float(value)
189200
setter_func = "SetText"
190201
else
191202
setter_func = "SetIntText"
@@ -202,6 +213,34 @@ function set_element_text(style_element, name, value)
202213
return element
203214
end
204215

216+
local function set_point_element(style_element, name, x, y)
217+
local element = style_element:FirstChildElement(name)
218+
if not element then
219+
element = style_element:InsertNewChildElement(name)
220+
end
221+
element:SetText("")
222+
element:SetAttribute("x", format_muse_float(x))
223+
element:SetAttribute("y", format_muse_float(y))
224+
return element
225+
end
226+
227+
local function font_mag_val(font_info)
228+
return font_info.Absolute and 1 or MUSE_FINALE_SCALE_DIFFERENTIAL
229+
end
230+
231+
local function calc_font_ascent_in_spaces(font_info)
232+
if not font_info then
233+
return 0
234+
end
235+
local text_metrics = finale.FCTextMetrics()
236+
local test_string = finale.FCString()
237+
test_string.LuaString = "0123456789"
238+
if not text_metrics:LoadString(test_string, font_info, 100 * font_mag_val(font_info)) then
239+
return 0
240+
end
241+
return text_metrics.TopEVPUs / EVPU_PER_SPACE
242+
end
243+
205244
function muse_font_efx(font_info)
206245
local retval = 0
207246
if font_info.Bold then
@@ -232,7 +271,7 @@ end
232271

233272
function write_font_pref(style_element, name_prefix, font_info)
234273
set_element_text(style_element, name_prefix .. "FontFace", font_info.Name)
235-
set_element_text(style_element, name_prefix .. "FontSize", font_info.Size * (font_info.Absolute and 1 or MUSE_FINALE_SCALE_DIFFERENTIAL))
274+
set_element_text(style_element, name_prefix .. "FontSize", font_info.Size * font_mag_val(font_info))
236275
set_element_text(style_element, name_prefix .. "FontSpatiumDependent", not font_info.Absolute)
237276
set_element_text(style_element, name_prefix .. "FontStyle", muse_font_efx(font_info))
238277
end
@@ -300,9 +339,7 @@ function write_page_prefs(style_element)
300339
set_element_text(style_element, "pageTwosided", page_prefs.UseFacingPages)
301340
set_element_text(style_element, "enableIndentationOnFirstSystem", page_prefs.UseFirstSystemMargins)
302341
set_element_text(style_element, "firstSystemIndentationValue", page_prefs.FirstSystemLeft / EVPU_PER_SPACE)
303-
local page_percent = page_prefs.PageScaling / 100
304-
local staff_percent = (page_prefs.SystemStaffHeight / (EVPU_PER_SPACE * 4 * 16)) * (page_prefs.SystemScaling / 100)
305-
set_element_text(style_element, "spatium", (EVPU_PER_SPACE * staff_percent * page_percent) / EVPU_PER_MM)
342+
set_element_text(style_element, "spatium", (EVPU_PER_SPACE * spatium_scaling) / EVPU_PER_MM)
306343
local first_system = finale.FCStaffSystem()
307344
if first_system:LoadFirst() then
308345
local min_size = 100
@@ -452,57 +489,116 @@ function write_measure_number_prefs(style_element)
452489
set_element_text(style_element, "showMeasureNumber", meas_num_regions:LoadAll() > 0)
453490
if meas_num_regions.Count > 0 then
454491
local meas_nums = meas_num_regions:GetItemAt(0)
455-
set_element_text(style_element, "showMeasureNumberOne", not meas_nums:GetHideFirstNumber(current_is_part))
456-
set_element_text(style_element, "measureNumberInterval", meas_nums:GetMultipleValue(current_is_part))
457-
set_element_text(style_element, "measureNumberSystem", meas_nums:GetShowOnSystemStart(current_is_part) and not meas_nums:GetShowMultiples(current_is_part))
458-
local function process_segment(font_info, enclosure, use_enclosure, justification, alignment, vertical, prefix)
459-
local function justification_string(justi)
460-
if justi == finale.MNJUSTIFY_LEFT then
461-
return "left,baseline"
462-
elseif justi == finale.MNJUSTIFY_CENTER then
463-
return "center,baseline"
464-
else
465-
return "right,baseline"
466-
end
492+
local parts_val = library.calc_parts_boolean_for_measure_number_region(meas_nums, current_is_part)
493+
set_element_text(style_element, "showMeasureNumberOne", not meas_nums:GetHideFirstNumber(parts_val))
494+
set_element_text(style_element, "measureNumberInterval", meas_nums:GetMultipleValue(parts_val))
495+
local show_on_every = meas_nums:GetShowMultiples(parts_val)
496+
local use_show_on_start = meas_nums:GetShowOnSystemStart(parts_val) and not show_on_every
497+
set_element_text(style_element, "measureNumberSystem", use_show_on_start)
498+
499+
local function justification_string(justi)
500+
if justi == finale.MNJUSTIFY_LEFT then
501+
return "left,baseline"
502+
elseif justi == finale.MNJUSTIFY_CENTER then
503+
return "center,baseline"
467504
end
468-
local function horz_alignment(align) -- MuseScore 4.6 changes this to "left", "center", "right"
469-
if align == finale.MNALIGN_LEFT then
470-
return 0
471-
elseif align == finale.MNALIGN_CENTER then
472-
return 1
473-
else
474-
return 2
475-
end
476-
end
477-
local function vert_alignment(vert)
478-
return vert >= 0 and 0 or 1
505+
return "right,baseline"
506+
end
507+
508+
local function align_string(align)
509+
if align == finale.MNALIGN_LEFT then
510+
return "left"
511+
elseif align == finale.MNALIGN_CENTER then
512+
return "center"
479513
end
514+
return "right"
515+
end
516+
517+
local function vert_alignment(vert)
518+
return vert >= 0 and 0 or 1
519+
end
520+
521+
local function process_segment(font_info, enclosure, use_enclosure, justification, alignment, horizontal, vertical, prefix)
522+
horizontal = horizontal or 0
523+
vertical = vertical or 0
480524
write_font_pref(style_element, prefix, font_info)
481525
set_element_text(style_element, prefix .. "VPlacement", vert_alignment(vertical))
482-
set_element_text(style_element, prefix .. "HPlacement", horz_alignment(alignment))
526+
set_element_text(style_element, prefix .. "HPlacement", align_string(alignment))
483527
set_element_text(style_element, prefix .. "Align", justification_string(justification))
528+
set_element_text(style_element, prefix .. "Position", align_string(justification))
529+
local horizontal_sp = horizontal / EVPU_PER_SPACE
530+
local vertical_sp = vertical / EVPU_PER_SPACE
531+
local text_height_sp = calc_font_ascent_in_spaces(font_info) * spatium_scaling
532+
set_point_element(style_element, prefix .. "PosAbove", horizontal_sp, math.min(-vertical_sp, 0))
533+
set_point_element(style_element, prefix .. "PosBelow", horizontal_sp,
534+
math.max(-(vertical_sp + NORMAL_STAFF_HEIGHT_SP) - text_height_sp, 0))
484535
write_frame_prefs(style_element, prefix, use_enclosure and enclosure or nil)
485536
end
486-
local font_info = meas_nums:GetShowOnSystemStart(current_is_part) and meas_nums:CreateStartFontInfo(current_is_part) or meas_nums:CreateMultipleFontInfo(current_is_part)
487-
local enclosure = meas_nums:GetShowOnSystemStart(current_is_part) and meas_nums:GetEnclosureStart(current_is_part) or meas_nums:GetEnclosureMultiple(current_is_part)
488-
local use_enclosure = meas_nums:GetShowOnSystemStart(current_is_part) and meas_nums:GetUseEnclosureStart(current_is_part) or meas_nums:GetUseEnclosureMultiple(current_is_part)
489-
local justification = meas_nums:GetShowMultiples(current_is_part) and meas_nums:GetMultipleJustification(current_is_part) or meas_nums:GetStartJustification(current_is_part)
490-
local alignment = meas_nums:GetShowMultiples(current_is_part) and meas_nums:GetMultipleAlignment(current_is_part) or meas_nums:GetStartAlignment(current_is_part)
491-
local vertical = meas_nums:GetShowOnSystemStart(current_is_part) and meas_nums:GetStartVerticalPosition(current_is_part) or meas_nums:GetMultipleVerticalPosition(current_is_part)
537+
538+
local scroll_view = finale.FCSystemStaves()
539+
scroll_view:LoadScrollView()
540+
local staff = finale.FCStaff()
541+
local top_on = false
542+
local bottom_on = false
543+
local any_interior_on = false
544+
local all_staves_on = scroll_view.Count > 0
545+
for index = 0, scroll_view.Count - 1 do
546+
local staff_id = scroll_view:GetItemAt(index).Staff
547+
local shows = false
548+
if staff:Load(staff_id) then
549+
shows = staff.ShowMeasureNumbers
550+
end
551+
all_staves_on = all_staves_on and shows
552+
if index == 0 then
553+
top_on = shows
554+
elseif index == scroll_view.Count - 1 then
555+
bottom_on = shows
556+
elseif shows then
557+
any_interior_on = true
558+
end
559+
end
560+
561+
local placement_mode = "on-so-staves"
562+
local show_top = meas_nums:GetShowOnTopStaff(parts_val)
563+
local show_bottom = meas_nums:GetShowOnBottomStaff(parts_val)
564+
local exclude_others = meas_nums:GetExcludeOtherStaves(parts_val)
565+
local use_above = exclude_others or (not any_interior_on and not bottom_on)
566+
local use_below = exclude_others or (not any_interior_on and not top_on)
567+
if use_above and show_top then
568+
placement_mode = "above-system"
569+
elseif use_below and show_bottom then
570+
placement_mode = "below-system"
571+
elseif all_staves_on then
572+
placement_mode = "on-all-staves"
573+
elseif show_bottom and not use_below then
574+
log_message("Show on Bottom not supported when other staves also show measure numbers.")
575+
end
576+
set_element_text(style_element, "measureNumberPlacementMode", placement_mode)
577+
578+
local font_info = use_show_on_start and meas_nums:CreateStartFontInfo(parts_val) or meas_nums:CreateMultipleFontInfo(parts_val)
579+
local enclosure = use_show_on_start and meas_nums:GetEnclosureStart(parts_val) or meas_nums:GetEnclosureMultiple(parts_val)
580+
local use_enclosure = use_show_on_start and meas_nums:GetUseEnclosureStart(parts_val) or meas_nums:GetUseEnclosureMultiple(parts_val)
581+
local justification = show_on_every and meas_nums:GetMultipleJustification(parts_val) or meas_nums:GetStartJustification(parts_val)
582+
local alignment = show_on_every and meas_nums:GetMultipleAlignment(parts_val) or meas_nums:GetStartAlignment(parts_val)
583+
local vertical = use_show_on_start and meas_nums:GetStartVerticalPosition(parts_val) or meas_nums:GetMultipleVerticalPosition(parts_val)
584+
local horizontal = use_show_on_start and meas_nums:GetStartHorizontalPosition(parts_val) or meas_nums:GetMultipleHorizontalPosition(parts_val)
585+
set_element_text(style_element, "measureNumberAlignToBarline", alignment == finale.MNALIGN_LEFT)
492586
set_element_text(style_element, "measureNumberOffsetType", 1)
493-
process_segment(font_info, enclosure, use_enclosure, justification, alignment, vertical, "measureNumber")
494-
set_element_text(style_element, "mmRestShowMeasureNumberRange", meas_nums:GetShowMultiMeasureRange(current_is_part))
495-
local left_char = meas_nums:GetMultiMeasureBracketLeft(current_is_part)
587+
process_segment(font_info, enclosure, use_enclosure, justification, alignment, horizontal, vertical, "measureNumber")
588+
process_segment(font_info, enclosure, use_enclosure, justification, alignment, horizontal, vertical, "measureNumberAlternate")
589+
590+
set_element_text(style_element, "mmRestShowMeasureNumberRange", meas_nums:GetShowMultiMeasureRange(parts_val))
591+
local left_char = meas_nums:GetMultiMeasureBracketLeft(parts_val)
496592
if left_char == 0 then
497593
set_element_text(style_element, "mmRestRangeBracketType", 2)
498-
elseif left_char == '(' then
594+
elseif left_char == string.byte('(') then
499595
set_element_text(style_element, "mmRestRangeBracketType", 1)
500596
else
501597
set_element_text(style_element, "mmRestRangeBracketType", 0)
502598
end
503-
process_segment(meas_nums:CreateMultiMeasureFontInfo(current_is_part), meas_nums:GetEnclosureMultiple(current_is_part), meas_nums:GetUseEnclosureMultiple(current_is_part),
504-
meas_nums:GetMultiMeasureJustification(current_is_part), meas_nums:GetMultiMeasureAlignment(current_is_part),
505-
meas_nums:GetMultiMeasureVerticalPosition(current_is_part), "mmRestRange")
599+
process_segment(meas_nums:CreateMultiMeasureFontInfo(parts_val), nil, false,
600+
meas_nums:GetMultiMeasureJustification(parts_val), meas_nums:GetMultiMeasureAlignment(parts_val),
601+
meas_nums:GetMultiMeasureHorizontalPosition(parts_val), meas_nums:GetMultiMeasureVerticalPosition(parts_val), "mmRestRange")
506602
end
507603
set_element_text(style_element, "createMultiMeasureRests", current_is_part)
508604
set_element_text(style_element, "minEmptyMeasures", mmrest_prefs.StartNumberingAt)

0 commit comments

Comments
 (0)