1%%%% Template toolkit (common functions).
2%%%% This file is part of LilyPond, the GNU music typesetter.
3%%%%
4%%%% Copyright (C) 2015--2020 Trevor Daniels <t.daniels@treda.co.uk>
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%\version "2.19.22"
20
21%%% These are the general utility functions and storage
22%   used by the built-in templates and the template kits
23%   (tkits) supporting them.
24
25% TODO: these may be more sensibly (re)defined as a scm file
26
27#(define (get-id str)
28   "Return the identifier with the value str"
29   (ly:parser-lookup (string->symbol str)))
30
31#(define (make-id a b)
32  "Return the identifier formed from concatenating the
33   two strings provided as arguments."
34   (get-id (string-append a b)))
35
36#(define (cartesian a b)
37  "Return a list formed from concatenating every element
38   of list a with every element of list b (the cartesian
39   product a X b)."
40   (append-map
41    (lambda (x)
42      (map
43       (lambda (y)
44         (string-append x y))
45       b))
46    a))
47
48#(define (define-missing-variables! ids)
49  "Check if each of the identifiers listed in the argument is
50   known to the parser.  If any are not, define them and set
51   their value to #f"
52   (for-each
53      (lambda (id)
54        (define sym (string->symbol id))
55          (if (null? (ly:parser-lookup sym))
56            (ly:parser-define! sym #f)))
57      ids))
58
59% Define the lists used to hold the names and
60% component names which form the variable names
61% used in the templates.  These are populated by the
62% set-music-definitions! procedure
63% The variables defined here as empty lists will be provided
64% by the template, and may be set to any values there.
65#(define voice-prefixes '())   % eg "Soprano"
66#(define all-music-names '())  % eg "SopranoMusic"
67#(define lyrics-postfixes '())	% eg "Lyrics"
68#(define lyrics-names '())     % eg "VerseOne"
69
70% Define the derived variables to be populated
71#(define all-music-lyrics-names '())  % eg "SopranoLyrics"
72#(define AllMusic (make-music 'SequentialMusic 'void #t))
73#(define KeepAlive AllMusic)   % used to ensure voices don't terminate
74#(define have-music #f)        % -> #t when at least one music name
75                                %    contains music
76#(define voice-postfixes
77   ;; These names are used verbatim in code, so may not be changed
78   '("InstrumentName"
79     "MidiInstrument"
80     "Music"
81     "ShortInstrumentName"))
82
83#(define variable-names
84   ;; These names are used verbatim in code, so may not be changed
85   '("Key"
86     "Layout"
87     "PianoDynamics"
88     "Time"
89     "TwoVoicesPerStaff"))
90
91% Define the predicates used in the tkits and templates
92#(define (above-or-below? x)
93  (member x '("Above" "Below")))
94
95#(define (up-or-down? x)
96   (member x '("Down" "Up" "")))
97
98#(define (voice-prefix? x)
99   (member x voice-prefixes))
100
101#(define (vocal-lyrics-or-verses? x)
102  (or (member x lyrics-postfixes)
103      (member x lyrics-names)))
104
105
106#(define (set-music-definitions! prefixes lyr-postfixes lyr-names)
107  "Populate the name definitions and their derivatives
108   with the values provided by the calling template"
109   (set! voice-prefixes prefixes)
110   (append! variable-names lyr-names)
111   (set! all-music-names
112         (cartesian voice-prefixes '("Music")))
113   (set! lyrics-postfixes lyr-postfixes)
114   (set! lyrics-names lyr-names)
115   (set! all-music-lyrics-names
116     (cartesian voice-prefixes (append
117                                voice-postfixes
118                                lyrics-postfixes)))
119   (define-missing-variables! (append
120                                  all-music-lyrics-names
121                                  variable-names))
122   (set! AllMusic
123     (make-simultaneous-music
124      (filter ly:music?
125              (map
126               (lambda (x)
127                 (get-id x))
128               all-music-names))))
129   (set! KeepAlive
130         (skip-of-length AllMusic))
131   (set! have-music
132         (ly:moment<?
133          (ly:make-moment 0)
134          (ly:music-length KeepAlive))))
135
136