nwcut.setlevel(2) -- Variables -------------------------- local Testing = false local HelpLines = { "This tool changes the clef, moving all notes and chords up or down appropriately.\n", "User input: new clef and new octave shift.", "The tool acts on the selected items, or on the whole staff if nothing is selected.\n" }-- end HelpLines local CaretIndex = 0 local CurrentIndex = 0 local CaretPos = 0 local Selection = nil local SelectIndex = -1 local SelectStart = -1 local SelectEnd = -1 local StartingBar = 1 local Retain = nil local AtStart = false local ActiveStaff = -1 local CurrentStaff = 0 local OldClef, NewClef, OldOctShift, NewOctShift, OldValue, NewValue, NewClefItem local LastClefAdded = false local MyItems = {} local MI = 0 -- functions ------------------------ local function WriteError(errstring) nwcut.msgbox(errstring,"ERROR") nwcut.status = nwcut.const.rc_Error return end -- QuitError local function ShowVar(name, var) if Testing then local function v2s(v) local s if v == true then s = "true" elseif v == false then s = "false" elseif v == nil then s = "nil" elseif type(v) == "table" then s = "{" for val in pairs(v) do if s ~= "{" then s = s..", " end--if local s1 = v2s(val) local s2 = v2s(v[s1]) s = s..s1.." = "..s2 end--for s = s.."}" else s = v end--if return s end --v2s nwcut.warn(name.." = ", v2s(var),"\n") end -- if end -- ShowVar local function WriteHelpLines () nwcut.status = nwcut.const.rc_Report for i = 1, #HelpLines do nwcut.writeline(HelpLines[i]) end -- for return end -- WriteHelpLines local function Selected() return CurrentStaff == ActiveStaff and CurrentIndex >= SelectStart and CurrentIndex < SelectEnd end --Selected() local function AtCursor() return CurrentStaff == ActiveStaff and CurrentIndex > 0 and CurrentIndex == CaretIndex - 1 end --AtCursor() local function FileHeaderItem(item) return item:Is("Locale") or item:Is("Editor") or item:Is("SongInfo") or item:Is("PgSetup") or item:Is("Font") or item:Is("PgMargins") end--FileHeaderitem local function StaffHeaderItem(item) return item:Is("AddStaff") or item:Is("StaffProperties") or item:Is("StaffInstrument") or string.sub(item.ObjType,1,5) == "Lyric" end--StaffHeaderitem local function AddClef(clef, octshift) local t = nwcItem.new("|Clef") t.Opts.Type = clef t.Opts.OctaveShift = octshift MI = MI + 1 MyItems[MI] = t end--AddClef local function CalcValue(clef, octave) local clefval = { ["Bass"] = 6, ["Treble"] = -6, ["Alto"] = 0, ["Tenor"] = 2, ["Percussion"] = 6 }--end clefval local octval = {["None"] = 0, ["Octave Up"] = -7, ["Octave Down"] = 7} return clefval[clef] + octval[octave] end--CalcValue local function ProcessEditor(item) ActiveStaff = item.Opts.ActiveStaff + 0 CaretIndex = item.Opts.CaretIndex + 0 CaretPos = item.Opts.CaretPos + 0 SelectIndex = item.Opts.SelectIndex Selection = (SelectIndex ~= nil) if Selection then SelectIndex = SelectIndex + 0 end--if if Selection then SelectStart = CaretIndex < SelectIndex and CaretIndex or SelectIndex SelectEnd = CaretIndex > SelectIndex and CaretIndex or SelectIndex end --if end -- ProcessContext local function ProcessAddStaff(item) CurrentStaff = CurrentStaff + 1 ShowVar ("CurrentStaff", CurrentStaff) MeasureNumber = StartingBar ShowVar("MeasureNumber", MeasureNumber) CurrentIndex = 0 return end -- ProcessAddStaff(item) local function ProcessNotes(item) local minpos = 999 local maxpos = -999 local newpos for notepos in item:AllNotePositions() do newpos = notepos.Position + NewValue - OldValue notepos.Position = newpos if item:Is("RestChord") then if newpos < minpos then minpos = newpos end--if if newpos > maxpos then maxpos = newpos end--if if maxpos < 0 then item.Opts.Opts.Stem = "Up" elseif minpos > 0 then item.Opts.Opts.Stem = "Down" else local absminpos = - minpos if absminpos < maxpos then item.Opts.Opts.Stem = "Down" else item.Opts.Opts.Stem = "Up" end--if end--if end--if end--for end -- ProcessNotes local function InRange(item) return not Selection or Selected(item) end--InRange local function ProcessClef(item) OldClef = item.Opts.Type OldOctShift = item.Opts.OctaveShift or "None" OldValue = CalcValue(OldClef, OldOctShift) if InRange(item) then item.Opts.Type = NewClef item.Opts.OctaveShift = NewOctShift end--if end--ProcessClef local function ProcessItem(item) Retain = true if item:Is("Editor") then ProcessEditor(item) elseif item:Is("AddStaff") then ProcessAddStaff(item) end--if if not StaffHeaderItem(item) and not FileHeaderItem(item) and CurrentStaff == ActiveStaff then CurrentIndex = CurrentIndex + 1 if item:Is("Clef") then ProcessClef(item) end--if if Selection and SelectStart > 1 and CurrentIndex == SelectStart and not item:Is("Clef") then AddClef(NewClef, NewOctShift) end--if if item:ContainsNotes() then if InRange(item) then ProcessNotes(item) elseif Selection and CurrentIndex >= SelectEnd and not LastClefAdded then AddClef(OldClef, OldOctShift) LastClefAdded = true end--if end -- if end--if end -- ProcessItem -- Main processing ------------------- nwcut.status = nwcut.const.rc_Succes if nwcut.getprop('Mode') ~= nwcut.const.mode_FileText then WriteError("Input type must be ''File Text'") return end -- if if nwcut.getprop('ReturnMode') ~= nwcut.const.mode_FileText then WriteError("Under 'Options', check 'Returns File Text'") return end -- if --if #arg ~= NPrompts then WriteError(NPrompts .. " prompts needed, " .. #arg .. " found!")return end -- if NewClef = nwcut.prompt("New Clef? ","|Help|Treble|Bass|Tenor|Alto|Percussion") if NewClef == "Help" then WriteHelpLines() return end NewOctShift = nwcut.prompt("New Octave Shift? ", "|None|Octave Up|Octave Down") NewValue = CalcValue(NewClef, NewOctShift) for item in nwcut.items() do ProcessItem(item) MI = MI + 1 MyItems[MI] = item end --for item CurrentStaff = 0 OldClef = nil OldOctShift = nil for i, item in ipairs(MyItems) do Retain = true if item:Is("AddStaff") then ProcessAddStaff(item)end--if if not StaffHeaderItem(item) and CurrentStaff == ActiveStaff then if item:Is("Clef") then if item.Opts.Type == OldClef and item.Opts.OctaveShift == OldOctShift then Retain = false else OldClef = item.Opts.Type OldOctShift = item.Opts.OctaveShift end--if end--if end--if if Retain then nwcut.writeline(item)end end--for