Add shortcuts for manual sub-beaming
[opus_libre.git] / bin / macros.scm
bloba6d5aa74c5479774e3552bd882cca832e507392e
1 ;------------------------------------------------------------------;
2 ; opus_libre -- macros.scm                                         ;
3 ;                                                                  ;
4 ; (c) 2008-2011 Valentin Villenave <valentin@villenave.net>        ;
5 ;                                                                  ;
6 ;     opus_libre is a free framework for GNU LilyPond: you may     ;
7 ; redistribute it and/or modify it under the terms of the GNU      ;
8 ; General Public License as published by the Free Software         ;
9 ; Foundation, either version 3 of the License, or (at your option) ;
10 ; any later version.                                               ;
11 ;     This program is distributed WITHOUT ANY WARRANTY; without    ;
12 ; even the implied warranty of MERCHANTABILITY or FITNESS FOR A    ;
13 ; PARTICULAR PURPOSE.  You should have received a copy of the GNU  ;
14 ; General Public License along with this program (typically in the ;
15 ; share/doc/ directory).  If not, see http://www.gnu.org/licenses/ ;
16 ;                                                                  ;
17 ;------------------------------------------------------------------;
20 ; Input macros.
22 (load "../lib/libmusic.scm")
24 ;; TODO: use make-simple-function everywhere possible.
26 ;; Rhythm shortcuts -----------------------------------------------;
27 (make-function lang:tuplet-letter ; default: \t
28   (define-music-function (parser location span music)
29     ((ly:duration? '()) ly:music?)
30     #{ \tuplet 3/2 $(if (not-null? span) span) $music #}))
32 (make-function lang:tuplet-letter-double ; \tt
33   (define-music-function (parser location span music)
34     ((ly:duration? '()) ly:music?)
35     #{ \tuplet 5/4 $(if (not-null? span) span) $music #}))
37 (make-function lang:tuplet-letter-triple ; \ttt
38   (define-music-function (parser location span music)
39     ((ly:duration? '()) ly:music?)
40     #{ \tuplet 6/4 $(if (not-null? span) span) $music #}))
42 (make-function lang:tuplet-letter-quad ; \tttt
43   (define-music-function (parser location span music)
44     ((ly:duration? '()) ly:music?)
45     #{ \tuplet 7/4 $(if (not-null? span) span) $music #}))
48 ;; Time signature equivalence
49 (define equiv
50  (define-music-function (parser location str) (string?)
51    (let* ((mark-ev (make-music 'MarkEvent))
52           (mark-ch (make-event-chord (list mark-ev)))
53           (equiv-lst (string-split str #\= ))
54           (before (parse-my-duration (car equiv-lst)))
55           (after (parse-my-duration (cadr equiv-lst)))
56           (before-mark (make-note-by-number-markup (car before) (cadr before) 1))
57           (after-mark (make-note-by-number-markup (car after) (cadr after) 1))
58           (equiv-mark
59             (make-concat-markup
60               (list
61                 (make-general-align-markup Y DOWN
62                   (make-smaller-markup before-mark))
63                 (make-simple-markup " ")
64                 (make-simple-markup "=")
65                 (make-simple-markup " ")
66                 (make-general-align-markup Y DOWN
67                   (make-smaller-markup after-mark))
68                 )))
69           (mark-set (context-spec-music
70               (make-property-set 'rehearsalMark equiv-mark)
71               'Score)))
72          (ly:music-set-property! mark-ev 'origin location)
73          (ly:music-set-property! mark-ev 'label equiv-mark)
74          mark-ch)))
76 ;; Auto octavation ------------------------------------------------;
77 (define oct
78   (define-music-function (parser location x) (ly:music?)
79     (octavize x)))
81 ;; Polyphony shortcuts --------------------------------------------;
82 (define pl
83   (define-music-function (parser location one two)
84     (ly:music? ly:music?)
85     #{ << { \voiceTwo $one } \\ { \voiceOne $two } >> #}))
87 (staff-change-command lang:upper-hand) ;; depending on your input language:
88 (staff-change-command lang:lower-hand) ;; \rh or \md etc. for switching staves.
90 ;; Hiding stuff ---------------------------------------------------;
91 (define hideNote #{
92 \once \override Dots #'transparent = ##t
93 \once \override NoteHead #'transparent = ##t
94 \once \override NoteHead #'no-ledgers = ##t
95 \once \override Stem #'transparent = ##t
96 \once \override Flag #'transparent = ##t
97 \once \override Beam #'transparent = ##t
98 \once \override Accidental #'transparent = ##t
99 #})
101 (define hideNoteHead #{
102 \once \override NoteHead #'transparent = ##t
105 (define hideNoteHeads
106   (define-music-function (parser location x) (ly:music?)
107   #{\override NoteHead #'transparent = ##t $x \revert NoteHead #'transparent #}))
109 (define noTuplet #{
110 \once \override TupletBracket #'transparent = ##t
111 \once \override TupletNumber #'transparent = ##t
114 (define noTuplets
115   (define-music-function (parser location x) (ly:music?)
116   #{
117 \override TupletBracket #'transparent = ##t
118 \override TupletNumber #'transparent = ##t
120 \revert TupletBracket #'transparent
121 \revert TupletNumber #'transparent
122 #}))
124 (define tupletsOff #{
125 \override TupletBracket #'transparent = ##t
126 \override TupletNumber #'transparent = ##t
129 (define tupletsOn #{
130 \override TupletBracket #'transparent = ##f
131 \override TupletNumber #'transparent = ##f
135 ;; Stems and beaming ----------------------------------------------;
136 (define oneStemDown #{
137 \once \override Stem #'direction = #DOWN
140 (define oneStemUp #{
141 \once \override Stem #'direction = #UP
144 (define graceNote #{
145 %% Pasted from graceSettings definition in engraver-init.ly
146 %% \once \override Stem #'direction = #UP
147 \once \override Stem #'font-size = #-3
148 \once \override NoteHead #'font-size = #-3
149 \once \override TabNoteHead #'font-size = #-4
150 \once \override Dots #'font-size = #-3
151 \once \override Stem #'length-fraction = #0.8
152 \once \override Flag #'font-size = #-3
153 %% \once \override Stem #'no-stem-extend = ##t
154 \once \override Beam #'beam-thickness = #0.384
155 \once \override Beam #'length-fraction = #0.8
156 \once \override Accidental #'font-size = #-4
157 \once \override AccidentalCautionary #'font-size = #-4
158 %% \once \override Slur #'direction = #DOWN
159 \once \override Script #'font-size = #-3
160 \once \override Fingering #'font-size = #-8
161 \once \override StringNumber #'font-size = #-8
164 (define graceNotes
165   (define-music-function (parser location x) (ly:music?)
166   #{
167 %% \override Stem #'direction = #UP %% Nope.
168 \override Stem #'font-size = #-3
169 \override Flag #'font-size = #-3
170 \override NoteHead #'font-size = #-3
171 \override TabNoteHead #'font-size = #-4
172 \override Dots #'font-size = #-3
173 \override Stem #'length-fraction = #0.8
174 %% \override Stem #'no-stem-extend = ##t %% Not sure.
175 \override Beam #'beam-thickness = #0.384
176 \override Beam #'length-fraction = #0.8
177 \override Accidental #'font-size = #-4
178 \override AccidentalCautionary #'font-size = #-4
179 %% \override Slur #'direction = #DOWN
180 \override Script #'font-size = #-3
181 \override Fingering #'font-size = #-8
182 \override StringNumber #'font-size = #-8
184 %% \revert Stem #'direction
185 \revert Stem #'font-size
186 \revert NoteHead #'font-size
187 \revert TabNoteHead #'font-size
188 \revert Dots #'font-size
189 \revert Stem #'length-fraction
190 %% \revert Stem #'no-stem-extend
191 \revert Beam #'beam-thickness
192 \revert Beam #'length-fraction
193 \revert Accidental #'font-size
194 \revert AccidentalCautionary #'font-size
195 %% \revert Slur #'direction
196 \revert Script #'font-size
197 \revert Fingering #'font-size
198 \revert StringNumber #'font-size
199 #}))
201 (define lightBeam #{
202 \once \override Beam #'beam-thickness = #0.384
203 \once \override Beam #'gap = #0.5
204 \override Flag #'font-size = #-3
207 (define lightBeams
208   (define-music-function (parser location x) (ly:music?) #{
209 \override Beam #'beam-thickness = #0.384
210 \override Beam #'gap = #0.5
211 \override Flag #'font-size = #-3
213 \revert Beam #'beam-thickness
214 \revert Beam #'gap
215 \revert Flag #'font-size
216 #}))
218 (define fullBeat #{
219 \set baseMoment = #(ly:make-moment 1 4)
220 ; the beatStructure length doesn’t really matter here,
221 ; 16 should be enough for most cases.
222 \set beatStructure = #'(1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
225 (define halfBeat #{
226 \set baseMoment = #(ly:make-moment 1 8)
227 \set beatStructure = #'(2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2)
230 (define quarterBeat #{
231 \set baseMoment = #(ly:make-moment 1 6)
232 \set beatStructure = #'(4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4)
236 ;; Expressive marks -----------------------------------------------;
237 (define longHairpin #{
238 \once \override Hairpin #'to-barline = ##f
241 (define longHairpins
242   (define-music-function (parser location x) (ly:music?) #{
243 \override Hairpin #'to-barline = ##f
245 \revert Hairpin #'to-barline
246 #}))
249 ;; Custom note heads ----------------------------------------------;
250 (define whiteNote
251   (define-music-function (parser location x) (ly:music?)
252     (set! (ly:music-property x 'tweaks)
253                                (acons 'duration-log 1
254                                   (ly:music-property x 'tweaks)))
255                          x))
257 (define blackNote
258   (define-music-function (parser location x) (ly:music?)
259     (set! (ly:music-property x 'tweaks)
260        (acons 'before-line-breaking
261               (lambda (grob)
262                 (let ((dots (ly:grob-object grob 'dot)))
263                   (ly:grob-set-property! grob 'duration-log 2)
264                   (and (ly:grob? dots)
265                        (ly:grob-set-property! dots 'dot-count 0))))
266               (ly:music-property x 'tweaks)))
267         x))
269 (define parlato
270  (define-music-function (parser location x) (ly:music?)
272 \override NoteHead #'style = #'cross
274 \revert NoteHead #'style
275 #}))
277 (define slap ;;TODO: adapt accordingly to stem direction?
278  (define-music-function (parser location x) (ly:music?)
280 \override NoteHead #'stencil = #ly:text-interface::print
281 \override NoteHead #'text = \markup \musicglyph #"scripts.sforzato"
282 \override NoteHead #'extra-offset = #'(0.1 . 0.0 )
284 \revert NoteHead #'stencil
285 \revert NoteHead #'text
286 \revert NoteHead #'extra-offset
287 #}))
289 (define harmoChord ;; FIXME: overly complicated.
290  (define-music-function (parser location chord result) (ly:music? ly:music?)
291  #{
292 << \oneStemDown $chord \\ { \stemUp %FIXME: ties could look better.
293 \override NoteHead #'stencil = #ly:text-interface::print
294 \override NoteHead #'text = \markup { \null \musicglyph #"noteheads.s2"}
295 \once \override NoteHead #'text = \markup {\null \override #'(direction . 1)
296   \dir-column {\musicglyph #"noteheads.s2" \teeny \musicglyph #"eight"}}
297 \override Stem #'stencil = ##f $result
298 \revert Stem #'stencil \revert NoteHead #'stencil \stemNeutral } >> #}))
300 (define harmonics
301  (define-music-function (parser location x) (ly:music?)
303 \override Dots #'transparent = ##t
304 \override Stem #'transparent = ##t
305 \override Beam #'transparent = ##t
306 \override NoteHead #'style = #'harmonic
308 \revert NoteHead #'style
309 \revert Beam #'transparent
310 \revert Stem #'transparent
311 \revert Dots #'transparent #}))
313 (define smart
314  (define-music-function (parser location x) (ly:music?)
315    (naturalize x)))