This is an old revision of the document!
If you have never used JW Lua to run scripts before, this is a good page to start. At the bottom of the page is a full script that will automatically create a harp gliss from a 7-tuplet that you might want to test (the script works on Finale 2012 and later versions).
This wiki page is based on beta version 0.07, but it should hopefully work with any later version as well.
The beta versions of JW Lua are available for download at this page: http://finaletips.nu/index.php?option=com_phocadownload&view=category&id=28:beta-version&Itemid=2
Install the plug-in as any other third party Finale plug-in. The Windows version contains a DLL file as well, which must be put in the same folder as the plug-in .fxt file.
Once the JW Lua plug-in has been installed and Finale has been restarted, select JW Lua… in Finale's Plug-ins menu.
To organize the scripts into a workflow, a script need to be put in a group.
Download the harpgliss.lua
file below, if you haven't done so already. Make sure to store the JW Lua scripts at a good location on your computer. These scripts can be put anywhere on the hard drive, they don't need to be related to the Finale installation.
To add the script to the group:
When you exit Finale, the changes made on the Manager page will be saved.
Select the Explorer page and press the Refresh All button. The group should now appear with the script inside.
On the Explorer page, open your group container and select the script. Press the Run button.
The harp glissado script will transform a 7-tuplet with seven undotted notes into a graphical harp glissando start note that spans the duration of the tuplet.
(Click on the harpgliss.lua
text to download the script.)
-- CHANGE THESE 2 VALUES IF YOU WANT OTHER VALUES StemLength = 84 -- Stem Length of the first note in EVPUs SmallNoteResize = 70 -- Resize % of small notes function plugindef() -- This function and the 'finaleplugin' namespace -- are both reserved for the plug-in definition. finaleplugin.RequireSelection = true finaleplugin.MinFinaleVersion = "2012" finaleplugin.Author = "Jari Williamsson" finaleplugin.Version = "0.01" finaleplugin.Notes = [[ This script will only process 7-tuplets that appears on staves that has been defined as "Harp" in the Score Manager. ]] finaleplugin.CategoryTags = "Idiomatic, Note, Pluckedstrings, Region, Tuplet, Woodwinds" return "Harp gliss (from 7-tuplet)", "Harp gliss", "Transforms 7-tuplets to harp gliss notation." end -- Sets the beam width to 0 and resizes the stem for the first note (by moving -- the primary beam) -- This is a sub-function to ChangePrimaryBeam() function ChangeBeamInfo(primarybeam, entry) local currentlength = entry:CalcStemLength() primarybeam.Thickness = 0 if entry:CalcStemUp() then primarybeam.LeftVerticalOffset = primarybeam.LeftVerticalOffset + StemLength - currentlength else primarybeam.LeftVerticalOffset = primarybeam.LeftVerticalOffset - StemLength + currentlength end end -- Changes a primary beam for and entry function ChangePrimaryBeam(entry) local primarybeams = finale.FCPrimaryBeamMods(entry) primarybeams:LoadAll() if primarybeams.Count > 0 then -- Modify the existing beam modification record to hide the beam local primarybeam = primarybeams:GetItemAt(0) ChangeBeamInfo(primarybeam, entry) primarybeam:Save() else -- Create a beam modification record and hide the beam local primarybeam = finale.FCBeamMod(false) primarybeam:SetNoteEntry(entry) ChangeBeamInfo(primarybeam, entry) primarybeam:SaveNew() end end -- Assures that the entries that spans the entries are -- considered "valid" for a harp gliss. Rests and too few -- notes in the tuplet are things that aren't ok. -- This is a sub-function to GetMatchingTuplet() function VerifyEntries(entry, tuplet) local entrystaffspec = finale.FCCurrentStaffSpec() entrystaffspec:LoadForEntry(entry) if entrystaffspec.InstrumentUUID ~= finale.FFUUID_HARP then return false end local symbolicduration = 0 local firstentry = entry for i = 0, 6 do if entry == nil then return false end if entry:IsRest() then return false end if entry.Duration >= finale.QUARTER_NOTE then return false end if entry.Staff ~= firstentry.Staff then return false end if entry.Layer ~= firstentry.Layer then return false end if entry:CalcDots() > 0 then return false end symbolicduration = symbolicduration + entry.Duration entry = entry:Next() end return (symbolicduration == tuplet:CalcFullSymbolicDuration()) end -- If a "valid" harp tuplet is found for an entry, this method returns it. function GetMatchingTuplet(entry) local tuplets = entry:CreateTuplets() for t in each(tuplets) do if t.SymbolicNumber == 7 and VerifyEntries(entry, t) then return t end end return nil end -- Hides a tuplet (both by visibility and appearance) function HideTuplet(t) t.ShapeStyle = finale.TUPLETSHAPE_NONE t.NumberStyle = finale.TUPLETNUMBER_NONE t.Visible = false t:Save() end -- Hide stems for the small notes in the gliss. If the "full" note has a long -- enough duration to not have a stem, the first entry also gets a hidden stem. function HideStems(entry, tuplet) local hidefirstentry = (tuplet:CalcFullReferenceDuration() >= finale.WHOLE_NOTE) for i = 0, 6 do if i > 0 or hidefirstentry then local stem = finale.FCCustomStemMod() stem:SetNoteEntry(entry) stem:UseUpStemData(entry:CalcStemUp()) if stem:LoadFirst() then stem.ShapeID = 0 stem:Save() else stem.ShapeID = 0 stem:SaveNew() end end entry = entry:Next() end end -- Change the notehead shapes and notehead sizes function SetNoteheads(entry, tuplet) for i = 0, 6 do for chordnote in each(entry) do local notehead = finale.FCNoteheadMod() if i == 0 then local fullrefdur = tuplet:CalcFullReferenceDuration() if fullrefdur >= finale.WHOLE_NOTE then notehead.CustomChar = 119 -- Whole note character elseif fullrefdur >= finale.HALF_NOTE then notehead.CustomChar = 250 -- Half note character end else notehead.Resize = SmallNoteResize end notehead:SaveAt(chordnote) end entry = entry:Next() end end -- If the tuplet spans a duration that is dotted, modify the -- rhythm at the beginning of the tuplet function ChangeDottedFirstEntry(entry, tuplet) local refdur = tuplet:CalcFullReferenceDuration() local tupletdots = finale.FCNoteEntry.CalcDotsForDuration(refdur) local entrydots = entry:CalcDots() if tupletdots == 0 then return end if tupletdots > 3 then return end -- Don't support too complicated gliss rhythm values if entrydots > 0 then return end -- Create dotted rhythm local nextentry = entry:Next() local nextduration = nextentry.Duration / 2 for i = 1, tupletdots do entry.Duration = entry.Duration + nextduration nextentry.Duration = nextentry.Duration - nextduration nextduration = nextduration / 2 end end -- *** THE SCRIPT EXECUTION STARTS HERE *** -- Make sure the harp tuplets are beamed for entry in eachentrysaved(finenv.Region()) do local harptuplet = GetMatchingTuplet(entry) if harptuplet then harp_tuplets_exist = true for i = 1, 6 do entry = entry:Next() entry.BeamBeat = false end end end if harp_tuplets_exist == nil then return end -- Since the entries might change direction when they are beamed, -- tell Finale to update the entry metric data info finale.FCNoteEntry.MarkEntryMetricsForUpdate() -- Change the harp tuplets for entry in eachentrysaved(finenv.Region()) do local harptuplet = GetMatchingTuplet(entry) if harptuplet then ChangeDottedFirstEntry(entry, harptuplet) ChangePrimaryBeam(entry) HideTuplet(harptuplet) HideStems(entry, harptuplet) SetNoteheads(entry, harptuplet) end end