3

I've recently started experimenting with LilyPond (Version 2.18.2 in case it matters). I've been fairly successful in creating basic scores, but I cannot figure how to properly make position/barre markers for my guitar scores.

The documentation suggests using Text Spanners for this purpose and using this method I've been able to produce the following output:

LilyPond Markers

While basically functional, I'd prefer if I could make them look closer to this (made in MuseScore):

enter image description here

More specifically the things I'd like to do in LilyPond are:

1. Make the line be aligned to the middle of the numeral rather than the bottom.

2. Having the option adding a "hook" at the end of the line, indicating the extent of the barre.

I've experimented with the options for Text Spanners but have been unable to make any progress. I also found this suggested solution but not only am I unable to follow what's actually going on, the pictured output doesn't match what I hope to achieve.

In short, what I'm asking is:

1. Is it possible to achieve what I'm after using Text Spanners, and how would I go about doing it?

2. If not, is there some other feature/workaround that I could try that would produce the desired output?

3. If neither is possible, is there some alternate way to convey the same information using a feature which is easier to produce in LilyPond?

1

I used the example in the documentation and switched the text to the left of the spanner while the hook is now placed to the right. Probably, there is a way to include a boolean to the function to change from ‘hooked’ to ‘non-hooked’, but I wasn’t able to figure out how …

Anyway, to answer your questions: Yes, it is possible to do this using text spanners:

hbarre =
#(define-music-function (barre location str music) (string? ly:music?)
   (let ((elts (extract-named-music music '(NoteEvent EventChord))))
     (if (pair? elts)
         (let ((first-element (first elts))
               (last-element (last elts)))
           (set! (ly:music-property first-element 'articulations)
                 (cons (make-music 'TextSpanEvent 'span-direction -1)
                       (ly:music-property first-element 'articulations)))
           (set! (ly:music-property last-element 'articulations)
                 (cons (make-music 'TextSpanEvent 'span-direction 1)
                       (ly:music-property last-element 'articulations))))))
   #{
       \once \override TextSpanner.font-size = #-2
       \once \override TextSpanner.font-shape = #'upright
       \once \override TextSpanner.staff-padding = #3
       \once \override TextSpanner.style = #'line
       \once \override TextSpanner.to-barline = ##f
       \once \override TextSpanner.bound-details =
            #`((left
                (text . ,#{ \markup { \raise #-.5 \concat { #str " " }} #})
                (Y . 0)
                (padding . .25)
                (attach-dir . -2))
               (right
                (text . ,#{ \markup { \draw-line #'( 0 . -.75) } #})
                (Y . 0)
                (padding . 0.25)
                (attach-dir . 2)))
      $music
   #})

dbarre =
#(define-music-function (barre location str music) (string? ly:music?)
   (let ((elts (extract-named-music music '(NoteEvent EventChord))))
     (if (pair? elts)
         (let ((first-element (first elts))
               (last-element (last elts)))
           (set! (ly:music-property first-element 'articulations)
                 (cons (make-music 'TextSpanEvent 'span-direction -1)
                       (ly:music-property first-element 'articulations)))
           (set! (ly:music-property last-element 'articulations)
                 (cons (make-music 'TextSpanEvent 'span-direction 1)
                       (ly:music-property last-element 'articulations))))))
   #{
       \once \override TextSpanner.font-size = #-2
       \once \override TextSpanner.font-shape = #'upright
       \once \override TextSpanner.staff-padding = #3
       \once \override TextSpanner.style = #'dashed-line
       \once \override TextSpanner.dash-fraction = #.5
       \once \override TextSpanner.dash-period = #1
       \once \override TextSpanner.to-barline = ##f
       \once \override TextSpanner.bound-details =
            #`((left
                (text . ,#{ \markup { \raise #-.5 \concat { #str " " }} #})
                (Y . 0)
                (padding . .25)
                (attach-dir . -2))
               (right
                (Y . 0)
                (padding . 0.25)
                (attach-dir . 2)))
      $music
   #})

\relative c' {
  \clef "treble_8"
  \key g \major
  \time 4/4
  \hbarre #"C III" { g4 g g g }  \dbarre #"IV" { g g g g }  g g g g
}

enter image description here

  • Thank you so much! That's exactly what I wanted. If I understand correctly I should be able to save these in a separate file and just import them into other projects (so I don't have to type this in every time)? – user57228 Feb 4 at 8:25
  • 1
    Right, you can put the scheme part (upto \relative) into another ly-file and just include it with \include. – Jasper Habicht Feb 4 at 8:29
2

Using Jasper's excellent answer (thanks again!) I was able to make some small modifications which I thought I'd post here for posterity.

The output now looks like this:

enter image description here

Changes include:

  1. Made the font bold, and slightly bigger, which I felt looked better when seen in context with other notation.
  2. Added a separate function for half-barre indication.
  3. There's no longer a need to enter a "C" manually - only the roman numeral needs to be specified.

Here's the code:

\version "2.18.2"

cWithSlash = \markup {
  \translate #'(0.0 . 0.8) \smaller { \musicglyph #"timesig.C22" }
}

cWithoutSlash = \markup {
  \translate #'(0.0 . 0.8) \smaller { \musicglyph #"timesig.C44" }
}

guithalfbarre =
#(define-music-function (barre location str music) (string? ly:music?)
   (let ((elts (extract-named-music music '(NoteEvent EventChord))))
     (if (pair? elts)
         (let ((first-element (first elts))
               (last-element (last elts)))
           (set! (ly:music-property first-element 'articulations)
                 (cons (make-music 'TextSpanEvent 'span-direction -1)
                       (ly:music-property first-element 'articulations)))
           (set! (ly:music-property last-element 'articulations)
                 (cons (make-music 'TextSpanEvent 'span-direction 1)
                       (ly:music-property last-element 'articulations))))))
   #{
       \once \override TextSpanner.font-shape = #'upright
       \once \override TextSpanner.staff-padding = #3
       \once \override TextSpanner.style = #'line
       \once \override TextSpanner.to-barline = ##f
       \once \override TextSpanner.bound-details =
            #`((left
                (text . ,#{ \markup { \raise #-.5 \concat { \cWithSlash \bold { #str " " }}} #})
                (Y . 0)
                (padding . .25)
                (attach-dir . -2))
               (right
                (text . ,#{ \markup { \draw-line #'( 0 . -.75) } #})
                (Y . 0)
                (padding . 0.25)
                (attach-dir . 2)))
      $music
   #})

guitbarre =
#(define-music-function (barre location str music) (string? ly:music?)
  (let ((elts (extract-named-music music '(NoteEvent EventChord))))
        (if (pair? elts)
            (let ((first-element (first elts))
                  (last-element (last elts)))
              (set! (ly:music-property first-element 'articulations)
                    (cons (make-music 'TextSpanEvent 'span-direction -1)
                          (ly:music-property first-element 'articulations)))
              (set! (ly:music-property last-element 'articulations)
                    (cons (make-music 'TextSpanEvent 'span-direction 1)
                          (ly:music-property last-element 'articulations))))))
      #{
          \once \override TextSpanner.font-shape = #'upright
          \once \override TextSpanner.staff-padding = #3
          \once \override TextSpanner.style = #'line
          \once \override TextSpanner.to-barline = ##f
          \once \override TextSpanner.bound-details =
               #`((left
                   (text . ,#{ \markup { \raise #-.5 \concat { \cWithoutSlash \bold { #str " " }}} #})
                   (Y . 0)
                   (padding . .25)
                   (attach-dir . -2))
                  (right
                   (text . ,#{ \markup { \draw-line #'( 0 . -.75) } #})
                   (Y . 0)
                   (padding . 0.25)
                   (attach-dir . 2)))
         $music
      #})


guitpos =
#(define-music-function (barre location str music) (string? ly:music?)
   (let ((elts (extract-named-music music '(NoteEvent EventChord))))
     (if (pair? elts)
         (let ((first-element (first elts))
               (last-element (last elts)))
           (set! (ly:music-property first-element 'articulations)
                 (cons (make-music 'TextSpanEvent 'span-direction -1)
                       (ly:music-property first-element 'articulations)))
           (set! (ly:music-property last-element 'articulations)
                 (cons (make-music 'TextSpanEvent 'span-direction 1)
                       (ly:music-property last-element 'articulations))))))
   #{
       \once \override TextSpanner.font-shape = #'upright
       \once \override TextSpanner.staff-padding = #3
       \once \override TextSpanner.style = #'dashed-line
       \once \override TextSpanner.dash-fraction = #.5
       \once \override TextSpanner.dash-period = #1
       \once \override TextSpanner.to-barline = ##f
       \once \override TextSpanner.bound-details =
            #`((left
                (text . ,#{ \markup { \raise #-.5 \concat \bold { { #str " " }}} #})
                (Y . 0)
                (padding . .25)
                (attach-dir . -2))
               (right
                (Y . 0)
                (padding . 0.25)
                (attach-dir . 2)))
      $music
   #})

Here's how the above example was made

\relative c' {
  %1
  \guithalfbarre #"III" {g4 g4 g4 g4} |

  %2
  \guitbarre #"VI" { g4 g4 g4 g4 }

  %3
  \guitpos #"V" {g4 g4 g4 g4} |
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy