[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