===== Using JW Lua - Create Harp Glissando ===== 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** of //JW Lua//, but it should hopefully work with any later version as well. ==== Step 1 - Download and Install JW Lua ==== 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 location as the plug-in .fxt file. ==== Step 2 - Start JW Lua ==== Once the JW Lua plug-in has been installed and Finale has been restarted, select //JW Lua...// in Finale's //Plug-ins// menu. ==== Step 3 - Create a script group ==== To organize the scripts into a workflow, a script need to be put in a group. - Select the **Manager** page - Click the **New...** button to the top right, which will open the //Edit Plug-in Group// dialog box. - Enter a **Group Name** (such as "Harp Editing", "Plucked Strings", "Note Editing", "Client X", etc) where you want to put your script. - Enter a **Description** with a text that is a more detailed description of what the group will contain. - Leave everything else as it is and press the **OK** button. ==== Step 4 - Add the script to the 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: - Make sure that the group is selected in the //top list// on the //Manager// page. - Press the **New...** button next to the **bottom list**. - In the dialog box that appears, locate the script on your computer and select it to add to the group. When you exit Finale, the changes made on the //Manager// page will be saved. ==== Step 5 - Refresh the plug-in list ==== Select the **Explorer** page and press the **Refresh All** button. The group should now appear with the script inside. ==== Step 6 - Run ==== On the **Explorer** page, open your group container and select the script. Press the **Run** button. ==== The Harp Glissando script ==== The harp glissado script will transform 7-tuplets with seven undotted notes (of a "flagged" note duration) in the selected region into graphical harp glissando start note that spans the duration of the tuplet. {{ :wiki:jwlua:jwlua-harpgliss.jpg?nolink |}} The script will only modify staves that are defined a ''Harp'' in Finale's //Score Manager// - so if a 7-tuplet is for example found on a violin staff, nothing will be processed. It will also handle situations such as when the tuplet duration spans a half note or more. The original notes in the tuplet doesn't need to be beamed. Note that at the very start of the script are 2 values (''StemLength'' and ''SmallNoteResize'') that you might want to modify. To do that, select the **Development** page and open/edit/save the file there. (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