\version "2.16.0" % tested with "2.17.96", too \language "deutsch" rochadeAlpha = { \override Score.BreakAlignment #'break-align-orders = #(make-vector 3 '(left-edge ambitus breathing-sign staff-bar clef key-cancellation key-signature time-signature custos)) \once \override Score.TimeSignature #'space-alist = #'( (first-note fixed-space . 2.0) (right-edge extra-space . 0.5) (staff-bar minimum-space . 2.5)) \once \override Score.KeySignature #'space-alist = #'( (time-signature extra-space . 1.15) (first-note fixed-space . 1.0) (right-edge extra-space . 0.5) (staff-bar minimum-space . 2.5)) } onceTextLengthOn = { \once\override TextScript #'extra-spacing-width = #'(0 . 0) \once\override TextScript #'extra-spacing-height = #'(-inf.0 . +inf.0) } staffStop = { \onceTextLengthOn \stopStaff \cadenzaOn } staffStart = { \once\override Score.BarNumber #'break-visibility = #'#(#f #t #t) \startStaff \cadenzaOff \set Staff.forceClef = ##t } #(define-markup-command (bar-line layout props strg)(string?) #:properties ((font-size 0) (thin-thickness #f) (thick-thickness #f) (kern #f) (add-height 0)) " Please note: @code{bar-line} isn't finished. There are some weird codings in it. I wouldn't be surprised, if it crashes soon. " (define (string->string-list str) "Convert a string into a list of strings with length 1. @code{"aBc"} will be converted to @code{("a" "B" "c")}. An empty string will be converted to a list containing @code{""}." (if (and (string? str) (not (zero? (string-length str)))) (map (lambda (s) (string s)) (string->list str)) (list ""))) (define (make-bar-line thickness height font-size blot-diameter) "Draw a simple bar line." (ly:round-filled-box (cons 0 (* (magstep font-size) thickness)) (interval-widen (cons 0 (+ add-height height)) (magstep font-size)) blot-diameter)) (define (make-colon-bar-line height font-size) (let* ((font (ly:paper-get-font layout (cons '((font-encoding . fetaMusic)) props))) (dot (ly:font-get-glyph font "dots.dot"))) (ly:stencil-add dot (ly:stencil-translate-axis dot (magstep (+ (/ add-height 2) font-size)) Y)))) (define (make-bracket-bar-line height font-size dir thick-bar ) "Draw a bracket-style bar line. If @var{dir} is set to @code{LEFT}, the opening bracket will be drawn, for @code{RIGHT} we get the closing bracket." (let* ((font (ly:paper-get-font layout (cons '((font-encoding . fetaMusic)) props))) (brackettips-up (ly:font-get-glyph font "brackettips.up")) (brackettips-down (ly:font-get-glyph font "brackettips.down")) ;; the x-extent of the brackettips must not be taken into account ;; for bar line constructs like "[|:", so we set new bounds: (tip-up-stil (ly:make-stencil (ly:stencil-expr brackettips-up) (cons 0 0) (ly:stencil-extent brackettips-up Y))) (tip-down-stil (ly:make-stencil (ly:stencil-expr brackettips-down) (cons 0 0) (ly:stencil-extent brackettips-down Y))) (stencil (ly:stencil-add thick-bar (ly:stencil-translate-axis tip-up-stil (+ (/ (+ add-height height) 2) (magstep font-size)) Y) (ly:stencil-translate-axis tip-down-stil (* -1 (+ (/ (+ add-height height) 2) (magstep font-size))) Y)))) (if (eq? dir LEFT) stencil (ly:stencil-scale stencil -1 1)))) ;; TODO: changing global-staff-size will ruin the output for the braces ;; manual readjustment needed :( (define (make-brace-bar-line height font-size) (let* ((pt (ly:output-def-lookup layout 'pt)) (new-height (/ (+ height add-height) pt)) (line-thickness (ly:output-def-lookup layout 'line-thickness)) (font (ly:paper-get-font layout (cons '((font-encoding . fetaBraces) (font-name . #f)) props))) (glyph-count (1- (ly:otf-glyph-count font))) (scale (ly:output-def-lookup layout 'output-scale)) ;; Why `+ 2´ ? (scaled-size (+ 2 (/ (ly:pt new-height) scale))) ;; TODO How about font-size? ;; (scaled-size ;; (+ 2 (magstep font-size) (/ (ly:pt new-height) scale))) (glyph (lambda (n) (ly:font-get-glyph font (string-append "brace" (number->string n))))) (get-y-from-brace (lambda (brace) (interval-length (ly:stencil-extent (glyph brace) Y)))) (find-brace (binary-search 0 glyph-count get-y-from-brace scaled-size)) (glyph-found (glyph find-brace))) (if (or (null? (ly:stencil-expr glyph-found)) (< scaled-size (interval-length (ly:stencil-extent (glyph 0) Y))) (> scaled-size (interval-length (ly:stencil-extent (glyph glyph-count) Y)))) (begin (ly:warning (_ "no brace found for point size ~S ") new-height) (ly:warning (_ "defaulting to ~S pt") (/ (* scale (interval-length (ly:stencil-extent glyph-found Y))) (ly:pt 10))))) glyph-found)) (let* ((line-thickness (ly:output-def-lookup layout 'line-thickness)) (size (ly:output-def-lookup layout 'text-font-size 12)) ;; Numerical values taken from the IR ;; making them overrideable (kern (or kern (* line-thickness 3.0))) (thin-thickness (or thin-thickness (* line-thickness 1.9))) (thick-thickness (or thick-thickness (* line-thickness 6.0))) (blot (ly:output-def-lookup layout 'blot-diameter)) ;; Not sure about the numerical value, found it by try and error. (thin-bar-line (ly:stencil-aligned-to (make-bar-line thin-thickness (/ size 9) font-size blot) Y CENTER)) (thick-bar-line (ly:stencil-aligned-to (make-bar-line thick-thickness (/ size 9) font-size blot) Y CENTER)) (colon-bar-line (ly:stencil-aligned-to (make-colon-bar-line (/ size 9) font-size) Y CENTER)) (bracket-left-bar-line (ly:stencil-aligned-to (make-bracket-bar-line (/ size 9) font-size -1 thick-bar-line) Y CENTER)) (bracket-right-bar-line (ly:stencil-aligned-to (make-bracket-bar-line (/ size 9) font-size 1 thick-bar-line) Y CENTER)) (brace-left-bar-line (ly:stencil-aligned-to (make-brace-bar-line (/ size 9) font-size) Y CENTER)) (strg-list (string->string-list strg)) (find-bar-line-proc (lambda (x) (cond ((string=? ":" x) colon-bar-line) ((string=? "|" x) thin-bar-line) ((string=? "." x) thick-bar-line) ((string=? "[" x) bracket-left-bar-line) ((string=? "]" x) bracket-right-bar-line) ((string=? "{" x) brace-left-bar-line) (else empty-stencil)))) (bar-line-stils (remove ly:stencil-empty? (map find-bar-line-proc strg-list))) (stil (stack-stencils X RIGHT (* (magstep font-size) kern) bar-line-stils)) (stil-y-length (interval-length (ly:stencil-extent stil Y)))) ;; Hm, should the stencil-translate be hard-coded? (ly:stencil-translate-axis stil 0;(/ stil-y-length 4) Y))) %% The BarLine to add is defined using the markup-command \bar-line, %% It depends of 'start-bar-length' (y-length) %% 'kern' (kerning) %% 'start-bar-type (type) %% 'thick-thickness (harcoded thick-thickness) #(define (start-bar-markup kern start-bar-length thick-thickness start-bar-type) #{ \markup \with-dimensions #(cons kern kern) #'(0 . 0) \override #`(add-height . ,start-bar-length) \override #`(thick-thickness . 0.5) \bar-line #start-bar-type #}) %% The 'markup' is turned into a stencil and moved in %% Y-direction to fit. #(define ((new-start-bar start-bar-length markup) grob) (let* ((layout (ly:grob-layout grob)) (staff-space (ly:output-def-lookup layout 'staff-space)) (size (ly:output-def-lookup layout 'text-font-size 12)) (line-thickness (ly:output-def-lookup layout 'line-thickness)) (new-start-bar-stil (grob-interpret-markup grob markup)) (new-stencil (ly:stencil-combine-at-edge (ly:bar-line::print grob) X LEFT (ly:stencil-translate-axis new-start-bar-stil (+ staff-space (/ line-thickness 2) (/ (+ start-bar-length (/ size 9)) -2)) Y) 0))) new-stencil)) addBar = #(define-music-function (parser location kern start-bar-type start-bar-length) (number? string? number?) " Adds a custom-bar-line to @code{\\bar "|"}. @var{kern} is for kerning @var{start-bar-type} determines the type @var{start-bar-length} determines the Y-length Also, other settings are used to fake the appearence of a starting system. Using custom-staff-sizes or other global-staff-size will result in the need to readjust the value for @var{start-bar-length} " #{ \once \override Staff.BarLine #'stencil = #(new-start-bar start-bar-length (start-bar-markup kern start-bar-length 0.5 start-bar-type)) \once\override Score.BarLine #'hair-thickness = #1.6 \once\override Score.SpanBar #'hair-thickness = #1.6 \once\override Score.BarLine #'Y-extent = #'(0 . 0) \bar "|" \rochadeAlpha \once\override Score.RehearsalMark #'self-alignment-X = #LEFT #}) space = #(define-music-function (parser location width) (number?) " Adding a gap of width @var{width} into a StaffSymbol. Only works in the middle of a Staff. SpanBars are forced. Ofcourse this will only work, if the Span_bar_engraver is present. " #{ \noBreak \staffStop \onceTextLengthOn s1*1/1000000-\markup \with-dimensions #(cons 0 width) #'(0 . 0) \null \once \override Staff.BarLine #'allow-span-bar = ##t \once \override Score.Clef #'font-size = #'2 \staffStart \noBreak #}) noSpan = \with { \override BarLine #'allow-span-bar = ##f } %%%%%%%%%%%%%%%%%%%%%%%%%%%% % EXAMPLE %%%%%%%%%%%%%%%%%%%%%%%%%%%% onceSpan = \once \override Staff.BarLine #'allow-span-bar = ##t %% If you want no SpanBars before and after the gap and at the end of %% the last line, uncomment: % onceSpan = { } %% Or delete \onceSpan in the code below, where you want. global = { \key es \major \time 12/8 } tenorVoice = \relative c'' { \global \repeat volta 2 { b8 a b c b c d4. r | \mark\markup \concat \vcenter \small { "dal " \musicglyph #"scripts.segno" "al " \musicglyph #"scripts.coda" } } \onceSpan \space #10 \addBar #1.3 "[" #27.7 \key es \major \mark \markup { \musicglyph #"scripts.coda" } b4. b c d | es1. \onceSpan \bar "|." } verseTenorVoice = \lyricmode { % stanza 1 ha -- ben wir ei -- nes er -- kannt | % coda größ -- te Schatz den's | gibt. } verseTenorVoiceAlt = \lyricmode { % stanza 2 wir a -- ber hal -- ten zu -- samm': | } baritonVoice = \relative c' { \global \repeat volta 2 { d8 d d es es es d4. r | } \onceSpan \space #10 \key es \major << { g4. g as as | g1. } \new Voice { \voiceTwo es4. es es f | b,1. } >> \onceSpan } verseBaritonVoice = \lyricmode { % stanza 1 ha -- ben wir ei -- nes er -- kannt | % coda größ -- te Schatz den's | gibt. } verseBaritonVoiceAlt = \lyricmode { % stanza 2 wir a -- ber hal -- ten zu -- samm': | } bassVoice = \relative c { \global \repeat volta 2 { b'8 b b a8 a a b4. b, | } \onceSpan \space #10 \key es \major b'4. g f b, | es1. \onceSpan \bar "|." } verseBassVoice = \lyricmode { \repeat unfold 7 \skip 1 Ein | größ -- te Schatz den's | gibt. } right = \relative c' { \global 4. | \space #10 \key es \major \addBar #0.3 "{" #9.8 4. q | 1. \bar "|." } left = \relative c { \global b4. f b b | \space #10 \key es \major b'4. g f b, | es1. \bar "|." } %% \noSpan is added to every single Staff, apart from PianoStaff tenorVoicePart = \new Staff \noSpan { \tenorVoice } \addlyrics { \verseTenorVoice } \addlyrics { \verseTenorVoiceAlt } baritonVoicePart = \new Staff \noSpan { \baritonVoice } \addlyrics { \verseBaritonVoice } \addlyrics { \verseBaritonVoiceAlt } bassVoicePart = \new Staff \noSpan { \clef bass \bassVoice } \addlyrics { \verseBassVoice } pianoPart = \new PianoStaff << \new Staff = "right" \right \new Staff = "left" { \clef bass \left } >> \score { << \new ChoirStaff << \tenorVoicePart \baritonVoicePart \bassVoicePart >> \pianoPart >> \layout { %% adding Span_bar_engraver \context { \Score \consists "Span_bar_engraver" } } }