]> git.donarmstrong.com Git - lilypond.git/blob - scm/parser-ly-from-scheme.scm
Add '-dcrop' option to ps and svg backends
[lilypond.git] / scm / parser-ly-from-scheme.scm
1 ;;;; This file is part of LilyPond, the GNU music typesetter.
2 ;;;;
3 ;;;; Copyright (C) 2004--2015  Nicolas Sceaux  <nicolas.sceaux@free.fr>
4 ;;;;           Jan Nieuwenhuizen <janneke@gnu.org>
5 ;;;;
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.
10 ;;;;
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.
15 ;;;;
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/>.
18
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."
23   (let* ((closures '())
24          (filename (port-filename port))
25          (line (port-line port))
26          (lily-string (call-with-output-string
27                        (lambda (out)
28                          (let ((copycat
29                                 (make-soft-port
30                                  (vector #f #f #f
31                                          (lambda ()
32                                            (let ((x (read-char port)))
33                                              (write-char x out)
34                                              x)) #f)
35                                  "r")))
36                            (set-port-filename! copycat filename)
37                            (do ((c (read-char port) (read-char port)))
38                                ((and (char=? c #\#)
39                                      (char=? (peek-char port) #\}))
40                                 ;; we stop when #} is encountered
41                                 (read-char port))
42                              (write-char c out)
43                              ;; a #scheme or $scheme expression
44                              (if (or (char=? c #\#) (char=? c #\$))
45                                  (let* ((p (ftell out))
46                                         (expr
47                                          (begin
48                                            (set-port-line! copycat
49                                                            (port-line port))
50                                            (set-port-column! copycat
51                                                              (port-column port))
52                                            (if (char=? (peek-char port) #\@)
53                                                (read-char copycat))
54                                            (read copycat))))
55                                    ;; kill unused lookahead, it has been
56                                    ;; written out already
57                                    (drain-input copycat)
58                                    ;; only put symbols and non-quote
59                                    ;; lists into closures -- constants
60                                    ;; don't need lexical environments
61                                    ;; for evaluation.
62                                    (if (or (symbol? expr)
63                                            (and (pair? expr)
64                                                 (not (eq? 'quote (car expr)))))
65                                        (set! closures
66                                              (cons `(cons ,p (lambda () ,expr))
67                                                    closures)))))))))))
68     (define (embedded-lilypond lily-string filename line closures)
69       (let* ((clone (ly:parser-clone closures (*location*)))
70              (result (ly:parse-string-expression clone lily-string
71                                                  filename line)))
72         (if (ly:parser-has-error? clone)
73             (ly:parser-error (_ "error in #{ ... #}") (*location*)))
74         result))
75     (list embedded-lilypond
76           lily-string filename line
77           (cons 'list (reverse! closures)))))
78
79 (read-hash-extend #\{ read-lily-expression)