lilypond-user
[Top][All Lists]
Advanced

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

Re: Argument transfer?


From: Nicolas Sceaux
Subject: Re: Argument transfer?
Date: Tue, 07 Jun 2005 23:22:42 +0200
User-agent: Gnus/5.1007 (Gnus v5.10.7) Emacs/21.4 (gnu/linux)

Nicolas Sceaux <address@hidden> writes:

> I would like to see a real example where a pre processor is a win over
> using LilyPond's built-in extensibility capabilities, which many seem
> to underestimate.

To be more precise about how extensible LilyPond is, I'll show an
example of a file I'm working on, which is a unit test file for a
`display-lily-music' function: this function takes a music expression
(the scheme internal representation) and outputs a string,
representing the music expression using LilyPond notation. For
instance:

guile> (display-lily-music #{ \bar "||" #})
{ \bar "||"
  }

The test file looks like:

{
  ##[ << { a b } \\ { c d } >> #]
  ##[ < c\1 e\3 >4.*3/4-. #]
  ##[ { c1 \afterGrace { b,16 c } d2 } #]
  ##[ { \makeClusters { c4 g } } #]
  ##[ \tempo 4 = 120 #]
  ##[ \clef "alto_3" #]
  ##[ \time 2/4 #]
  ##[ \bar "|." #]
  ##[ \once \set Score . skipBars = ##t #]
}

What this snippet does, is parsing the expression between #[ and #],
which gives a internal music expression, then calling the
`display-lily-music' function, to get back a string. The input and
this output string are compared, and if they are different, a report
is printed in the output score. For instance, if the file contains:

  {
    ##[ \figures { < 6 > } #]
  }

Then the resulting score contains the following markups:

  \figures { < 6 > }
  \new FiguredBass \figuremode { < 6 > }

showing that a difference has been found. No preprocessor needed.

For the curious, the definition of the #[ #] syntax, defined in the
top of the test file (no hacking LilyPond's core needed):


%%%
%%% Utilities
%%%
#(begin
  (init-print-lily parser)
  (define gen-lily-sym
    ;; Generate a lilyvartmpXX symbol, that may be (hopefully) unique.
    (let ((var-idx -1))
      (lambda ()
        (set! var-idx (1+ var-idx))
        (string->symbol (format #f "lilyvartmp~a"
                                (list->string (map (lambda (chr)
                                                     (integer->char (+ 
(char->integer #\a) (- (char->integer chr)
                                                                                
              (char->integer #\0)))))
                                                   (string->list 
(number->string var-idx)))))))))
  
  (define (my-parse-string-result str parser module)
    "Parse `str', which is supposed to contain a music expression."
    (let ((music-sym (gen-lily-sym)))
      (ly:parser-parse-string
       parser
       (format #f "
  ~a = \\notemode { ~a }
  #(ly:export '~a)
  #(module-define! (resolve-module '~a) '~a ~a)
  "
               music-sym str music-sym (module-name module) music-sym 
music-sym))
    (eval `,music-sym module)))
  
  (define (my-read-lily-expression chr port)
    (let ((lily-string (call-with-output-string
                        (lambda (out)
                          (do ((c (read-char port) (read-char port)))
                              ((and (char=? c #\#)
                                    (char=? (peek-char port) #\]))
                               (read-char port))
                            (display c out))))))
      `(let* ((parser-clone (ly:clone-parser parser))
              (input-str (string-trim-both ,lily-string))
              (music (car (ly:music-property 
                           (my-parse-string-result input-str parser-clone 
(current-module))
                           'elements)))
              (result-str (string-trim-both (print-lily-music music))))
         (if (string=? input-str result-str)
             (ly:export (make-music 'SequentialMusic))
             (ly:export
              (make-music
               'SimultaneousMusic
               'elements
               (list (make-music
                      'ContextSpeccedMusic
                      'context-id
                      "$uniqueContextId"
                      'property-operations
                      '()
                      'context-type
                      'Lyrics
                      'element
                      (make-music
                       'SequentialMusic
                       'elements
                       (list (make-music
                              'EventChord
                              'elements
                              (list (make-music
                                     'LyricEvent
                                     'duration
                                     (ly:make-duration 2 0 1 1)
                                     'text
                                     (markup #:simple input-str)))))))
                     (make-music
                      'ContextSpeccedMusic
                      'context-id
                      "$uniqueContextId"
                      'property-operations
                      '()
                      'context-type
                      'Lyrics
                      'element
                      (make-music
                       'SequentialMusic
                       'elements
                       (list (make-music
                              'EventChord
                              'elements
                              (list (make-music
                                     'LyricEvent
                                     'duration
                                     (ly:make-duration 2 0 1 1)
                                     'text
                                     (markup #:simple result-str))))
                             (make-music
                              'EventChord
                              'elements
                              (list (make-music
                                     'BreakEvent
                                     'page-penalty
                                     0
                                     'penalty
                                     -10001)))))))))))))
  
  (read-hash-extend #\[ my-read-lily-expression))

nicolas




reply via email to

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