[JW Lua] Dynamic positioning script
Jari Williamsson
jari.williamsson at mailbox.swipnet.se
Wed Oct 9 17:34:59 CEST 2013
Hello!
Here's a script that has saved me hours of layout time during the past
month.
It repositions dynamics horizontally to be centered to the note. Since
Finale doesn't provide different positioning settings for
downstem/upstem/whole notes, it's impossible to get accurate horizontal
positioning with a "good default file".
It also reposition main note dynamics leftwise to appear on the first
grace note.
This sample script only supports the Maestro and Maestro Wide fonts, but
you should easily be able to add support for other fonts by expanding
the tables.
I've attached a sample picture that displays the before/after states.
Let me know if the script doesn't work as it should.
Best regards,
Jari Williamsson
-------------- next part --------------
A non-text attachment was scrubbed...
Name: jwlua-dynamics_horizpos.jpg
Type: image/jpeg
Size: 85930 bytes
Desc: not available
URL: <http://jwmusic.nu/pipermail/jwlua_jwmusic.nu/attachments/20131009/3d1e1d46/attachment.jpg>
-------------- next part --------------
function plugindef()
-- This function and the 'finaleplugin' namespace
-- are both reserved for the plug-in definition.
finaleplugin.RequireSelection = true
finaleplugin.MinJWLuaVersion = "0.07"
finaleplugin.Author = "Jari Williamsson"
finaleplugin.Version = "0.01"
finaleplugin.CategoryTags = "Expression, Layout, Region"
return "Dynamic Pos (w. grace note adjust)", "Dynamic Pos", "Centers dynamics horizontally to the notehead and moves to first grace note."
end
function AdjustmentForGraceNote(entry)
local previous = entry:Previous()
if not previous then return 0 end
if not previous.GraceNote then return 0 end
local gracenotewidth = previous:CalcWidestNoteheadWidth()
while previous:Previous() and previous:Previous().GraceNote do
-- Compensate for multiple grace notes. This seems to work ok...
gracenotewidth = gracenotewidth - previous:GetManualPosition()
previous = previous:Previous()
gracenotewidth = gracenotewidth + (previous:CalcWidestNoteheadWidth() * 2 / 3)
end
return -previous:GetManualPosition() + gracenotewidth
end
function RepositionOneExpression(expr, str, fontinfo)
-- pos_table syntax: [character] = {downstem-pos, upstem-pos, wholenote-pos}
local pos_table = {
["Maestro"] =
{
[236] = {-4, 5, 6}, -- fff
[196] = {-2, 5, 10}, -- ff
[102] = {-2, 3, 8}, -- f
[70] = {-5, 3, 6}, -- mf
[80] = {2, 8, 12}, -- mp
[112] = {9, 12, 15}, -- p
[185] = {8, 12, 16}, -- pp
[184] = {10, 15, 17}, -- ppp
[234] = {8, 14, 14}, -- fp
[167] = {2, 12, 14} -- sfz
},
["Maestro Wide"] =
{
[236] = {0, 3, 8}, -- fff
[196] = {2, 10, 10}, -- ff
[102] = {0, 6, 12}, -- f
[70] = {-3, 3, 9}, -- mf
[80] = {4, 13, 15}, -- mp
[112] = {5, 10, 18}, -- p
[185] = {6, 14, 18}, -- pp
[184] = {6, 17, 19}, -- ppp
[234] = {8, 14, 18}, -- fp
[167] = {4, 12, 16} -- sfz
}
}
local char = str:GetItemAt(0)
local postableref = pos_table[fontinfo.Name]
if postableref == nil then
print ("Unknown font at measure", expr.Measure, ":", fontinfo.Name )
return
end
postableref = postableref[char]
if postableref == nil then
print("Unreferenced font character at measure", expr.Measure, ":", char)
return
end
if (postableref == nil) then
print ("Character", char, "not found in table in measure", expr.Measure )
return
end
-- Check if it's upstem or downstem
local notecell = finale.FCNoteEntryCell(expr.Measure, expr.Staff)
notecell:Load()
local entry = notecell:FindEntryStartPosition(expr.MeasurePos, -1)
if not entry then return end
if entry:IsRest() then return end
local graceadjust = AdjustmentForGraceNote(entry)
local refvalue = nil
if entry.Duration == finale.WHOLE_NOTE then
refvalue = postableref[3]
elseif entry:CalcStemUp() then
refvalue = postableref[2]
else
refvalue = postableref[1]
end
if refvalue == nil then
print ("Unknown reference value for character", char, ", Measure:", expr.Measure, ", Stem up:", entry:CalcStemUp(), ", Duration:", entry.Duration)
return
end
expr.HorizontalPos = refvalue - graceadjust
expr:Save()
end
function RepositionDynamics(m, region)
local expressions = finale.FCExpressions()
expressions:LoadAllForItem(m)
for e in each(expressions) do
if region:IsStaffIncluded(e.Staff) and e.StaffGroupID == 0 then
local textexp = e:CreateTextExpressionDef()
if textexp then
local fontinfo = finale.FCFontInfo()
local str = textexp:CreateTextString()
fontinfo = str:CreateLastFontInfo()
str:TrimEnigmaTags()
if str:GetLength() == 1 then
RepositionOneExpression(e, str, fontinfo)
end
end
end
end
end
local region = finenv.Region()
for m = region.StartMeasure, region.EndMeasure do
RepositionDynamics(m, region)
end
More information about the JWLua
mailing list