lilypond-devel
[Top][All Lists]
Advanced

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

#{ $music #}


From: Nicolas Sceaux
Subject: #{ $music #}
Date: Thu, 13 May 2004 16:57:22 +0200
User-agent: Gnus/5.1006 (Gnus v5.10.6) Emacs/21.3 (gnu/linux)

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  <address@hidden>
+
+       * 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   <address@hidden>
 
        * 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

reply via email to

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