(string-downcase
(car (string-tokenize (utsname:sysname (uname)))))))
+(define lilypond-declarations '())
+
+(defmacro-public define-session (name value)
+ "This defines a variable @var{name} with the starting value
+@var{value} that is reinitialized at the start of each session.
+A@tie{}session basically corresponds to one LilyPond file on the
+command line. The value is recorded at the start of the first session
+after loading all initialization files and before loading the user
+file and is reinstated for all of the following sessions. This
+happens just by replacing the value, not by copying structures, so you
+should not destructively modify them. For example, lists defined in
+this manner should be changed within a session only be adding material
+to their front or replacing them altogether, not by modifying parts of
+them. It is an error to call @code{define-session} after the first
+session has started."
+ (define (add-session-variable name value)
+ (if (ly:undead? lilypond-declarations)
+ (ly:error (_ "define-session used after session start")))
+ (let ((var (make-variable value)))
+ (module-add! (current-module) name var)
+ (set! lilypond-declarations (cons var lilypond-declarations))))
+ `(,add-session-variable ',name ,value))
+
+(defmacro-public define-session-public (name value)
+ "Like @code{define-session}, but also exports @var{name}."
+ `(begin
+ (define-session ,name ,value)
+ (export ,name)))
+
+(define (session-terminate)
+ (if (ly:undead? lilypond-declarations)
+ (for-each
+ (lambda (p) (variable-set! (cadr p) (cddr p)))
+ (ly:get-undead lilypond-declarations))))
+
+(define-public (session-initialize thunk)
+ "Initialize this session. The first session in a LilyPond run is
+initialized by calling @var{thunk}, then recording the values of all
+variables in the current module as well as those defined with
+@code{define-session}. Subsequent calls of @code{session-initialize}
+ignore @var{thunk} and instead just reinitialize all recorded
+variables to their value after the initial call of @var{thunk}."
+
+;; We need to save the variables of the current module along with
+;; their values: functions defined in the module might refer to the
+;; variables.
+
+;; The entries in lilypond-declarations consist of a cons* consisting
+;; of symbol, variable, and value. Variables defined with
+;; define-session have the symbol set to #f.
+
+ (if (ly:undead? lilypond-declarations)
+ (begin
+ (for-each
+ (lambda (p)
+ (let ((var (cadr p))
+ (val (cddr p)))
+ (variable-set! var val)
+ (if (car p)
+ (module-add! (current-module) (car p) var))))
+ (ly:get-undead lilypond-declarations)))
+ (begin
+ (thunk)
+ (let ((decl (map! (lambda (v)
+ (cons* #f v (variable-ref v)))
+ lilypond-declarations)))
+ (module-for-each
+ (lambda (s v)
+ (let ((val (variable-ref v)))
+ (if (not (ly:lily-parser? val))
+ (set! decl
+ (cons
+ (cons* s v val)
+ decl)))))
+ (current-module))
+ (set! lilypond-declarations (ly:make-undead decl))))))
+
(define scheme-options-definitions
`(
;; NAMING: either
"define-grobs.scm"
"define-grob-interfaces.scm"
"define-stencil-commands.scm"
+ "scheme-engravers.scm"
"titling.scm"
"text.scm"
(,fraction? . "fraction, as pair")
(,grob-list? . "list of grobs")
(,index? . "non-negative integer")
- ;; this is built on cheap-list
- (,list-or-symbol? . "list or symbol")
(,markup? . "markup")
(,markup-command-list? . "markup command list")
(,markup-list? . "markup list")
(,moment-pair? . "pair of moment objects")
(,number-list? . "number list")
(,number-or-grob? . "number or grob")
+ (,number-or-markup? . "number or markup")
(,number-or-pair? . "number or pair")
(,number-or-string? . "number or string")
(,number-pair? . "pair of numbers")
(,string-or-pair? . "string or pair")
(,string-or-music? . "string or music")
(,string-or-symbol? . "string or symbol")
+ (,symbol-list? . "symbol list")
+ (,symbol-list-or-music? . "symbol list or music")
+ (,symbol-list-or-symbol? . "symbol list or symbol")
(,void? . "void")
))
(> (string-length s) 0))
(apply append
(map (lambda (f)
- (string-split (ly:gulp-file f) #\nl))
+ (string-split (string-delete (ly:gulp-file f) #\cr) #\nl))
files)))))
(if (and (number? (ly:get-option 'job-count))
(>= (length files) (ly:get-option 'job-count)))
(mtrace:start-trace (ly:get-option 'trace-memory-frequency)))
(lilypond-file handler x)
(ly:check-expected-warnings)
+ (session-terminate)
(if start-measurements
(dump-profile x start-measurements (profile-measurements)))
(if (ly:get-option 'trace-memory-frequency)
(dump-profile "lily-run-total" '(0 0) (profile-measurements)))
failed))
-(define-public lilypond-declarations '())
-
(define (lilypond-file handler file-name)
(catch 'ly-file-failed
(lambda () (ly:parse-file file-name))