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 acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.