@c -*-texinfo-*- @ignore TODO * cue notes * different staff sizes * font selection * move some stuff to refman * merge some stuff with refman entries * add @ref{}s to lilypond-internals: @rgrob{Name} to grob @reng{Name} to engraver there's a very simple, very general noXXX mechanism; try noop \property Staff.VoltaBrace = #'() yes: \property Staff.VoltaBracket = #'((meta . ((interfaces . ())))) visibility? brew_molecule? @end ignore @node Tricks @chapter Tricks @menu * Manual beam settings:: Manual beam settings * Slur attachments:: Slur attachments * Text spanner:: Text spanner * Engraver hacking:: Engraver hacking * Part combiner:: Part combiner * Markup text:: Markup text * Apply hacking:: Apply hacking * Output property:: Output property * Embedded TeX:: Embedded TeX * Embedded PostScript:: Embedded PostScript @c * Index:: Checking Feature index @end menu @node Manual beam settings @section Manual beam settings @cindex beams @cindex beam settings @cindex manual beams @c auto knees @cindex @code{]} In some cases it may be necessary to override LilyPond's automatic beaming algorithm. For example, the auto beamer will not beam over rests, so if you want that, specify the begin and end point manually using @code{[} and @code{]}: @quotation @lilypond[fragment,relative,verbatim] \context Staff { r4 [r8 g'' a] } @end lilypond @end quotation Similarly, for beams over bar lines: @quotation @lilypond[fragment,relative,verbatim] \context Staff { a''8 r a2 r8 [a a] } @end lilypond @end quotation @cindex @code{stemLeftBeamCount} If you have specific wishes for the number of beams, you can fully control the number of beams through the properties @code{Voice.stemLeftBeamCount}; @quotation @lilypond[fragment,relative,verbatim] \context Staff { [f'8 r16 f g a] [f8 r16 \property Voice.stemLeftBeamCount = #1 f g a] } @end lilypond @end quotation @cindex @code{stemRightBeamCount} and @code{Voice.stemRightBeamCount}: @quotation @lilypond[fragment,relative,verbatim] f'32 g a b b a g f \property Voice.autoBeamSettings \set #'(end * * * *) = #(make-moment 1 4) f32 g a b b a g f f32 g a \property Voice.stemRightBeamCount = #1 b \property Voice.stemLeftBeamCount = #1 b a g f @end lilypond @end quotation @cindex @code{no-stem-extend} Conventionally, stems and beams extend to the middle staff line. This extension can be controlled through @code{Voice.Stem}'s grob-property @code{no-stem-extend}: @quotation @lilypond[fragment,relative,verbatim] \grace a'8 a4 \property Voice.Stem \set #'no-stem-extend = ##t \grace g8 g4 [g8 g] @end lilypond @end quotation The beam symbol can be tweaked through @code{Voice.Beam}'s grob-properties @code{height-hs} and @code{y-position-hs}. Set @code{height-hs} to zero, to get horizontal beams: @quotation @lilypond[fragment,relative,verbatim] \property Voice.Beam \set #'direction = #1 \property Voice.Beam \set #'height-hs = #0 [a''8 e' d c] @end lilypond @end quotation Both are in half spaces. Here's how you'd specify a weird looking beam that instead of being horizontal, falls two staff spaces (ie, four half spaces): @quotation @lilypond[fragment,relative,verbatim] \property Voice.Beam \set #'y-position-hs = #4 \property Voice.Beam \set #'height-hs = #-4 [c'8 c] @end lilypond @end quotation @cindex @code{default-neutral-direction} The direction of a perfectly centred beams can be controlled through @code{Voice.Beam}'s grob-property @code{default-neutral-direction} @quotation @lilypond[fragment,relative,verbatim] [b''8 b] \property Voice.Beam \set #'default-neutral-direction = #-1 [b b] @end lilypond @end quotation There are several ways to calculate the direction of a beam. @table @code @item majority number count of up or down notes @item mean mean center distance of all notes @item median mean centre distance weighted per note @end table You can spot the differences of these settings from these simple examples: @quotation @lilypond[fragment,relative,verbatim] [d''8 a] \property Voice.Beam \set #'dir-function = #beam-dir-mean [d a] \property Voice.Beam \set #'dir-function = #beam-dir-median [d a] @end lilypond @end quotation @quotation @lilypond[fragment,relative,verbatim] \time 3/8; [d''8 a a] \property Voice.Beam \set #'dir-function = #beam-dir-mean [d a a] \property Voice.Beam \set #'dir-function = #beam-dir-median [d a a] @end lilypond @end quotation These beam direction functions are defined in @file{scm/beam.scm}. If your favourite algorithm isn't one of these, you can hook up your own. @node Slur attachments @section Slur attachments The ending of a slur should whenever possible be attached to a note head. Only in some instances where beams are involved, LilyPond may attach a slur to a stem end. In some cases, you may want to override LilyPond's decision, e.g., to attach the slur to the stem end. This can be done through @code{Voice.Slur}'s grob-property @code{attachment}: @c FIXME: make @ref{} to backend doco @quotation @lilypond[fragment,relative,verbatim] \property Voice.Slur \set #'direction = #1 \property Voice.Stem \set #'length = #5.5 g''8(g)g4 \property Voice.Slur \set #'attachment = #'(stem . stem) g8(g)g4 @end lilypond @end quotation Similarly, slurs can be attached to note heads even when beams are involved: @quotation @lilypond[fragment,relative,verbatim] \property Voice.Slur \set #'direction = #1 \property Voice.Slur \set #'attachment = #'(head . head) g''16()g()g()g()d'()d()d()d @end lilypond @end quotation If a slur would strike through a stem or beam, LilyPond will move the slur away vertically (upward or downward). In some cases, this may cause ugly slurs that you may want to correct: @quotation @lilypond[fragment,relative,verbatim] \property Voice.Stem \set #'direction = #1 \property Voice.Slur \set #'direction = #1 d'32( d'4 )d8.. \property Voice.Slur \set #'attachment = #'(stem . stem) d,32( d'4 )d8.. @end lilypond @end quotation LilyPond will increase the curvature of a slur trying to stay free of note heads and stems. However, if the curvature would increase too much, the slur will be reverted to its default shape. This decision is based on @code{Voice.Slur}'s grob-property @code{beautiful} value. In some cases, you may find ugly slurs beautiful, and tell LilyPond so by increasing the @code{beautiful} value: [hoe gedefd?? wat betekent beautiful = X?] @quotation @lilypond[verbatim] \score { \notes \context PianoStaff < \time 6/4; \context Staff=up { s1 * 6/4 } \context Staff=down < \clef bass; \autochange Staff \context Voice \notes \relative c { d,8( a' d f a d f d a f d )a } > > \paper { linewidth = -1.; \translator { \VoiceContext Slur \override #'beautiful = #5.0 Slur \override #'direction = #1 Stem \override #'direction = #-1 autoBeamSettings \override #'(end * * * *) = #(make-moment 1 2) } \translator { \PianoStaffContext VerticalAlignment \override #'threshold = #'(5 . 5) } } } @end lilypond @end quotation @node Text spanner @section Text spanner Have crescendo set a text spanner instead of hairpin @lilypond[fragment,relative,verbatim] \context Voice { \property Voice.crescendoText = "cresc." \property Voice.crescendoSpanner = #'dashed-line a''2\mf\< a a \!a } @end lilypond @subsection Ottava @lilypond[fragment,relative,verbatim] a'''' b c a \property Voice.TextSpanner \set #'type = #'dotted-line \property Voice.TextSpanner \set #'edge-height = #'(0 . 1.5) \property Voice.TextSpanner \set #'edge-text = #'("8va " . "") \property Staff.centralCPosition = #-13 a\spanrequest \start "text" b c a \spanrequest \stop "text" @end lilypond @node Engraver hacking @section Engraver hacking No time signature, no barlines... @lilypond[verbatim] \score { \notes \relative c'' { a b c d d c b a } \paper { linewidth = -1.; \translator { \StaffContext whichBar = #"" \remove "Time_signature_engraver"; } } } @end lilypond No staff, no clef, squash pitches @lilypond[verbatim] \score { \notes { c4 c4 c8 c8 } \paper { linewidth = -1.; \translator { \StaffContext \remove Staff_symbol_engraver; \consists Pitch_squash_engraver; \remove Clef_engraver; } } } @end lilypond @node Part combiner @section Part combiner @lilypond[verbatim] \score{ \context Staff = flauti < \time 4/4; \context Voice=one \partcombine Voice \context Thread=one \notes\relative c'' { c4 d e f | b,4 d c d | r2 e4 f | c4 d e f | c4 r e f | c4 r e f | c4 r a r | a a r a | a2 \property Voice.soloADue = ##f a | } \context Thread=two \notes\relative c'' { g4 b d f | r2 c4 d | a c c d | a4. b8 c4 d c r e r | r2 s2 | a,4 r a r | a r r a | a2 \property Voice.soloADue = ##f a | } > \paper{ linewidth = 80 * \staffspace; \translator{ \ThreadContext \consists Rest_engraver; } \translator{ \VoiceContext \remove Rest_engraver; } } } @end lilypond @node Markup text @section Markup text @ignore #(define text-flat '((font-relative-size . -2 ) (music "accidentals--1"))) \property VoiceCombineStaff.instrument = #`((kern . 0.5) (lines "2 Clarinetti" (rows " (B" ,text-flat ")"))) % Ugh, markup burps \property StaffCombineStaff.instrument = #'((kern . 0.5) (lines "Violoncello" (rows " e") (rows "Contrabasso"))) @end ignore Metrome hack... [todo: hack this into C++, use \tempo] @lilypond[verbatim] #(define note '(rows (music "noteheads-2" ((kern . -0.1) "flags-stem")))) #(define eight-note `(rows ,note ((kern . -0.1) (music ((raise . 3.5) "flags-u3"))))) #(define dotted-eight-note `(rows ,eight-note (music "dots-dot"))) \score { \notes\relative c'' { a1^#`(rows ,dotted-eight-note " = 64") } \paper { linewidth = -1.; \translator{ \ScoreContext TextScript \override #'font-shape = #'upright } } } @end lilypond @node Output property @section Output property @lilypond[fragment,relative,verbatim] \outputproperty #(make-type-checker 'note-head-interface) #'extra-offset = #'(2 . 3) c''2 c @end lilypond Don't move the finger 2, only text "m.d." ... @lilypond[verbatim] #(define (make-text-checker text) (lambda (grob) (equal? text (ly-get-elt-property grob 'text)))) \score { \notes\relative c''' { \property Voice.Stem \set #'direction = #1 \outputproperty #(make-text-checker "m.d.") #'extra-offset = #'(-3.5 . -4.5) a^2^"m.d." } \paper { linewidth = -1.; } } @end lilypond @c equalizer @node Apply hacking @section Apply hacking @lilypond[verbatim] music = \notes { c'4 d'4( e'4 f'4 } #(define (reverse-music music) (let* ((elements (ly-get-mus-property music 'elements)) (reversed (reverse elements)) (span-dir (ly-get-mus-property music 'span-direction))) (ly-set-mus-property music 'elements reversed) (if (dir? span-dir) (ly-set-mus-property music 'span-direction (- span-dir))) (map reverse-music reversed) music)) \score { \context Voice { \music \apply #reverse-music \music } \paper { linewidth = -1.; } } @end lilypond @node Embedded TeX @section Embedded TeX @lilypond[fragment,relative,verbatim] a''^"3 $\\times$ \\`a deux" @end lilypond @node Embedded PostScript @section Embedded PostScript Arbitrary lines and curves not supported... [TODO:] Make a direct postscript command? @lilypond[verbatim] \score { \notes \relative c'' { a-#"\\embeddedps{3 4 moveto 5 3 rlineto stroke}" -#"\\embeddedps{ [ 0 1 ] 0 setdash 3 5 moveto 5 -3 rlineto stroke}" b-#"\\embeddedps{3 4 moveto 0 0 1 2 8 4 20 3.5 rcurveto stroke}" s2 a'1 } \paper { linewidth = 70 * \staffspace; } } @end lilypond @ignore @node Index @section Checking Feature index @printindex cp @bye @end ignore