Discussion:
Adding text to slurs
Pablo Cordal
2018-11-04 08:38:51 UTC
Permalink
Hi to everyone from Spain,

I have got a special need with lilypond. I need to add text to slurs for
educational purposes, I'm a music teacher and I'd like to add information
to musical phrases. The code:

\version "2.18.2"
#(ly:set-option 'midi-extension "midi")
\header {}

\score {
<<
\new Staff = "melody" {
\clef "treble"
\set Staff.midiInstrument = #"acoustic grand"
\new Voice {
\override Score.BarNumber.break-visibility = #'#(#f #t #t)
\override Score.BarNumber.font-size = #-4
\slurDown
\time 4/4

\set Score.currentBarNumber = #0
r2.^\markup { \column { \bold "The Beatles - Till there was you
(1950)" "A(16)" } } e'4(
\bar "|." g'4) r2 e'4( g'4) r2 e'4( g'4 f'4) r4 c''4(
g'4 f'4) r4 c'4( f'4 e'4 b'2 a'2) r2 c'2( g'2) r2. e'4(
\bar "||" \break
g'4) r2 e'4( g'4) r2 e'4( g'4 f'4) r4 c''4( g'4 f'4)
r4 c'4( f'4 e'4 b'2 a'2) r2 c'2( c'2) r1 \bar "|." \break
\set Score.currentBarNumber = #0
r2 c'2(^\markup { "B(8)" } \bar "|." d''2 c''2) r2
d''2( a'2 g'2 a'2 b'2) a'1( e'2 c'2 d'1) dis'1 \bar "|." \break
}
}
\layout { indent = #0 }
}

\markup {
\column {
\line { \hspace #1.0 }

}
}

I've checking the online manual and no info about this. Anybody can help
with this?

Best regards to all
Urs Liska
2018-11-05 10:05:46 UTC
Permalink
Hi Pablo,
Post by Pablo Cordal
Hi to everyone from Spain,
I have got a special need with lilypond. I need to add text to slurs
for educational purposes, I'm a music teacher and I'd like to add
information to musical phrases.
I have recently written a function (with extensive help from this list)
that should be exactly what you need. It places a markup centered above
or below (depending on the direction) of a slur:

\version "2.19.82"

% "Annotate" a slur with a horizontally centered markup.
% The vertical position of the markup is determined both by
% (uses the greater of) the mozart.markup-staff-padding option and
% the min-padding argument.
%
% NOTE: As this function is an after-line-breaking callback it can't
% provide any collision handling for the added markup. This may result
% in collisions with other score elements, or it can cause the added
% markup to be cut off at the paper border. For the latter case the
% function \forceTopCropping from the paper-top-padding tool can be used.


annotatedSlur =
#(define-event-function (min-padding text)((number? 1) markup?)
"Create a slur with an attached markup."
#{
-\tweak after-line-breaking
#(lambda (grob)
(let*
((dir (ly:grob-property grob 'direction))
;; staff-padding from the options
(staff-padding (getOption '(mozart markup-staff-padding)))
;; The original slur stencil
(stencil (ly:slur::print grob))
;; A new stencil for the markup
(markup-stencil (grob-interpret-markup grob text))
;; Y-extent of the original slur for later reference
(slur-extent (ly:grob-property grob 'Y-extent))
;; total height of slur
(slur-height (- (cdr slur-extent) (car slur-extent)))
;; absolute distance of outer slur edge from middle staffline
(outer-slur-edge-abs
(abs (if (> dir 0) (cdr slur-extent) (car slur-extent))))
;; Y-extent of the added markup stencil
(markup-extent (ly:stencil-extent markup-stencil Y))
;; total height of markup
(markup-height (- (cdr markup-extent) (car markup-extent)))
;; height of lower extender or X height, depending on direction
(markup-inner-height
(if (> dir 0)
(* -1 (car markup-extent))
(cdr markup-extent)))
;; offset because staff-padding *below* staff is increased by 1
(direction-offset (if (> dir 0) 0 -1))
;; padding between slur and markup, based on both the min-padding
;; argument and the global mozart.markup-staff-padding option
(effective-padding
(max
(- (+ staff-padding 2)
markup-inner-height
direction-offset
outer-slur-edge-abs)
min-padding))
;; necessary horizontal shift to center the markup against the slur
(hshift (- (interval-center (ly:stencil-extent stencil X))
(interval-center (ly:stencil-extent markup-stencil X))))
;; combined stencil from slur and text
(new-stencil
(ly:stencil-combine-at-edge stencil Y dir
(ly:stencil-translate-axis markup-stencil hshift X)
effective-padding)))
;; enclose the *new* stencil by the modified Y-extent
;; NOTE: this only makes the whole thing *clickable*, it doesn't
;; help with pushing the staff towards the bottom of the page.
(ly:grob-set-property! grob 'Y-extent
(if (> dir 0)
(cons
(car slur-extent)
(+ (car slur-extent) slur-height effective-padding markup-height))
(cons
(- (car slur-extent) effective-padding markup-height)
(cdr slur-extent))))
(ly:grob-set-property! grob 'stencil new-stencil)))
% NOTE: this is a slur-event, not a misplaced parenthesis
(
#})

You would use it like

{
c'1 ^\annotatedSlur "My text" c' ) c' _\annotatedSlur 4 "My padded text" c' )
}

HTH
Urs
Urs Liska
2018-11-05 10:15:59 UTC
Permalink
Post by Urs Liska
Hi Pablo,
Post by Pablo Cordal
Hi to everyone from Spain,
I have got a special need with lilypond. I need to add text to slurs
for educational purposes, I'm a music teacher and I'd like to add
information to musical phrases.
I have recently written a function (with extensive help from this
list) that should be exactly what you need. It places a markup
\version "2.19.82"
...
Oops, I'm sorry, there is some "private" code in here that prevents it
from compiling. At the very least you would have to replace the line
   (staff-padding (getOption '(mozart markup-staff-padding)))
with e.t.
   (staff-padding 3)

but if you don't want to have staff-padding (which is used to try
placing all markups on a common baseline) there would be more to change.

Urs
pablocordal
2018-11-08 15:00:23 UTC
Permalink
Hi everyone!

I really have a special need with this function we have been talking about:

<code>
annotatedSlur =
#(define-music-function (parser location padding text) (number? markup?)
#{
\once \override Slur.after-line-breaking =
#(lambda (grob)
(let*
((stencil (ly:slur::print grob))
(dir (ly:grob-property grob 'direction))
(markup-stencil (grob-interpret-markup grob text))
(shift (- (interval-center (ly:stencil-extent stencil X))
(interval-center (ly:stencil-extent markup-stencil X))))
(new-stencil
(ly:stencil-combine-at-edge
stencil
Y dir
(ly:stencil-translate-axis markup-stencil shift X)
padding)))
(ly:grob-set-property! grob 'stencil new-stencil)))
#})
</code>

The funcion works fine, but I think it would be even better if it could
receive another number. This number should move the text horizontally in the
slur- sometimes, the text collides with another element, and it would be
great to move it forward or backward a little.

Any master coder out there can help me with this please?

Thank you. Best regards



--
Sent from: http://lilypond.1069038.n5.nabble.com/User-f3.html
Urs Liska
2018-11-08 16:29:51 UTC
Permalink
Post by pablocordal
Hi everyone!
<code>
annotatedSlur =
#(define-music-function (parser location padding text) (number? markup?)
#{
\once \override Slur.after-line-breaking =
#(lambda (grob)
(let*
((stencil (ly:slur::print grob))
(dir (ly:grob-property grob 'direction))
(markup-stencil (grob-interpret-markup grob text))
(shift (- (interval-center (ly:stencil-extent stencil X))
(interval-center (ly:stencil-extent markup-stencil X))))
(new-stencil
(ly:stencil-combine-at-edge
stencil
Y dir
(ly:stencil-translate-axis markup-stencil shift X)
padding)))
(ly:grob-set-property! grob 'stencil new-stencil)))
#})
</code>
The funcion works fine, but I think it would be even better if it could
receive another number. This number should move the text horizontally in the
slur- sometimes, the text collides with another element, and it would be
great to move it forward or backward a little.
Any master coder out there can help me with this please?
annotatedSlur =
#(define-music-function (parser location padding hor-offset text)
(number? number? markup?)
   #{
     \once \override Slur.after-line-breaking =
     #(lambda (grob)
        (let*
         ((stencil (ly:slur::print grob))
          (dir (ly:grob-property grob 'direction))
          (markup-stencil (grob-interpret-markup grob text))
          (shift (+ hor-offset
                   (- (interval-center (ly:stencil-extent stencil X))
                   (interval-center (ly:stencil-extent markup-stencil
X)))))
          (new-stencil
           (ly:stencil-combine-at-edge
            stencil
            Y dir
            (ly:stencil-translate-axis markup-stencil shift X)
            padding)))
         (ly:grob-set-property! grob 'stencil new-stencil)))
   #})

{
  \annotatedSlur 2 1 "Here"
  c'1 ( d' )
}

But of course this means you have to use "0" everytime you do *not* need
the horizontal offset.

Best
Urs
Post by pablocordal
Thank you. Best regards
--
Sent from: http://lilypond.1069038.n5.nabble.com/User-f3.html
_______________________________________________
lilypond-user mailing list
https://lists.gnu.org/mailman/listinfo/lilypond-user
Loading...