1 ;;;; This file is part of LilyPond, the GNU music typesetter.
3 ;;;; Copyright (C) 2004--2012 Nicolas Sceaux <nicolas.sceaux@free.fr>
4 ;;;; Jan Nieuwenhuizen <janneke@gnu.org>
6 ;;;; LilyPond is free software: you can redistribute it and/or modify
7 ;;;; it under the terms of the GNU General Public License as published by
8 ;;;; the Free Software Foundation, either version 3 of the License, or
9 ;;;; (at your option) any later version.
11 ;;;; LilyPond is distributed in the hope that it will be useful,
12 ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ;;;; GNU General Public License for more details.
16 ;;;; You should have received a copy of the GNU General Public License
17 ;;;; along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
19 (define-public (read-lily-expression chr port)
20 "Read a lilypond music expression enclosed within @code{#@{} and @code{#@}}
21 from @var{port} and return the corresponding Scheme music expression.
22 @samp{$} and @samp{#} introduce immediate and normal Scheme forms."
24 (filename (port-filename port))
25 (line (port-line port))
26 (lily-string (call-with-output-string
32 (let ((x (read-char port)))
36 (set-port-filename! copycat filename)
37 (do ((c (read-char port) (read-char port)))
39 (char=? (peek-char port) #\}))
40 ;; we stop when #} is encountered
43 ;; a #scheme or $scheme expression
44 (if (or (char=? c #\#) (char=? c #\$))
45 (let* ((p (ftell out))
48 (set-port-line! copycat
50 (set-port-column! copycat
52 (if (char=? (peek-char port) #\@)
55 ;; kill unused lookahead, it has been
56 ;; written out already
58 ;; only put symbols and non-quote
59 ;; lists into closures -- constants
60 ;; don't need lexical environments
62 (if (or (symbol? expr)
64 (not (eq? 'quote (car expr)))))
66 (cons `(cons ,p (lambda () ,expr))
68 (define (embedded-lilypond parser lily-string filename line closures)
69 (let* ((clone (ly:parser-clone parser closures))
70 (result (ly:parse-string-expression clone lily-string
72 (if (ly:parser-has-error? clone)
73 (ly:parser-error parser (_ "error in #{ ... #}")))
75 (list embedded-lilypond 'parser lily-string filename line (cons 'list (reverse! closures)))))
77 (read-hash-extend #\{ read-lily-expression)