Add \eval to Lilypond?

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Add \eval to Lilypond?

Alan Stern
The facility for generating Lilypond code from within Scheme is
fairly limited.  The #{ ... #} syntax only recognizes music
expressions, so it can't be used in a \layout block, for instance.

Is it possible to add a \eval primitive to Lilypond?  It could
take as an argument either a literal string or a Scheme expression
that returns a string, and then it would feed the contents of that
string directly into the parser.

As an example, we could put in a source file

\eval #(if OutputMidi "\\midi { \\tempo 4 = 120 } " "")

Then the setting of the single variable OutputMidi would control
whether or not the \midi block was parsed and hence whether a MIDI
output file was created.   Currently there's no way to make such a
decision at runtime.  Much more complicated code could easily be
constructed, in which the strings are calculated and assembled
on-the-fly.

This ought to be reasonably simple to implement for someone who is
already familiar with Lilypond's internal operation (which I am not).
Is anyone interested?

Alan Stern



_______________________________________________
lilypond-devel mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/lilypond-devel
Reply | Threaded
Open this post in threaded view
|

Re: Add \eval to Lilypond?

Erik Sandberg
Citerar Alan Stern <[hidden email]>:

> The facility for generating Lilypond code from within Scheme is
> fairly limited.  The #{ ... #} syntax only recognizes music
> expressions, so it can't be used in a \layout block, for instance.
>
> Is it possible to add a \eval primitive to Lilypond?  It could
> take as an argument either a literal string or a Scheme expression
> that returns a string, and then it would feed the contents of that
> string directly into the parser.
>
> As an example, we could put in a source file
>
> \eval #(if OutputMidi "\\midi { \\tempo 4 = 120 } " "")

Sounds like what you're looking for is a preprocessor. There will never be a
builtin preprocessor in lilypond, but you are free to use an external one if
you like (e.g. m4, gpp).

For music expressions, you could define an 'apply' music function:

apply = #(def-music-function (parser location statement music) (procedure?
ly:music?)
  (let ((ls (ly:music-property music 'elements)))
   (statement ls)))

\apply #(lambda (x) (if (eq? 1 0) (car x) (cadr x))) { {c' d'} {e' f'} }

=> {e' f'}

Erik



_______________________________________________
lilypond-devel mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/lilypond-devel
Reply | Threaded
Open this post in threaded view
|

Re: Add \eval to Lilypond?

Nicolas Sceaux
Erik Sandberg <[hidden email]> writes:

> \apply #(lambda (x) (if (eq? 1 0) (car x) (cadr x))) { {c' d'} {e' f'} }

I know that this has nothing to do with this discussion, but according
to R5RS, (eq? 0 1) is unspecified. See
http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%25_idx_216 

nicolas



_______________________________________________
lilypond-devel mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/lilypond-devel
Reply | Threaded
Open this post in threaded view
|

Re: Add \eval to Lilypond?

Alan Stern
In reply to this post by Erik Sandberg
Erik Sandberg <Erik.Sandberg.9195 <at> student.uu.se> writes:

> Citerar Alan Stern <stern <at> rowland.harvard.edu>:
>
> > The facility for generating Lilypond code from within Scheme is
> > fairly limited.  The #{ ... #} syntax only recognizes music
> > expressions, so it can't be used in a \layout block, for instance.
> >
> > Is it possible to add a \eval primitive to Lilypond?  It could
> > take as an argument either a literal string or a Scheme expression
> > that returns a string, and then it would feed the contents of that
> > string directly into the parser.
> >
> > As an example, we could put in a source file
> >
> > \eval #(if OutputMidi "\\midi { \\tempo 4 = 120 } " "")
>
> Sounds like what you're looking for is a preprocessor. There will never be a
> builtin preprocessor in lilypond, but you are free to use an external one if
> you like (e.g. m4, gpp).

You got me thinking.  A preprocessor is indeed what I was looking for, so I
wrote a simple one for Lilypond.  It's in Scheme, which means it's portable to
any machine that Lilypond can run on.  The preprocessor itself does almost no
work, since it can rely on Scheme to take care of all the hard stuff.

With this approach, I can generate both an orchestral conductor's score and
individual parts from a single source.  If anyone is interested, I will post the
source and explain how to use it.

Alan Stern



_______________________________________________
lilypond-devel mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/lilypond-devel
Reply | Threaded
Open this post in threaded view
|

Re: Add \eval to Lilypond?

Werner LEMBERG
> A preprocessor is indeed what I was looking for, so I wrote a simple
> one for Lilypond.  [...]
>
> With this approach, I can generate both an orchestral conductor's
> score and individual parts from a single source.

I can do this with plain lilypond also...


    Werner


_______________________________________________
lilypond-devel mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/lilypond-devel