Ripped, torn staff-lines
Here are some macros (contributed by Mark Polesky) which can make a single staff appear as though its right side has been torn off. Two styles are available: the first "erases" the ends of individual staff- lines to different lengths; the second draws a zigzag line and erases everything to its right. Furthermore, the first type is capable of producing tear-patterns at random. Both work by temporarily modifying the BarLine stencil.
For technical reasons, the zigzag lines don't show up in the Wiki because \postscript only works with LilyPond's PS backend and is neither supported in the SVG (used in this Wiki) nor in the Cairo backend.
STYLE 1 PREFERENCES:
[edit | edit source]tearWidth... default is 1
horizontal distance (measured in staff-spaces) between the end-points of the shortest and longest staff-lines.
tearXext... default is '(0 . 0)
X-extent of the BarLine stencil, NOT including its width. Can be used as "padding" around the stencil, if needed.
STYLE 2 PREFERENCES:
[edit | edit source]zigzagDefaultYext... default is '(-4 . 4)
Y-extent of the zigzag BarLine stencil (measured in staff-spaces).
zigzagDefaultSerrationCount... default is 5
Number of "teeth" or "notches" on the zigzag line.
zigzagTearLineWidth... default is 0.1
Width of the zigzag line itself.
zigzagTearAngle... default is 90
Angle (measured in degrees) of kinks in the zigzag line.
zigzagTearXext... default is '(0 . 0)
X-extent of the zigzag BarLine stencil, NOT including its width. Can be used as "padding" around the stencil, if needed.
USAGE:
[edit | edit source]see the \score { } block at the end of the file.
\version "2.24"
%% preferences %%
tearWidth = #1
tearXext = #'(0 . 0)
zigzagDefaultYext = #'(-4 . 4)
zigzagDefaultSerrationCount = #5
zigzagTearLineWidth = #0.1
zigzagTearAngle = #90
zigzagTearXext = #'(0 . 0)
%% start definitions %%
tearGeneric =
#(define-music-function (lengths) (list?)
(let ((x-ext
(lambda (n)
(cons (* (list-ref lengths n) (/ tearWidth 4)) tearWidth)))
(y-ext '(1.5 . 2.5)))
#{
\once \override Staff.BarLine.stencil = #ly:text-interface::print
\once \override Staff.BarLine.text = \markup
\override #'(baseline-skip . 0) \with-color #white
\column {
\filled-box #(x-ext 0) #y-ext #0
\filled-box #(x-ext 1) #y-ext #0
\filled-box #(x-ext 2) #y-ext #0
\filled-box #(x-ext 3) #y-ext #0
\filled-box #(x-ext 4) #y-ext #0
}
\once \override Staff.BarLine.layer = #1
\once \override Staff.BarLine.X-extent =
#`(,(car tearXext) . ,(- (+ (cdr tearXext) tearWidth) 0.1))
\break
#}))
tear =
#(define-music-function () ()
#{
\tearGeneric
#(let loop ((unused '(0 1 2 3 4))
(lengths '()))
(if (= (length lengths) 5)
lengths
(let* ((x (random (length unused)))
(y (- (length unused) x))
(z (list-ref unused x)))
(loop (append (list-tail unused (+ x 1))
(list-tail (reverse unused) y))
(append lengths `(,z))))))
#})
tearCustom =
#(define-music-function (lengths) (list?)
#{ \tearGeneric #lengths #})
zigzagTearCustom =
#(define-music-function (y-ext serrations)
(pair? number?)
(let* ((zigzagTearHeight (- (cdr y-ext) (car y-ext)))
(deg2rad (lambda (x) (* x (/ (* (atan 1) 4) 180))))
(zigzagTearWidth
(/ zigzagTearHeight
serrations
(* (tan (/ (deg2rad zigzagTearAngle) 2)) 2))))
#{
\once \override Staff.BarLine.stencil = #ly:text-interface::print
\once \override Staff.BarLine.text =
\markup \with-dimensions
#`(0 . ,zigzagTearWidth)
#`(,(car y-ext) . ,(cdr y-ext))
\postscript
#(string-append "
/linewidth " (number->string zigzagTearLineWidth) " def
/height " (number->string zigzagTearHeight) " def
/serrations " (number->string serrations) " def
/width " (number->string zigzagTearWidth) " def
/padding " (number->string (cdr zigzagTearXext)) " 2 width mul add def
/serrationHeight height serrations div def
/y0 " (number->string (cdr y-ext)) " def
/xn width def
/yn serrationHeight 2 div neg def
/plotAngle {
xn yn rlineto
xn neg yn rlineto
} def
/plotSerrations {
serrations { plotAngle } repeat
} def
%% whiteout:
1 setgray
linewidth setlinewidth
0 y0 linewidth add moveto %% (whiteout staff-lines when y-exts are integers)
0 y0 lineto
plotSerrations
0 linewidth neg rlineto %% (whiteout staff-lines when y-exts are integers)
padding 0 rlineto
0 height linewidth 2 mul add rlineto %% (account for top and bottom linewidth)
padding neg 0 rlineto
fill stroke
%% draw serrations:
newpath
0 setgray
linewidth setlinewidth
0 y0 moveto
plotSerrations
stroke")
\once \override Staff.BarLine.layer = #1
\once \override Staff.BarLine.X-extent =
#`(,(car zigzagTearXext) .
,(- (+ (cdr zigzagTearXext) zigzagTearWidth) 0.1))
\break
#}))
zigzagTear = \zigzagTearCustom #zigzagDefaultYext #zigzagDefaultSerrationCount
%% end definitions %%
%% example of a custom tear-pattern:
tearRagged = \tearCustom #'(3 1 3 1 3)
music = { g'4 d'' b' d'' }
\header { tagline=##f }
\score {
{
%% random line-lengths:
\music \tear
%% set line-lengths on-the-fly:
\music \tearCustom #'(0 1 2 3 4)
%% define a custom tear-pattern if you want consistency (see above):
\music \tearRagged
%% default zigzag tear:
\music \zigzagTear
%% set zigzag Y-extent and serration-count on-the-fly:
\transpose c c' \music \zigzagTearCustom #'(-4 . 7) #4
}
\layout {
indent = #0
ragged-right = ##t
}
}