lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Parsing lyrics in a music function


From: Michael Ellis
Subject: Re: Parsing lyrics in a music function
Date: Thu, 15 Sep 2011 15:45:40 -0400


On Thu, Sep 15, 2011 at 3:16 PM, David Kastrup <address@hidden> wrote:
Michael Ellis <address@hidden> writes:

> I've written some music functions I use frequently to operate on
> lyrics.  For example, there's one call "lacc" that allows me to
> intermix lyrics and notation by accumulating the lyrics into a list I
> can instantiate later in the \score block.   Very nice and convenient,
> but the usage is a little messy:
>
>
> \lacc \lyricmode { This is a ly -- ric line. }
> c4 d e f | g a
>
> \lacc \lyricmode { Here is the next. }
> b c  | d c2. |
>
> Normally, I deal with the messiness by defining a keystroke macro in
> my editor that wraps a line of bare text in the necessary commands and
> braces.  I now find myself   (skipping a long story)  needing to work
> in an environment where keystroke macros will not be available.  
>
> Is it possible to define a music function that will do the work of my
> keystroke macro?  Ideally I'd like to be able to  write in an input
> file something like
>
> \lyr This is a lyric line
>
> and have LilyPond do the rest,  but none of my attempts thus far have
> worked.

The arguments of a music function are parsed before it is called, so
no.  However, if you already are in lyrics mode, you can pick up the
music in that manner.  You may also think about doing

\lacc " This is a lyric line "

and then using ly:parser-parse-string to pick up lyricmode expressions.
It might be nice at one point of time to be able to call #{ \lyricmode
\somefunction-taking-a-music-argument #} or similar trickery, but this
kind of closure is not available yet.

Thanks, David.  I figured it must be a parsing issue so it's nice to have it clarified by someone knowledgable.   I like the ly:parser-parse-string idea.  Does that function return a music object if the parsing is successful?  

Would it work to have my \lacc function massage the string so that it becomes 

"\lyricmode { This is a lyric line }" 

and then call ly:parser-parse-string to return the result?

For reference (and in case someone else might find it useful) here is the complete set of functions I currently have:

%% --------------------------------------------
#(define (make-music-accumulator)
  (define acc '())

  (define (add lyr) 
    (set! acc (append acc lyr)))

  (define (get) acc)

  (define (interface op . rest)
    (cond
      ((eq? op 'add)
        (add (car rest)))
      ((eq? op 'get)
        (get))
      (else (error "Undefined operation"))))

  interface) 

#(define defaultLyricAccumulator (make-music-accumulator))

lacc = 
#(define-music-function (parser location music) (ly:music?)
  "For accumulating lyrics mixed with notation"
  (defaultLyricAccumulator 
    'add 
    (ly:music-property music 'elements))
  (make-music 'SequentialMusic 'void #t))



getLyrics = 
#(define-music-function (parser location) ()
 "for retrieving accumulated lyrics."
  (make-music 
    'SequentialMusic 
    'elements 
    (defaultLyricAccumulator 'get))) 
    
%% --------------------------------------------


reply via email to

[Prev in Thread] Current Thread [Next in Thread]