]> git.donarmstrong.com Git - lilypond.git/blob - Documentation/user/features.tely
patch::: 1.3.121.jcn1
[lilypond.git] / Documentation / user / features.tely
1 \input texinfo @c -*-texinfo-*-
2 @setfilename features.info
3 @settitle GNU LilyPond Features
4
5 @ignore
6 TODO
7   * add more un/badly documented features
8   * write some text
9   * add to/merge with refman
10
11
12   
13   there's a very simple, very general noXXX mechanism; try
14
15 noop    \property Staff.VoltaBrace = #'()
16 yes: \property Staff.VoltaBracket = #'((meta .  ((interfaces . ()))))
17
18
19   visibility?
20   brew_molecule?
21 @end ignore
22
23
24
25
26 @node Top
27 @chapter Features
28
29 @menu
30 * Arpeggio::                       Arpeggio
31 * Glissando::                      Glissando
32 * Manual beam settings::           Manual beam settings
33 * Slur attachments::               Slur attachments
34 * Text spanner::                   Text spanner
35 * Engraver hacking::               Engraver hacking
36 * Part combiner::                  Part combiner
37 * Markup text::                    Markup text
38 * Apply hacking::                  Apply hacking
39 * Output property::                Output property
40 * Embedded TeX::                   Embedded TeX
41 * Embedded PostScript::            Embedded PostScript
42 @end menu
43
44 @ignore
45 Testin'' a b c...
46 @lilypond[fragment,relative,verbatim,center]
47   a'' b c
48 @end lilypond
49 @end ignore
50
51 @node Arpeggio
52 @section Arpeggio
53
54 @lilypond[fragment,relative,verbatim,center]
55   \context Voice <c'\arpeggio e g c>
56 @end lilypond
57
58 @lilypond[fragment,relative,verbatim,center]
59   \context PianoStaff <
60     \property PianoStaff.connectArpeggios = ##t
61     \context Staff \context Voice <c''\arpeggio e g c>
62     \context Staff=other \context Voice <c,\arpeggio e g>
63   >  
64 @end lilypond
65
66
67 @node Glissando
68 @section Glissando
69
70
71 @lilypond[fragment,relative,verbatim,center]
72   c'' \glissando c'
73 @end lilypond
74
75 @subsection Follow Thread
76 @lilypond[fragment,relative,verbatim,center]
77   \context PianoStaff <
78     \property PianoStaff.followThread = ##t
79     \context Staff \context Voice {
80       c'1
81       \translator Staff=two
82       b2 a
83     }
84     \context Staff=two {\clef bass; \skip 1*2;}
85   >  
86 @end lilypond
87
88 @node Manual beam settings
89 @section Manual beam settings
90
91
92 Beams over rests...
93
94 @lilypond[fragment,relative,verbatim,center]
95   \context Staff {
96     r4 [r8 g'' a]
97   }
98 @end lilypond
99
100
101 Control number of beams...
102
103 @lilypond[fragment,relative,verbatim,center]
104   \context Staff {
105     [f'8 r16 f g a]
106     [f8 r16 \property Voice.stemLeftBeamCount = #1 f g a]
107   }
108 @end lilypond
109
110 @lilypond[fragment,relative,verbatim,center]
111   f'32 g a b b a g f
112
113   \property Voice.autoBeamSettings
114     \set #'(end * * * *) = #(make-moment 1 4)
115   f32 g a b b a g f
116
117   f32 g a
118   \property Voice.stemRightBeamCount = #1 b
119   \property Voice.stemLeftBeamCount = #1 b
120   a g f
121 @end lilypond
122
123 Don't extend to middle line esp. for grace
124
125 @lilypond[fragment,relative,verbatim,center]
126   \grace a'8 a4
127   \property Voice.Stem \set #'no-stem-extend = ##t
128   \grace g8 g4
129 @end lilypond
130   
131 Beam slope (height)
132
133 Horizontal beam
134
135 @lilypond[fragment,relative,verbatim,center]
136   \property Voice.Beam \set #'direction = #1
137   \property Voice.Beam \set #'height-hs = #0
138   [a''8 e' d c]
139 @end lilypond
140
141 beam start-y beam-height
142
143 Weird beam
144 @lilypond[fragment,relative,verbatim,center]
145   \property Voice.Beam \set #'y-position-hs = #4
146   \property Voice.Beam \set #'height-hs = #-4
147   [c'8 c] 
148 @end lilypond
149
150
151 Like stem...
152
153 @lilypond[fragment,relative,verbatim,center]
154   [b''8 b]
155   \property Voice.Beam \set #'default-neutral-direction = #-1
156   [b b]
157 @end lilypond
158
159 There are several ways to calculate the direction of a beam.
160
161 [Ross] states that the majority of the notes dictates the
162 direction (and not the mean of "center distance")
163
164 But is that because it really looks better, or because he wants
165 to provide some real simple hands-on rules?
166      
167 We have our doubts, so we simply provide all sensible alternatives:
168
169 @table @samp
170 @item majority
171 number count of up or down notes
172 @item mean
173 mean centre distance of all notes
174 @item median
175 mean centre distance weighted per note
176 @end table
177
178 You can spot the difference of these settings quite easily from these simple examples:
179
180 @lilypond[fragment,relative,verbatim,center]
181   [d''8 a]
182   \property Voice.Beam \set #'dir-function = #beam-dir-mean
183   [d a] 
184   \property Voice.Beam \set #'dir-function = #beam-dir-median
185   [d a]
186 @end lilypond
187     
188 @lilypond[fragment,relative,verbatim,center]
189   \time 3/8;
190   [d''8 a a]
191   \property Voice.Beam \set #'dir-function = #beam-dir-mean
192   [d a a] 
193   \property Voice.Beam \set #'dir-function = #beam-dir-median
194   [d a a] 
195 @end lilypond
196
197
198 @node Slur attachments
199 @section Slur attachments
200
201 Override attachments...
202 @lilypond[fragment,relative,verbatim,center]
203   \property Voice.Slur \set #'direction = #1
204   \property Voice.Stem \set #'length = #5.5
205   g''8(g)g4
206   g4(g8)g
207   \property Voice.Slur \set #'attachment = #'(stem . stem)
208   g8(g)g4
209   g4(g8)g
210 @end lilypond
211
212
213 Test Before, after
214
215 @c Ugh, ugh @multitable is broken in texinfo-4.0
216 @c Fixed in 4.0.jcn3
217 @c We'll have to postpone this before/after representation until
218 @c jcn3 is rolled into texinfo...
219
220 @multitable @columnfractions .40 .40
221 @item
222 @noindent
223 @lilypond[fragment,relative,verbatim,center]
224 \property Voice.Slur
225   \set #'direction = #1
226 g''8(g)g4
227 g4(g8)g
228 @end lilypond
229 @tab
230 @lilypond[fragment,relative,verbatim,center]
231 \property Voice.Slur
232   \set #'direction = #1
233 \property Voice.Stem
234   \set #'length = #5.5
235 \property Voice.Slur
236   \set #'attachment = #'(stem . stem)
237 g''8(g)g4
238 g4(g8)g
239 @end lilypond
240 @end multitable
241
242         
243 Ophee slurs...
244 @lilypond[fragment,relative,verbatim,center]
245   \property Voice.Slur \set #'direction = #1
246   \property Voice.Slur \set #'attachment = #'(head . head)
247   g''16()g()g()g()d'()d()d()d
248 @end lilypond
249
250
251 Steep slur correct...
252 @lilypond[fragment,relative,verbatim,center]
253   \property Voice.Stem \set #'direction = #1
254   \property Voice.Slur \set #'direction = #1
255   d'32( d'4 )d8..
256   \property Voice.Slur \set #'attachment = #'(stem . stem)
257   d,32( d'4 )d8..
258 @end lilypond
259
260 Ugly slurs...
261 @lilypond[verbatim,center]
262 \score {
263   \notes \context PianoStaff <
264     \time 6/4;
265     \context Staff=up { s1 * 6/4 }
266     \context Staff=down <
267       \clef bass;
268       \autochange Staff \context Voice
269         \notes \relative c {
270           d,8( a' d f a d f d a f d )a
271         }
272     >
273   >
274   \paper {
275     linewidth = -1.;
276     \translator {
277       \VoiceContext
278       Slur \override #'beautiful = #5.0
279       Slur \override #'direction = #1
280       Stem \override #'direction = #-1
281       autoBeamSettings \override #'(end * * * *)
282         = #(make-moment 1 2)
283     }
284     \translator {
285       \PianoStaffContext
286       VerticalAlignment \override #'threshold = #'(5 . 5)
287     }
288   }
289 }
290 @end lilypond
291
292
293 @node Text spanner
294 @section Text spanner
295
296 Have crescendo set a text spanner iso hairpin
297 @lilypond[fragment,relative,verbatim,center]
298   \context Voice {
299     \property Voice.crescendoText = "cresc."
300     \property Voice.crescendoSpanner = #'dashed-line
301     a''2\mf\< a a \!a 
302   }
303 @end lilypond
304
305 @subsection Ottava
306
307 @lilypond[fragment,relative,verbatim,center]
308   a'''' b c a
309   \property Voice.TextSpanner \set #'type = #'dotted-line
310   \property Voice.TextSpanner \set #'edge-height = #'(0 . 1.5)
311   \property Voice.TextSpanner \set #'edge-text = #'("8va " . "")
312   \property Staff.centralCPosition = #-13
313   a\spanrequest \start "text" b c a \spanrequest \stop "text"
314 @end lilypond
315
316
317
318 @node Engraver hacking
319 @section Engraver hacking
320
321 No time signature, no barlines... 
322 @lilypond[verbatim,center]
323 \score {
324   \notes \relative c'' {
325     a b c d
326     d c b a
327   }
328   \paper {
329     linewidth = -1.;
330     \translator {
331       \StaffContext
332       whichBar = #""
333       \remove "Time_signature_engraver";
334     }
335   }
336 }
337 @end lilypond
338
339 No staff, no clef, squash pitches
340 @lilypond[verbatim,center]
341 \score {
342   \notes { c4 c4 c8 c8 }
343   \paper {
344     linewidth = -1.;
345     \translator {
346       \StaffContext
347       \remove Staff_symbol_engraver;
348       \consists Pitch_squash_engraver;
349       \remove Clef_engraver;
350     }
351   }
352 }
353 @end lilypond
354
355
356 @node Part combiner
357 @section Part combiner
358
359 @lilypond[verbatim,center]
360 \score{
361   \context Staff = flauti <
362     \time 4/4;
363     \context Voice=one \partcombine Voice
364     \context Thread=one \notes\relative c'' {
365       c4 d e f | b,4 d c d | r2 e4 f | c4 d e f |
366       c4 r e f | c4 r e f | c4 r a r | a a r a |
367       a2 \property Voice.soloADue = ##f a |
368     }
369     \context Thread=two \notes\relative c'' {
370       g4 b d f | r2 c4 d | a c c d | a4. b8 c4 d
371       c r e r | r2 s2 | a,4 r a r | a r r a |
372       a2 \property Voice.soloADue = ##f a |
373     }
374   >
375   \paper{
376     linewidth = 80 * \staffspace;
377     \translator{
378       \ThreadContext
379       \consists Rest_engraver;
380     }
381     \translator{
382       \VoiceContext
383       \remove Rest_engraver;
384     }
385   }
386 }
387 @end lilypond
388
389
390
391
392 @node Markup text
393 @section Markup text
394
395 Metrome hack...
396
397 @lilypond[verbatim,center]
398 #(define note '(rows (music "noteheads-2" ((kern . -0.1) "flags-stem"))))
399 #(define eight-note `(rows ,note ((kern . -0.1) (music ((raise . 3.5) "flags-u3")))))
400 #(define dotted-eight-note `(rows ,eight-note (music "dots-dot")))
401
402 \score {
403   \notes\relative c'' {
404     a1^#`(rows ,dotted-eight-note " = 64")
405   }
406   \paper {
407     linewidth = -1.;
408     \translator{
409       \ScoreContext
410       TextScript \override #'font-shape = #'upright
411     }
412   }
413 }
414 @end lilypond
415
416
417 @node Output property
418 @section Output property
419
420 @lilypond[fragment,relative,verbatim,center]
421     \outputproperty #(make-type-checker 'note-head-interface) 
422       #'extra-offset = #'(2 . 3)
423     c''2 c
424 @end lilypond
425
426 Don't move the finger 2, only text "m.d." ...
427 @lilypond[verbatim,center]
428 #(define (make-text-checker text)
429    (lambda (grob) (equal? text (ly-get-elt-property grob 'text))))
430
431 \score {    
432   \notes\relative c''' {
433     \property Voice.Stem \set #'direction = #1
434     \outputproperty #(make-text-checker "m.d.")
435       #'extra-offset = #'(-3.5 . -4.5)
436     a^2^"m.d."    
437   }
438   \paper { linewidth = -1.; }
439 }
440 @end lilypond
441
442
443 @c  equalizer
444
445
446 @node Apply hacking
447 @section Apply hacking
448
449 @lilypond[verbatim,center]
450 music = \notes { c'4 d'4( e'4 f'4 }
451
452 #(define (reverse-music music)
453   (let* ((elements (ly-get-mus-property music 'elements))
454          (reversed (reverse elements))
455          (span-dir (ly-get-mus-property music 'span-direction)))
456     
457     (ly-set-mus-property music 'elements reversed)
458     
459     (if (dir? span-dir)
460         (ly-set-mus-property music 'span-direction (- span-dir)))
461     
462     (map reverse-music reversed)
463     
464     music))
465
466 \score {
467   \context Voice {
468     \music
469     \apply #reverse-music \music
470   }
471   \paper { linewidth = -1.; }
472 }
473 @end lilypond
474
475
476 LilyPond is more flexible than some users realise.  Han-Wen could be
477 very rich.
478
479 Just too funny not to include.
480
481 @example
482 @quotation
483     I've just entered a request on cosource.com :
484 @quotation
485         http://www.cosource.com/cgi-bin/cos.pl/wish/info/387
486 @end quotation
487     Here's a copy of my feature request :
488 @quotation
489         Your task, if you accept it is to implement a \smarttranspose
490         command> that would translate such oddities into more natural
491         notations. Double accidentals should be removed, as well as #E
492         (-> F), bC (-> B), bF (-> E), #B (-> C).
493 @end quotation
494 @end quotation
495 You mean like this. (Sorry 'bout the nuked indentation.)
496
497 Add IMPLEMENT_TYPE_P(Music, "music?"); to music.cc, and presto, done.
498
499 That's an easy $ 100; if I'd make $ 200/hour for every hour I worked
500 on Lily, I'd be very rich :)
501 @end example
502
503
504 @lilypond[verbatim,center]
505 #(define  (unhair-pitch p)
506   (let* ((o (pitch-octave p))
507          (a (pitch-alteration p))
508          (n (pitch-notename p)))
509
510     (cond
511      ((and (> a 0) (or (eq? n 6) (eq? n 2)))
512       (set! a (- a 1)) (set! n (+ n 1)))
513      ((and (< a 0) (or (eq? n 0) (eq? n 3)))
514       (set! a (+ a 1)) (set! n (- n 1))))
515     
516     (cond
517      ((eq? a 2)  (set! a 0) (set! n (+ n 1)))
518      ((eq? a -2) (set! a 0) (set! n (- n 1))))
519
520     (if (< n 0) (begin (set!  o (- o 1)) (set! n (+ n 7))))
521     (if (> n 7) (begin (set!  o (+ o 1)) (set! n (- n 7))))
522     
523     (make-pitch o n a)))
524
525 #(define (smart-transpose music pitch)
526   (let* ((es (ly-get-mus-property music 'elements))
527          (e (ly-get-mus-property music 'element))
528          (p (ly-get-mus-property music 'pitch))
529          (body (ly-get-mus-property music 'body))
530          (alts (ly-get-mus-property music 'alternatives)))
531
532     (if (pair? es)
533         (ly-set-mus-property
534          music 'elements
535          (map (lambda (x) (smart-transpose x pitch)) es)))
536     
537     (if (music? alts)
538         (ly-set-mus-property
539          music 'alternatives
540          (smart-transpose alts pitch)))
541     
542     (if (music? body)
543         (ly-set-mus-property
544          music 'body
545          (smart-transpose body pitch)))
546
547     (if (music? e)
548         (ly-set-mus-property
549          music 'element
550          (smart-transpose e pitch)))
551     
552     (if (pitch? p)
553         (begin
554           (set! p (unhair-pitch (Pitch::transpose p pitch)))
555           (ly-set-mus-property music 'pitch p)))
556     
557     music))
558
559     
560 music = \notes \relative c' { c4 d  e f g a b  c }
561
562 \score {
563   \notes \context Staff {
564     \transpose ais' \music
565     \apply #(lambda (x) (smart-transpose x (make-pitch 0 5 1)))
566       \music
567   }
568   \paper { linewidth = -1.; }
569 }
570 @end lilypond
571
572
573 @node Embedded TeX
574 @section Embedded TeX
575 @lilypond[fragment,relative,verbatim,center]
576   a''^"3 $\\times$ \\`a deux"
577 @end lilypond
578
579 @node Embedded PostScript
580 @section Embedded PostScript
581
582 Arbitrary lines and curves not supported...
583
584 [TODO:] Make a direct postscript command?
585
586 @lilypond[verbatim,center]
587 \score {
588   \notes \relative c'' {
589     a-#"\\embeddedps{3 4 moveto 5 3 rlineto stroke}"
590     -#"\\embeddedps{ [ 0 1 ] 0 setdash 3 5 moveto 5 -3 rlineto stroke}"
591     b-#"\\embeddedps{3 4 moveto 0 0 1 2 8 4 20 3.5 rcurveto stroke}"
592     s2
593     a'1
594   }
595   \paper { linewidth = 70 * \staffspace; }
596 }
597 @end lilypond
598
599 @bye
600
601
602