Variable assignment in music functions
What's the right way to define a function that assigns string values to LilyPond variables? I'm trying to create a function in an include file that allows me to assign different values to variables used as midi instrument specifiers. % setMainCueClapInstruments= #(define-music-function (p l main cue clap) (string? string? string?) #{ mainInstrument = #$main cueInstrument = #$cue clapInstrument = #$clap #} (make-music 'SequentialMusic 'void #t)) \setMainCueClapInstruments #cello #acoustic grand #woodblock % But the parser throws errors, starting with the following ... Parsing... string:2:7: error: syntax error, unexpected STRING mainInstrument = #lilyvartmpbg I'm using LilyPond 2.14.1 Thanks, Mike ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Variable assignment in music functions
Michael Ellis michael.f.el...@gmail.com writes: What's the right way to define a function that assigns string values to LilyPond variables? I'm trying to create a function in an include file that allows me to assign different values to variables used as midi instrument specifiers. % setMainCueClapInstruments= #(define-music-function (p l main cue clap) (string? string? string?) #{ mainInstrument = #$main cueInstrument = #$cue clapInstrument = #$clap #} (make-music 'SequentialMusic 'void #t)) \setMainCueClapInstruments #cello #acoustic grand #woodblock % But the parser throws errors, starting with the following ... Parsing... string:2:7: error: syntax error, unexpected STRING mainInstrument = #lilyvartmpbg A music function can only do things you could also do inside of music. Assignments are _not_ permitted in music. Music is something you can put into music variables and shuffle around. Assignments are acted on immediately. What you _can_ put into music are property overrides and sets: those happen at the time they are replayed, and are wrapped into music events. You can, of course, just use ly:parser-define! inside of your function to manipulate variables. But they will get changed at the _location_ you call the music function, not at the _time_ the music expression is executed. If you put setMainCueClapInstruments into a music variable then, the effect will occur at the time you define the music variable, not at the time you use it. If you want the latter, you need to go through properties. Or even \ApplyToContext, but that's really obscure. -- David Kastrup ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Variable assignment in music functions
On Thu, Nov 3, 2011 at 12:04 PM, David Kastrup d...@gnu.org wrote: Michael Ellis michael.f.el...@gmail.com writes: What's the right way to define a function that assigns string values to LilyPond variables? I'm trying to create a function in an include file that allows me to assign different values to variables used as midi instrument specifiers. % setMainCueClapInstruments= #(define-music-function (p l main cue clap) (string? string? string?) #{ mainInstrument = #$main cueInstrument = #$cue clapInstrument = #$clap #} (make-music 'SequentialMusic 'void #t)) \setMainCueClapInstruments #cello #acoustic grand #woodblock % But the parser throws errors, starting with the following ... Parsing... string:2:7: error: syntax error, unexpected STRING mainInstrument = #lilyvartmpbg A music function can only do things you could also do inside of music. Assignments are _not_ permitted in music. Music is something you can put into music variables and shuffle around. Assignments are acted on immediately. What you _can_ put into music are property overrides and sets: those happen at the time they are replayed, and are wrapped into music events. You can, of course, just use ly:parser-define! inside of your function to manipulate variables. But they will get changed at the _location_ you call the music function, not at the _time_ the music expression is executed. If you put setMainCueClapInstruments into a music variable then, the effect will occur at the time you define the music variable, not at the time you use it. If you want the latter, you need to go through properties. Or even \ApplyToContext, but that's really obscure. Thanks David, I appreciate the detailed explanation but I'm still struggling with how to do what, in most programming languages, is a fairly straightforward task: define a variable in an outer scope and temporarily change its value in an inner scope. Over the past year or so, I've built up an include file with lots of handy functions for transcribing individual choral parts from printed scores. As a particular example, I have a function named cueNotes that prints notes inline in a teeny font and different color and specifies an alternate midi instrument and restores the defaults before exiting. Up until now, my preferences have been hard-coded, e.g. cueNotes= #(define-music-function (p l music) (ly:music?) for printing cue notes in teeny font in color #{ \set midiInstrument = #acoustic grand \override Accidental #'color = #(x11-color 'maroon) \override Beam #'color = #(x11-color 'maroon) \override NoteHead #'color = #(x11-color 'maroon) \override Rest #'color = #(x11-color 'maroon) \override Slur #'color = #(x11-color 'maroon) \override Stem #'color = #(x11-color 'maroon) \override Tie #'color = #(x11-color 'maroon) \teeny $music \normalsize \revert Accidental #'color \revert Beam #'color \revert NoteHead #'color \revert Rest #'color \revert Slur #'color \revert Stem #'color \revert Tie #'color \set midiInstrument = #cello #}) But recently, other singers in my choral groups are starting to use LilyPond and want to make use of my templates and include files but with the ability to easily change instrument and color preferences without having to hack the files. So, with that as background, let me re-ask the question in a different form: What's the best way to support changing a set of default values? ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Variable assignment in music functions
Le 03/11/2011 19:02, Michael Ellis disait : Thanks for the suggestion, Jean-Charles. I think I've now got a solution that's fairly satisfactory: In my include file, I now have: %-- #(define (make-named-instrument default-name) (define iname default-name) (define (set newname) (set! iname newname)) (define (interface op . rest) (cond ((eq? op 'set) (set (car rest))) ((eq? op 'get) iname) (else (error Undefined operation interface) #(define mainInstrument (make-named-instrument cello)) #(define cueInstrument (make-named-instrument acoustic grand)) #(define clapInstrument (make-named-instrument woodblock)) #(define (setMainCueClapInstruments main cue clap) (mainInstrument 'set main) (cueInstrument 'set cue) (clapInstrument 'set clap) '()) %-- This allows me to do \set midiInstrument = #(cueInstrument 'get) in my cueNotes and similar functions and the choice of instruments can be set within the .ly file by #(setMainCueClapInstruments trumpet clarinet timpani) Is it just me, or has the thought occurred to others that LilyPond might actually be easier to learn and use if the entry language was pure Scheme? :-) I actually used this kind of artifact with King Arthur: I typeset it for a music school here in France, so the table of contents, character and instrument names should be in French. Beside that, the sources I uploaded on the CPDL might be used in countries where French is not as commonly used as in France and Inhaltsverzeichnis looks better in German than Table des matières. So I had to find a way to collect all the strings that should be adapted in one place (per language) and set this preference in one dedicated file that gets included in each master file. Cheers, Jean-Charles On Thu, Nov 3, 2011 at 1:34 PM, Jean-Charles Malahieude wrote: Le 03/11/2011 12:53, Michael Ellis disait : So, with that as background, let me re-ask the question in a different form: What's the best way to support changing a set of default values? Wouldn't it be possible to base it on an extra file, let's say a dictionary.ily where you define variables like myCueColor = Blue_with_yellow_spots muCueInstrument = TripleBassThatSoundsLikeSnoringDucks that you include in your templates where you would then have something like \set midiInstrument = \myCueInstrument \override Rest #'color = \myCueColor This is just a guess... ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Variable assignment in music functions
Jean-Charles Malahieude lily...@orange.fr writes: Le 03/11/2011 19:02, Michael Ellis disait : This allows me to do \set midiInstrument = #(cueInstrument 'get) in my cueNotes and similar functions and the choice of instruments can be set within the .ly file by #(setMainCueClapInstruments trumpet clarinet timpani) Is it just me, or has the thought occurred to others that LilyPond might actually be easier to learn and use if the entry language was pure Scheme? :-) I actually used this kind of artifact with King Arthur: I typeset it for a music school here in France, so the table of contents, character and instrument names should be in French. Beside that, the sources I uploaded on the CPDL might be used in countries where French is not as commonly used as in France and Inhaltsverzeichnis looks better in German than Table des matières. So I had to find a way to collect all the strings that should be adapted in one place (per language) and set this preference in one dedicated file that gets included in each master file. \paper { tocname = Inhaltsverzeichnis } #(define-markup-command (toc layout props) () (interpret-markup layout props (ly:output-def-lookup layout 'tocname none))) \markup \toc -- David Kastrup ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Variable assignment in music functions
Le 03/11/2011 20:02, David Kastrup disait : Jean-Charles Malahieude writes: Le 03/11/2011 19:02, Michael Ellis disait : This allows me to do \set midiInstrument = #(cueInstrument 'get) in my cueNotes and similar functions and the choice of instruments can be set within the .ly file by #(setMainCueClapInstruments trumpet clarinet timpani) Is it just me, or has the thought occurred to others that LilyPond might actually be easier to learn and use if the entry language was pure Scheme? :-) I actually used this kind of artifact with King Arthur: I typeset it for a music school here in France, so the table of contents, character and instrument names should be in French. Beside that, the sources I uploaded on the CPDL might be used in countries where French is not as commonly used as in France and Inhaltsverzeichnis looks better in German than Table des matières. So I had to find a way to collect all the strings that should be adapted in one place (per language) and set this preference in one dedicated file that gets included in each master file. \paper { tocname = Inhaltsverzeichnis } #(define-markup-command (toc layout props) () (interpret-markup layout props (ly:output-def-lookup layout 'tocname none))) \markup \toc But the list is a bit longer (cf. enclosure) Cheers, Jean-Charles \version 2.14.0 %%% Instrument and character names LFlute = Flûte Lfl = Fl LOboe = Hautbois Lob = Htb LTrumpet = Trompette Ltpt = Tpt LViolin = Violon Lvn = Vln LViola = Viola Lva = Vla LCello = Violoncelle LBasso = Continuo Lbc = BC LDrums = Timbales LChor = ChÅur LSoprano = Soprano Lsop = S LAlto = Alto Lalt = A LTenor = Tenor Lten = T LBasse = Basse Lbas = B LFS = Premier prêtre Saxon LSS = Second prêtre Saxon LTS = Troisième prêtre Saxon LPhil = Philidel LGrim = Grimbald LGenius = Génie de l'or LCupid = Cupid LSyren = Sirène LNymph = Nymphe LShep = Berger LSylv = Sylvains LAelus = Ãlus LFishers = ChÅur des pêcheurs LNereid = Néréïde LPan = Pan LVenus = Vénus LHonour = Honneur LDuet = Duo LNVerse = Nymphes Ltacet = Tacet Lsolo = Solo Ltutti = Tutti LPrimo = \markup { \concat { 1 \super er } } LPrima = \markup { \concat { 1 \super re } } LSecundo = \markup { \concat { 2 \super e } } LSecunda = \markup { \concat { 2 \super e } } Lbar = mesure Lbars = mesures Lattributed = attribué à % List of ToC nodes and piece ToCTitle = Table des matières Overture = \markup { %% OV \smallCaps Ouverture } ActOne = \markup { Acte premier } AWodenFirst = \markup { %%1A \italic Solo chÅur \char ##x2013 Woden, first to thee, we have sacrificed } AWodenThanks = \markup { %%1A bar 47 \italic Duo chÅur \char ##x2013 To Woden, thanks we render } ALotIsCast = \markup { %%1C \italic Solo \char ##x2013 The lot is cast } ABraveSouls = \markup { %%1D \italic ChÅur \char ##x2013 Brave souls, to be renow'd } AWodensHall = \markup { %%1E \italic Solo chÅur \char ##x2013 I call you all to Woden's hall } AMSymphony = \markup { %%1F Symphonie militaire } AComeIfYouDare = \markup { %%1G \italic Solo chÅur \char ##x2013 Come, if you dare } ActTwo = \markup { Acte deux } BIntro = \markup { %%2A Introduction } BSymphony = \markup { %%2B Symphonie } BHitherWay = \markup { %%2C \italic Solo chÅur \char ##x2013 Hither, this way bend } BMoonBornElf = \markup { %%2D \italic Solo \char ##x2013 Let not a moon-born elf } BChorHither = \markup { %%2E \italic ChÅur \char ##x2013 Hither, this way } BFollowMe = \markup { %%2F \italic ChÅur \char ##x2013 Come, follow me } BHowBlessed = \markup { %%2G \italic Solo chÅur \char ##x2013 How blessed are shepherds } BDuet = \markup { %%2H \italic Duo \char ##x2013 Shepherd, shepherd, leave decoying } BComeShepherds = \markup { %%2J \italic ChÅur \char ##x2013 Come, shepherds, lead up a lively measure } BHornpipe = \markup { %%2K Hornpipe } ActThree = \markup { Acte trois } CRecitative = \markup { %%3B \italic Récitatif \char ##x2013 What oh! thou Genious of the clime } CWhatPower = \markup { %%3C \italic Solo \char ##x2013 What power art thou? } CDoatingFool = \markup { %%3D \italic Solo \char ##x2013 Thou doating fool } CGreatLove = \markup { %%3E \italic Solo \char ##x2013 Great Love, I know thee now } CDominions = \markup { %%3F \italic Récitatif \char ##x2013 No part of my dominions } CPrelude = \markup { %%3G Prélude } CWeAssemble = \markup { %%3H \italic ChÅur \char ##x2013 See, we assemble } CTisI = \markup { %%3J \italic Solo \char ##x2013 'T is I that have warm'd ye } CTisLove = \markup { %%3K \italic ChÅur \char ##x2013 'T is love that has warm'd us } CSoundaParley = \markup { %%3L \italic Duo \char ##x2013 Sound a parley, ye fair } CHornpipe = \markup { %%3M Hornpipe } ActFour = \markup { Acte quatre } DTwoDaughters = \markup { %%4A \italic Duo \char
Re: Variable assignment in music functions
Le 03/11/2011 20:02, David Kastrup disait : \paper { tocname = Inhaltsverzeichnis } #(define-markup-command (toc layout props) () (interpret-markup layout props (ly:output-def-lookup layout 'tocname none))) \markup \toc But the list is a bit longer (cf. enclosure) I first define in the language-fr.ily file TocTitle = Table des matières and in languege-de.ily TocTitle = Inhaltsverzeichnis and then in the master file \paper { %% Translate the toc title: tocTitleMarkup = \markup \huge \column { \fill-line { \null \ToCTitle \null } \hspace #1 } will produce the right wording, depending on the translation I wish. Cheers, Jean-Charles ps: sorry, the phone ring just disturbed me... \version 2.14.0 %%% Instrument and character names LFlute = Flûte Lfl = Fl LOboe = Hautbois Lob = Htb LTrumpet = Trompette Ltpt = Tpt LViolin = Violon Lvn = Vln LViola = Viola Lva = Vla LCello = Violoncelle LBasso = Continuo Lbc = BC LDrums = Timbales LChor = ChÅur LSoprano = Soprano Lsop = S LAlto = Alto Lalt = A LTenor = Tenor Lten = T LBasse = Basse Lbas = B LFS = Premier prêtre Saxon LSS = Second prêtre Saxon LTS = Troisième prêtre Saxon LPhil = Philidel LGrim = Grimbald LGenius = Génie de l'or LCupid = Cupid LSyren = Sirène LNymph = Nymphe LShep = Berger LSylv = Sylvains LAelus = Ãlus LFishers = ChÅur des pêcheurs LNereid = Néréïde LPan = Pan LVenus = Vénus LHonour = Honneur LDuet = Duo LNVerse = Nymphes Ltacet = Tacet Lsolo = Solo Ltutti = Tutti LPrimo = \markup { \concat { 1 \super er } } LPrima = \markup { \concat { 1 \super re } } LSecundo = \markup { \concat { 2 \super e } } LSecunda = \markup { \concat { 2 \super e } } Lbar = mesure Lbars = mesures Lattributed = attribué à % List of ToC nodes and piece ToCTitle = Table des matières Overture = \markup { %% OV \smallCaps Ouverture } ActOne = \markup { Acte premier } AWodenFirst = \markup { %%1A \italic Solo chÅur \char ##x2013 Woden, first to thee, we have sacrificed } AWodenThanks = \markup { %%1A bar 47 \italic Duo chÅur \char ##x2013 To Woden, thanks we render } ALotIsCast = \markup { %%1C \italic Solo \char ##x2013 The lot is cast } ABraveSouls = \markup { %%1D \italic ChÅur \char ##x2013 Brave souls, to be renow'd } AWodensHall = \markup { %%1E \italic Solo chÅur \char ##x2013 I call you all to Woden's hall } AMSymphony = \markup { %%1F Symphonie militaire } AComeIfYouDare = \markup { %%1G \italic Solo chÅur \char ##x2013 Come, if you dare } ActTwo = \markup { Acte deux } BIntro = \markup { %%2A Introduction } BSymphony = \markup { %%2B Symphonie } BHitherWay = \markup { %%2C \italic Solo chÅur \char ##x2013 Hither, this way bend } BMoonBornElf = \markup { %%2D \italic Solo \char ##x2013 Let not a moon-born elf } BChorHither = \markup { %%2E \italic ChÅur \char ##x2013 Hither, this way } BFollowMe = \markup { %%2F \italic ChÅur \char ##x2013 Come, follow me } BHowBlessed = \markup { %%2G \italic Solo chÅur \char ##x2013 How blessed are shepherds } BDuet = \markup { %%2H \italic Duo \char ##x2013 Shepherd, shepherd, leave decoying } BComeShepherds = \markup { %%2J \italic ChÅur \char ##x2013 Come, shepherds, lead up a lively measure } BHornpipe = \markup { %%2K Hornpipe } ActThree = \markup { Acte trois } CRecitative = \markup { %%3B \italic Récitatif \char ##x2013 What oh! thou Genious of the clime } CWhatPower = \markup { %%3C \italic Solo \char ##x2013 What power art thou? } CDoatingFool = \markup { %%3D \italic Solo \char ##x2013 Thou doating fool } CGreatLove = \markup { %%3E \italic Solo \char ##x2013 Great Love, I know thee now } CDominions = \markup { %%3F \italic Récitatif \char ##x2013 No part of my dominions } CPrelude = \markup { %%3G Prélude } CWeAssemble = \markup { %%3H \italic ChÅur \char ##x2013 See, we assemble } CTisI = \markup { %%3J \italic Solo \char ##x2013 'T is I that have warm'd ye } CTisLove = \markup { %%3K \italic ChÅur \char ##x2013 'T is love that has warm'd us } CSoundaParley = \markup { %%3L \italic Duo \char ##x2013 Sound a parley, ye fair } CHornpipe = \markup { %%3M Hornpipe } ActFour = \markup { Acte quatre } DTwoDaughters = \markup { %%4A \italic Duo \char ##x2013 Two daughters of this aged stream } DPassa = \markup { %%4B Passacaille } DHappyLover = \markup { %%4B bar 123 \italic Solo chÅur \char ##x2013 How happy the lover } DForLove = \markup { %%4B bar 184 \italic Duo chÅur \char ##x2013 For Love every creature } DNymphes = \markup { %%4B bar 247- \smallCaps Air des Nymphes } ActFive = \markup { Acte cinq } EBlustering = \markup { %%5A \italic Air \char ##x2013 Ye blustering brethren } ESymphony = \markup { %%5B Symphonie } EDitto = \markup { %%5C Ditto } ERound = \markup { %%5D \italic Duo chÅur \char ##x2013