Hello, Here is a patch for the #{ $music #} feature, following Han-Wen's suggestions.
Index: ChangeLog =================================================================== RCS file: /cvsroot/lilypond/lilypond/ChangeLog,v retrieving revision 1.2168 diff -u -r1.2168 ChangeLog --- ChangeLog 10 May 2004 19:00:18 -0000 1.2168 +++ ChangeLog 13 May 2004 14:44:38 -0000 @@ -1,3 +1,16 @@ +2004-05-13 Nicolas Sceaux <[EMAIL PROTECTED]> + + * scm/ly-from-scheme.scm (read-lily-expression): A variable + refering to a music expression can be used in lily-inside-scheme: + #{ $music #} + + * lily/my-lily-parser.cc (LY_DEFINE): introduce ly:clone-parser + and ly:parser-define, and change ly:parser-parse-string in order + to make #{ $music #} work. + + * scm/new-markup.scm (compile-markup-expression): when an argument + is a string, use `make-simple-markup'. + 2004-05-10 Han-Wen Nienhuys <[EMAIL PROTECTED]> * scripts/convert-ly.py (FatalConversionError.func): handle + in Index: lily/my-lily-parser.cc =================================================================== RCS file: /cvsroot/lilypond/lilypond/lily/my-lily-parser.cc,v retrieving revision 1.118 diff -u -r1.118 my-lily-parser.cc --- lily/my-lily-parser.cc 9 May 2004 11:15:48 -0000 1.118 +++ lily/my-lily-parser.cc 13 May 2004 14:44:48 -0000 @@ -310,6 +310,27 @@ return SCM_UNSPECIFIED; } +LY_DEFINE (ly_clone_parser, "ly:clone-parser", + 1, 0, 0, + (SCM parser_smob), + "Return a clone of PARSER_SMOB.") +{ + My_lily_parser *parser = unsmob_my_lily_parser (parser_smob); + My_lily_parser *clone = new My_lily_parser (*parser); + return clone->self_scm (); +} + +LY_DEFINE(ly_parser_define, "ly:parser-define", + 3, 0, 0, + (SCM parser_smob, SCM symbol, SCM val), + "Bind SYMBOL to VAL in PARSER_SMOB's module.") +{ + SCM_ASSERT_TYPE (ly_c_symbol_p (symbol), symbol, SCM_ARG1, __FUNCTION__, "symbol"); + My_lily_parser *parser = unsmob_my_lily_parser (parser_smob); + parser->lexer_->set_identifier (scm_symbol_to_string (symbol), val); + return SCM_UNSPECIFIED; +} + LY_DEFINE (ly_parser_parse_string, "ly:parser-parse-string", 2, 0, 0, (SCM parser_smob, SCM ly_code), @@ -321,7 +342,7 @@ #endif SCM_ASSERT_TYPE (ly_c_string_p (ly_code), ly_code, SCM_ARG1, __FUNCTION__, "string"); -#if 0 +#if 1 My_lily_parser *parser = unsmob_my_lily_parser (parser_smob); parser->parse_string (ly_scm2string (ly_code)); #else Index: scm/ly-from-scheme.scm =================================================================== RCS file: /cvsroot/lilypond/lilypond/scm/ly-from-scheme.scm,v retrieving revision 1.2 diff -u -r1.2 ly-from-scheme.scm --- scm/ly-from-scheme.scm 29 Apr 2004 14:49:52 -0000 1.2 +++ scm/ly-from-scheme.scm 13 May 2004 14:44:51 -0000 @@ -16,7 +16,7 @@ (char->integer #\0))))) (string->list (number->string var-idx))))))))) -(define-public (ly:parse-string-result str module) +(define-public (ly: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 @@ -34,27 +34,50 @@ the scheme music expression. The $ character may be used to introduce scheme forms, typically symbols. $$ may be used to simply write a `$' character." - (let* ((format-args '()) - (lily-string (with-output-to-string - (lambda () + (let ((bindings '())) + (define (create-binding! val) + "Create a new symbol, bind it to `val' and return it." + (let ((tmp-symbol (gen-lily-sym))) + (set! bindings (cons (cons tmp-symbol val) bindings)) + tmp-symbol)) + (define (remove-dollars! form) + "Generate a form where `$variable' and `$ value' mottos are replaced + by new symbols, which are binded to the adequate values." + (cond (;; $variable + (and (symbol? form) + (string=? (substring (symbol->string form) 0 1) "$") + (not (string=? (substring (symbol->string form) 1 2) "$"))) + (create-binding! (string->symbol (substring (symbol->string form) 1)))) + (;; atom + (not (pair? form)) form) + (;; ($ value ...) + (eqv? (car form) '$) + (cons (create-binding! (cadr form)) (remove-dollars! (cddr form)))) + (else ;; (something ...) + (cons (remove-dollars! (car form)) (remove-dollars! (cdr form)))))) + (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)) - (cond ((and (char=? c #\$) - (not (char=? (peek-char port) #\$))) - ;; a $variable - (display "~a") - (set! format-args (cons (read port) -format-args))) - ((and (char=? c #\$) - (char=? (peek-char port) #\$)) - ;; just a $ character - (display (read-char port))) - (else - ;; other caracters - (display c)))))))) - `(ly:parse-string-result (format #f ,lily-string ,@(reverse! format-args)) - (current-module)))) + ((and (char=? c #\#) + (char=? (peek-char port) #\})) ;; we stop when #} is encoutered + (read-char port)) + (cond + ;; a $form expression + ((and (char=? c #\$) (not (char=? (peek-char port) #\$))) + (format out "\\~a" (create-binding! (read port)))) + ;; just a $ character + ((and (char=? c #\$) (char=? (peek-char port) #\$)) + (display (read-char port) out)) ;; pop the second $ + ;; a #scheme expression + ((char=? c #\#) + (format out "#~a" (remove-dollars! (read port)))) + ;; other caracters + (else + (display c out)))))))) + `(let ((parser-clone (ly:clone-parser parser))) + ,@(map (lambda (binding) + `(ly:parser-define parser-clone ',(car binding) ,(cdr binding))) + (reverse bindings)) + (ly:parse-string-result ,lily-string parser-clone (current-module)))))) (read-hash-extend #\{ read-lily-expression) Index: scm/new-markup.scm =================================================================== RCS file: /cvsroot/lilypond/lilypond/scm/new-markup.scm,v retrieving revision 1.75 diff -u -r1.75 new-markup.scm --- scm/new-markup.scm 22 Mar 2004 14:55:36 -0000 1.75 +++ scm/new-markup.scm 13 May 2004 14:44:51 -0000 @@ -175,8 +175,11 @@ ;; expr === ((#:COMMAND arg1 ...) ...) (receive (m r) (compile-markup-expression (car expr)) (values m (cdr expr)))) + ((and (pair? expr) + (string? (car expr))) ;; expr === ("string" ...) + (values `(make-simple-markup ,(car expr)) (cdr expr))) (else - ;; expr === (symbol ...) or ("string" ...) or ((funcall ...) ...) + ;; expr === (symbol ...) or ((funcall ...) ...) (values (car expr) (cdr expr)))))
It makes it possible to write, eg: / | foo = \notes { d'^\markup \bold "hello" \appoggiatura f' e' } | | #(define (aroundify music dy) | #{ \notes { c' | \override TextScript #'extra-offset = #(cons $(* 2 dy) $dy) | $music | f' } #}) | | baz = #(aroundify foo 2) | | \score { \notes { \baz } } \ Does it seem commitable? nicolas
_______________________________________________ lilypond-devel mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/lilypond-devel