[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Macro pre-processing?
From: |
Nicolas Sceaux |
Subject: |
Re: Macro pre-processing? |
Date: |
Mon, 01 May 2006 23:43:12 +0200 |
User-agent: |
Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (darwin) |
"Rick Hansen (aka RickH)" <address@hidden> writes:
> Nice, will it will basically generate source code AFTER the \include files
> are merged but BEFORE compilation by LP occurs? The ability to modularize
> source code generation into macros would be valuable, kind of like "smart"
> \include files, where one can generate conditional LP music source code.
May you quote the original message to which your answering? it's not
easy to guess what you're talking about? I suppose you're answering to
Geoff's post about pre processor.
>> In two weeks, when I'm done with finals, I'll revisit my roughed-out
>> preprocessor and see if it can be made usable and easy.
Anyway, "smart" includes are already possible with LilyPond.
For instance, it's usual to see the following in a LilyPond file:
-- pieceA/lead-score.ly --
| global = {
| \key g \major
| \time 3/4
| s2.*27 \bar "|."
| }
|
| \score {
| ...
| \new Staff << \global { ..music1.. } >>
| \new Staff << \global { ..music2.. } >>
| ...
-------------------
When you build several version of a score (eg. lead score, separate
parts, etc), you put the content of the global variable in its own file:
-- pieceA/global.ily --
| \key g \major
| \time 3/4
| s2.*27 \bar "|."
----------------
and then, in each score file:
-- pieceA/lead-score.ly --
| global = { \include "pieceA/global.ily" }
| \score {
| ...
| \new Staff << \global { ..music1.. } >>
| \new Staff << \global { ..music2.. } >>
| ...
| }
-------------------
But then there is a pattern, the global variable affectation repeated in
each main score file.
So you define a music function, that will automatically include the
global.ily the first time it is invoked, and the following ones just
return what has already been loaded:
Supposing that (*cuurent-piece*) holds the identifier of the piece (I
use such identifiers to distinguate the different pieces in a book, and
to designate the drectory in which the piece files are placed, "pieceA"
above):
global =
#(define-music-function (parser location) ()
(let* ((global-symbol (string->symbol (format "global~a"
(*current-piece*))))
(global-music (ly:parser-lookup parser global-symbol)))
(if (not (ly:music? global-music))
(let* ((global-file (string-append (*current-piece*) "/global.ily")))
(set! global-music #{ \include $global-file #})
(ly:parser-define! parser global-symbol global-music)))
(ly:music-deep-copy global-music)))
[By the way, here you see an example of a music function using the
parser argument].
Then, all you have to write in your score files is:
-- pieceA/lead-score.ly --
| \score {
| ...
| \new Staff << \global { ..music1.. } >>
| \new Staff << \global { ..music2.. } >>
| ...
| }
-------------------
the pieceA/global.ily file is then auto-included.
But then you have to tell lilypond the identifier of each score, so the
benefit is not evident. Let's create another function to include a piece
in the main file, which will set the identifier of the piece.
---- common.ily ----
| #(use-modules (srfi srfi-39))
| #(define *current-piece* (make-parameter ""))
|
| includeScore =
| #(define-music-function (parser location name) (string?)
| (parameterize ((*current-piece* name))
| (ly:parser-parse-string (ly:clone-parser parser)
| (string-append "\\include \"" name
"/score.ily\""))
| (make-music 'SequentialMusic 'void #t)))
|
| global =
| #(define-music-function (parser location) ()
| (let* ((global-symbol (string->symbol (format "global~a"
(*current-piece*))))
| (global-music (ly:parser-lookup parser global-symbol)))
| (if (not (ly:music? global-music))
| (let* ((global-file (string-append (*current-piece*) "/global.ily")))
| (set! global-music #{ \include $global-file #})
| (ly:parser-define! parser global-symbol global-music)))
| (ly:music-deep-copy global-music)))
---- common.ily ----
---- main.ly ----
| \include "common.ily"
|
| %% includes pieceA/score.ily and sets (*current-piece*) to pieceA
| \includeScore "pieceA"
| \includeScore "pieceB"
| ...
---- main.ly ----
---- pieceA/score.ily ----
| \score {
| <<
| \new Staff << \global { ..music1.. } >>
| \new Staff << \global { ..music2.. } >>
| >>
| }
---- pieceA/score.ily ----
---- pieceA/global.ily ----
| \key g \major
| \time 3/4
| s2.*27 \bar "|."
---- pieceA/global.ily ----
etc.
nicolas
- Re: Macro pre-processing?, (continued)
- Re: Macro pre-processing?, David Feuer, 2006/05/02
- Re: Macro pre-processing?, Werner LEMBERG, 2006/05/02
- Re: Macro pre-processing?, Rick Hansen (aka RickH), 2006/05/02
- Re: Macro pre-processing?, David Feuer, 2006/05/02
- Re: Macro pre-processing?, Paul Scott, 2006/05/02
Re: Macro pre-processing?, Rick Hansen (aka RickH), 2006/05/01
Re: Macro pre-processing?, joe ferguson, 2006/05/02
Re: Macro pre-processing?, Eduardo Vieira, 2006/05/03