Force text on line without using \textLengthOn

classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

Force text on line without using \textLengthOn

Urs Liska-3
Hi,

I want to use TextScript.staff-padding to produce markup elements that
are aligned to their baseline. In order to prevent the texts from moving
vertically to avoid collisions I used \textLengthOn (or its spelled-out
variant):

\version "2.19.82"

test =
#(define-event-function (text)(markup?)
    #{
      -\tweak extra-spacing-width #(cons -0.0 0.4)
      -\tweak extra-spacing-height #(cons -inf.0 +inf.0)
      -\tweak staff-padding 3
      -\markup #text
    #})

\relative {
   c''8 ^\test "foobar" d16 c
   c8 ^\test "foobar" d16 ^\test "John Doe" c
}

However, this does not only push the next notes when there actually is
some neighboring text (as in the second beat of the following example)
but also when it wouldn't be needed (see atttached image):

Uncommenting the extra-spacing... tweaks will result in the texts moving
vertically which is not desired.

Is there another approach to make the following note columns move - but
only if there *is* something in the way?

Thanks
Urs


_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user

document.png (13K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Force text on line without using \textLengthOn

Aaron Hill
On 2018-10-22 11:27 pm, Urs Liska wrote:

> Hi,
>
> I want to use TextScript.staff-padding to produce markup elements that
> are aligned to their baseline. In order to prevent the texts from
> moving vertically to avoid collisions I used \textLengthOn (or its
> spelled-out variant):
>
> \version "2.19.82"
>
> test =
> #(define-event-function (text)(markup?)
>    #{
>      -\tweak extra-spacing-width #(cons -0.0 0.4)
>      -\tweak extra-spacing-height #(cons -inf.0 +inf.0)
>      -\tweak staff-padding 3
>      -\markup #text
>    #})
>
> \relative {
>   c''8 ^\test "foobar" d16 c
>   c8 ^\test "foobar" d16 ^\test "John Doe" c
> }
>
> However, this does not only push the next notes when there actually is
> some neighboring text (as in the second beat of the following example)
> but also when it wouldn't be needed (see atttached image):
>
> Uncommenting the extra-spacing... tweaks will result in the texts
> moving vertically which is not desired.
>
> Is there another approach to make the following note columns move -
> but only if there *is* something in the way?

At first glance, I would have assumed the issue is that the markup is
only considering the duration of the note to which it is attached.  So
the solution seemed to be to attach the markup to something longer.  I
tried creating a new voice with skips of the appropriate length.  
However, the markup still insisted on stretching the spacing only for
the note at the same moment.  (Is that a bug or just my misunderstanding
of something?)

But lyrics seem to work:

%%%%
   \new Staff {
     <<
       \new Voice { s4 ^"foobar" s8 ^"foobar" s8 ^"John Doe" }
       \new Voice { c''8 d''16 c'' c''8 d''16 c'' }
       \new Lyrics
         \with {
           \override LyricText.self-alignment-X = #-1
           \override LyricText.font-size = #0
         }
         \lyricmode { "foobar"4 "foobar"8 "John Doe"8 }
     >>
   }
%%%%

NOTE: I left in the voice with the skips for reference of my first
approach.  Unsurprisingly, the lyrics cause the notes to space as one
would expect which gives enough room for the markup to function
normally, since I forced the lyrics to be the same size as the default
markup.

So if you want markup to be able to span multiple notes and stay aligned
to a baseline, could you repurpose lyrics for this purpose?

Granted, a potentially big issue with either of the above options is
that the markup is no longer located with the associated notes.  But
perhaps some clever Scheme could take in music with notes and attached
markup in the normal manner and automatically generate a voice without
markup and the markup as lyrics with the appropriate durations.


-- Aaron Hill

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: Force text on line without using \textLengthOn

Urs Liska-3
Hi Aaron,

thank you for these thoughts and suggestions.

 From the layout aspect lyrics would be best, this would save me lots of
grey hair wrt baseline and horizontal alignment. But I had already tried
to do so earlier and failed miserably. The point is: I can't use a
dedicated lyrics variable and need to encode the texts along with the
notes (the input files belong to publicly visible edition contents so
they really have to be "clean").

Maybe I should give that another try ...

Best
Urs


Am 23.10.2018 um 12:17 schrieb Aaron Hill:

> On 2018-10-22 11:27 pm, Urs Liska wrote:
>> Hi,
>>
>> I want to use TextScript.staff-padding to produce markup elements that
>> are aligned to their baseline. In order to prevent the texts from
>> moving vertically to avoid collisions I used \textLengthOn (or its
>> spelled-out variant):
>>
>> \version "2.19.82"
>>
>> test =
>> #(define-event-function (text)(markup?)
>>    #{
>>      -\tweak extra-spacing-width #(cons -0.0 0.4)
>>      -\tweak extra-spacing-height #(cons -inf.0 +inf.0)
>>      -\tweak staff-padding 3
>>      -\markup #text
>>    #})
>>
>> \relative {
>>   c''8 ^\test "foobar" d16 c
>>   c8 ^\test "foobar" d16 ^\test "John Doe" c
>> }
>>
>> However, this does not only push the next notes when there actually is
>> some neighboring text (as in the second beat of the following example)
>> but also when it wouldn't be needed (see atttached image):
>>
>> Uncommenting the extra-spacing... tweaks will result in the texts
>> moving vertically which is not desired.
>>
>> Is there another approach to make the following note columns move -
>> but only if there *is* something in the way?
>
> At first glance, I would have assumed the issue is that the markup is
> only considering the duration of the note to which it is attached.  So
> the solution seemed to be to attach the markup to something longer.  I
> tried creating a new voice with skips of the appropriate length. 
> However, the markup still insisted on stretching the spacing only for
> the note at the same moment.  (Is that a bug or just my
> misunderstanding of something?)
>
> But lyrics seem to work:
>
> %%%%
>   \new Staff {
>     <<
>       \new Voice { s4 ^"foobar" s8 ^"foobar" s8 ^"John Doe" }
>       \new Voice { c''8 d''16 c'' c''8 d''16 c'' }
>       \new Lyrics
>         \with {
>           \override LyricText.self-alignment-X = #-1
>           \override LyricText.font-size = #0
>         }
>         \lyricmode { "foobar"4 "foobar"8 "John Doe"8 }
>     >>
>   }
> %%%%
>
> NOTE: I left in the voice with the skips for reference of my first
> approach.  Unsurprisingly, the lyrics cause the notes to space as one
> would expect which gives enough room for the markup to function
> normally, since I forced the lyrics to be the same size as the default
> markup.
>
> So if you want markup to be able to span multiple notes and stay
> aligned to a baseline, could you repurpose lyrics for this purpose?
>
> Granted, a potentially big issue with either of the above options is
> that the markup is no longer located with the associated notes.  But
> perhaps some clever Scheme could take in music with notes and attached
> markup in the normal manner and automatically generate a voice without
> markup and the markup as lyrics with the appropriate durations.
>
>
> -- Aaron Hill
>
> _______________________________________________
> lilypond-user mailing list
> [hidden email]
> https://lists.gnu.org/mailman/listinfo/lilypond-user


_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: Force text on line without using \textLengthOn

Thomas Morley-2
In reply to this post by Urs Liska-3
Am Di., 23. Okt. 2018 um 08:28 Uhr schrieb Urs Liska <[hidden email]>:

>
> Hi,
>
> I want to use TextScript.staff-padding to produce markup elements that
> are aligned to their baseline. In order to prevent the texts from moving
> vertically to avoid collisions I used \textLengthOn (or its spelled-out
> variant):
>
> \version "2.19.82"
>
> test =
> #(define-event-function (text)(markup?)
>     #{
>       -\tweak extra-spacing-width #(cons -0.0 0.4)
>       -\tweak extra-spacing-height #(cons -inf.0 +inf.0)
>       -\tweak staff-padding 3
>       -\markup #text
>     #})
>
> \relative {
>    c''8 ^\test "foobar" d16 c
>    c8 ^\test "foobar" d16 ^\test "John Doe" c
> }
>
> However, this does not only push the next notes when there actually is
> some neighboring text (as in the second beat of the following example)
> but also when it wouldn't be needed (see atttached image):
>
> Uncommenting the extra-spacing... tweaks will result in the texts moving
> vertically which is not desired.
>
> Is there another approach to make the following note columns move - but
> only if there *is* something in the way?
>
> Thanks
> Urs
Hi Urs,

from your description it sounds you need sort of a spanner with
adjustable length.
Attached some coding hacking TextSpanner.
What do you think?

Cheers,
  Harm

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user

atest-84.png (20K) Download Attachment
atest-84.ly (6K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Force text on line without using \textLengthOn

Urs Liska-3

Hi Harm,

thank you for this. From the *behaviour* this seems like what I need, but I have a few questions that may make it not really usable for my case.


Am 24.10.2018 um 18:25 schrieb Thomas Morley:
Am Di., 23. Okt. 2018 um 08:28 Uhr schrieb Urs Liska [hidden email]:
Hi,

I want to use TextScript.staff-padding to produce markup elements that
are aligned to their baseline. In order to prevent the texts from moving
vertically to avoid collisions I used \textLengthOn (or its spelled-out
variant):

\version "2.19.82"

test =
#(define-event-function (text)(markup?)
    #{
      -\tweak extra-spacing-width #(cons -0.0 0.4)
      -\tweak extra-spacing-height #(cons -inf.0 +inf.0)
      -\tweak staff-padding 3
      -\markup #text
    #})

\relative {
   c''8 ^\test "foobar" d16 c
   c8 ^\test "foobar" d16 ^\test "John Doe" c
}

However, this does not only push the next notes when there actually is
some neighboring text (as in the second beat of the following example)
but also when it wouldn't be needed (see atttached image):

Uncommenting the extra-spacing... tweaks will result in the texts moving
vertically which is not desired.

Is there another approach to make the following note columns move - but
only if there *is* something in the way?

Thanks
Urs
Hi Urs,

from your description it sounds you need sort of a spanner with
adjustable length.
Attached some coding hacking TextSpanner.
What do you think?

I didn't understand the code in detail, but am I right that
  • the code basically prints the texts as the start of a TextSpanner
  • \endTextSpanners parses a music expression and adds a \stopTextSpan automatically for any \startTextSpan
  • \testII creates such a \startTextSpan to be processed by  \endTextSpanners

?

If so this means that all the music must be wrapped in an \endTextSpanners expression, isn't it? If this is true then I would be quite a stretch to integrate this solution into my environment, because the input files are part of the edition in this case. They will be made available within a TEI file and therefore have to be extremely clean. So far there is exactly one \include and then either a single music expression (for a single-voice music example) or several music variables plus a custom \loadTemplate command that loads a file with a \score block to make use of the music variables.

For the first case (simple music expression) I can achieve the result by calling \endTextSpanners at the very end of the include file so the music expression will be used as the argument for the function. But for the other cases I'm not sure how I could arrange my files. In addition I only need this functionality in a subset of my >560 files, but such a solution could probably not be optional in the way I'm doing it elsewhere in the project. (The main include file loads a <filename>-include.ily file if that is present on disk. Within that optional file I can place a layout block, edition-engraver mods and an arbitrary number of \loadTool commands. While this latter function probably isn't necessary for efficiency reasons (it would probably be easier to simply include all the available code for each compiled file), it is a nice way to document the specific needs of an example.)


I think I'll do some more experiments with the code itself before trying to integrate this.

Hm, as said I don't fully understand the code. But if I'm not mistaken \endTextSpanners works by first identifying a music expression that holds a \startTextSpan event and then adding a \stopTextSpan event to the note, rest or chord. Would it be possible to achieve the same thing directly from a music-function or event-function? Maybe if \testII wouldn't be an event function but a music-function taking the note/rest/chord as an argument, like

  \testII ##t "John Doe" c'

where the TextSpanner is added to the c' ?

Best
Urs


Cheers,
  Harm


_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: Force text on line without using \textLengthOn

Thomas Morley-2
Hi Urs,

Am Do., 25. Okt. 2018 um 17:49 Uhr schrieb Urs Liska <[hidden email]>:

>
> Hi Harm,
>
> thank you for this. From the *behaviour* this seems like what I need, but I have a few questions that may make it not really usable for my case.
>
>
> Am 24.10.2018 um 18:25 schrieb Thomas Morley:
>
> Am Di., 23. Okt. 2018 um 08:28 Uhr schrieb Urs Liska <[hidden email]>:
>
> Hi,
>
> I want to use TextScript.staff-padding to produce markup elements that
> are aligned to their baseline. In order to prevent the texts from moving
> vertically to avoid collisions I used \textLengthOn (or its spelled-out
> variant):
>
> \version "2.19.82"
>
> test =
> #(define-event-function (text)(markup?)
>     #{
>       -\tweak extra-spacing-width #(cons -0.0 0.4)
>       -\tweak extra-spacing-height #(cons -inf.0 +inf.0)
>       -\tweak staff-padding 3
>       -\markup #text
>     #})
>
> \relative {
>    c''8 ^\test "foobar" d16 c
>    c8 ^\test "foobar" d16 ^\test "John Doe" c
> }
>
> However, this does not only push the next notes when there actually is
> some neighboring text (as in the second beat of the following example)
> but also when it wouldn't be needed (see atttached image):
>
> Uncommenting the extra-spacing... tweaks will result in the texts moving
> vertically which is not desired.
>
> Is there another approach to make the following note columns move - but
> only if there *is* something in the way?
>
> Thanks
> Urs
>
> Hi Urs,
>
> from your description it sounds you need sort of a spanner with
> adjustable length.
> Attached some coding hacking TextSpanner.
> What do you think?
>
>
> I didn't understand the code in detail, but am I right that
>
> the code basically prints the texts as the start of a TextSpanner

Yes

> \endTextSpanners parses a music expression and adds a \stopTextSpan automatically for any \startTextSpan

Not exactly, the first event with \startTextSpan is disregarded, all
other events with \startTextSpan get a \stopTextSpan added. The last
note/rest/skip/eventchord gets a \stopTextSpan as well.

> \testII creates such a \startTextSpan to be processed by  \endTextSpanners

Yes

>
> ?
>
> If so this means that all the music must be wrapped in an \endTextSpanners expression, isn't it?

Not exactly.
The proposed code/example does so, yes.
Though, \endTextSpanners is more for conveniance., you could drop
\endTextSpanners entirely and set \stopTextSpan manually.

> If this is true then I would be quite a stretch to integrate this solution into my environment, because the input files are part of the edition in this case. They will be made available within a TEI file and therefore have to be extremely clean. So far there is exactly one \include and then either a single music expression (for a single-voice music example) or several music variables plus a custom \loadTemplate command that loads a file with a \score block to make use of the music variables.
>
> For the first case (simple music expression) I can achieve the result by calling \endTextSpanners at the very end of the include file so the music expression will be used as the argument for the function. But for the other cases I'm not sure how I could arrange my files. In addition I only need this functionality in a subset of my >560 files, but such a solution could probably not be optional in the way I'm doing it elsewhere in the project. (The main include file loads a <filename>-include.ily file if that is present on disk. Within that optional file I can place a layout block, edition-engraver mods and an arbitrary number of \loadTool commands. While this latter function probably isn't necessary for efficiency reasons (it would probably be easier to simply include all the available code for each compiled file), it is a nice way to document the specific needs of an example.)


Well, I'm not familiar with TEI, the edition-engraver, etc.
Sorry.

>
>
> I think I'll do some more experiments with the code itself before trying to integrate this.
>
> Hm, as said I don't fully understand the code. But if I'm not mistaken \endTextSpanners works by first identifying a music expression that holds a \startTextSpan event and then adding a \stopTextSpan event to the note, rest or chord. Would it be possible to achieve the same thing directly from a music-function or event-function? Maybe if \testII wouldn't be an event function but a music-function taking the note/rest/chord as an argument, like
>
>   \testII ##t "John Doe" c'
>
> where the TextSpanner is added to the c' ?

Well, you can't start _and_ end a TextSpanner on the same event. See
the warning for { c'1\startTextSpan\stopTextSpan }.
Thus the sophisticated endTextSpanner. Ofcourse endTextSpanner can't
end a textSpanner which is started at the last note of a file as well.

It's thinkable to create a music-functions taking a musical argument
and doing something like
{ \myFunction c'1 }
-> { c'1\startTextSpan <>\stopTextSpan }
This will return a warning if at happens at the end of a file, though.

Cheers,
  Harm

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: Force text on line without using \textLengthOn

Urs Liska-3
Hi Harm,


Am 25.10.2018 um 23:38 schrieb Thomas Morley:

> Hi Urs,
>
> Am Do., 25. Okt. 2018 um 17:49 Uhr schrieb Urs Liska <[hidden email]>:
>> ...
>>
>>
>> > Hi Urs,
>>
>> > from your description it sounds you need sort of a spanner with
>> > adjustable length.
>> > Attached some coding hacking TextSpanner.
>> > What do you think?
>>
>>
>> I didn't understand the code in detail, but am I right that
>>
>> the code basically prints the texts as the start of a TextSpanner
> Yes
>
>> \endTextSpanners parses a music expression and adds a \stopTextSpan automatically for any \startTextSpan
> Not exactly, the first event with \startTextSpan is disregarded, all
> other events with \startTextSpan get a \stopTextSpan added. The last
> note/rest/skip/eventchord gets a \stopTextSpan as well.
OK. I don't really understand the handling of first and last events
here, but I think I don't need this approach anyway.

>
>> \testII creates such a \startTextSpan to be processed by  \endTextSpanners
> Yes
>
>> ?
>>
>> If so this means that all the music must be wrapped in an \endTextSpanners expression, isn't it?
> Not exactly.
> The proposed code/example does so, yes.
> Though, \endTextSpanners is more for conveniance., you could drop
> \endTextSpanners entirely and set \stopTextSpan manually.
I had a try that *seemed* to be successful, see below

>> If this is true then I would be quite a stretch to integrate this solution into my environment, because the input files are part of the edition in this case. They will be made available within a TEI file and therefore have to be extremely clean. So far there is exactly one \include and then either a single music expression (for a single-voice music example) or several music variables plus a custom \loadTemplate command that loads a file with a \score block to make use of the music variables.
>>
>> For the first case (simple music expression) I can achieve the result by calling \endTextSpanners at the very end of the include file so the music expression will be used as the argument for the function. But for the other cases I'm not sure how I could arrange my files. In addition I only need this functionality in a subset of my >560 files, but such a solution could probably not be optional in the way I'm doing it elsewhere in the project. (The main include file loads a <filename>-include.ily file if that is present on disk. Within that optional file I can place a layout block, edition-engraver mods and an arbitrary number of \loadTool commands. While this latter function probably isn't necessary for efficiency reasons (it would probably be easier to simply include all the available code for each compiled file), it is a nice way to document the specific needs of an example.)
>
> Well, I'm not familiar with TEI, the edition-engraver, etc.
> Sorry.

That's not necessary here. All I wanted to point out is that I need
"clean" input files and a generic structure where I can't wrap the music
variables in an arbitrary function call. The reference to the TEI is
only that the primary input file's content will be included in the
edition and should be stripped of any code that is only needed for
rendering purposes. Eventually the project will be publicly available,
and I'll probably write about it so it'll become clearer what this is
about ...

>>
>> I think I'll do some more experiments with the code itself before trying to integrate this.
>>
>> Hm, as said I don't fully understand the code. But if I'm not mistaken \endTextSpanners works by first identifying a music expression that holds a \startTextSpan event and then adding a \stopTextSpan event to the note, rest or chord. Would it be possible to achieve the same thing directly from a music-function or event-function? Maybe if \testII wouldn't be an event function but a music-function taking the note/rest/chord as an argument, like
>>
>>    \testII ##t "John Doe" c'
>>
>> where the TextSpanner is added to the c' ?
> Well, you can't start _and_ end a TextSpanner on the same event. See
> the warning for { c'1\startTextSpan\stopTextSpan }.
> Thus the sophisticated endTextSpanner. Ofcourse endTextSpanner can't
> end a textSpanner which is started at the last note of a file as well.
>
> It's thinkable to create a music-functions taking a musical argument
> and doing something like
> { \myFunction c'1 }
> -> { c'1\startTextSpan <>\stopTextSpan }
> This will return a warning if at happens at the end of a file, though.
I copied all relevant code to a different structure, and while it
compiles and produces the spanners as desired there are still problems.

%%%
\version "2.19.82"

#(define (minimum-length-from-stencil process-string?)
    ;; Set the minimum-length of a grob, which is supposed to be a TextSpanner,
    ;; to the length of the stencil of bound-details.left.text plus 0.1
    (lambda (grob)
      (let* ((bound-details (ly:grob-property grob 'bound-details))
             (lft (assoc-get 'left bound-details))
             (txt (assoc-get 'text lft))
             (txt-stil
              (if (markup? txt)
                  (grob-interpret-markup
                   grob
                   (if process-string?
                       (markup->string txt)
                       txt))
                  #f))
             (txt-x-ext (if txt-stil (ly:stencil-extent txt-stil X) #f))
             (txt-x-length
              (if (and txt-x-ext (interval-sane? txt-x-ext))
                  (- (cdr txt-x-ext) (car txt-x-ext))
                  0)))
        (+ txt-x-length 0.1))))


startSingleTextSpan =
#(define-event-function (text-length-on txt)((boolean? #f) markup?)
    #{
      -\tweak style #'none
      -\tweak staff-padding 3
      -\tweak springs-and-rods #ly:spanner::set-spacing-rods
      -\tweak minimum-length  #(minimum-length-from-stencil #f)
      -\tweak minimum-length-after-break 0
      -\tweak font-shape #'upright
      -\tweak bound-details.left.text
      #(if text-length-on
           txt
           (make-with-dimensions-markup empty-interval empty-interval txt))
      -\tweak bound-details.left-broken.text ##f
      \startTextSpan
    #})

spanner =
#(define-music-function (text-length-on text music)((boolean?) markup? ly:music?)
    (let*
     ((is-single-music #t))
     (define (append-script-at! prop)
       (set! (ly:music-property music prop)
             (append (ly:music-property music prop)
               (list (startSingleTextSpan text-length-on text)))))

     (case (ly:music-property music 'name)
       ((EventChord)
        (append-script-at! 'elements))
       ((NoteEvent RestEvent SkipEvent)
        (append-script-at! 'articulations))
       (else (set! is-single-music #f)))
     
     (if is-single-music
         #{
           #music
           <>\stopTextSpan
         #}
         music)))

my-upbow =
#(define-music-function (text-length-on music)((boolean?) ly:music?)
    (spanner text-length-on "hin." music))

my-downbow =
#(define-music-function (text-length-on music)((boolean?) ly:music?)
    (spanner text-length-on "her." music))

\relative {
   \my-upbow #f
   c'16 ( d e f )
   \my-downbow #f g (
   \my-upbow #f a g a )
   \my-upbow #f \time 2/4
}
%%%

I've reversed the logic of zero-dimensions? to a text-length-on argument
(#t meaning: do use the space). This doesn't affect the outcome, and the
wrong behaviour was the same before I changed this.

The problem is that with this text-length-on being true the spanner
pushes the next *note*, even if that doesn't have any spanner attached
(first attached image) while with it being false the spanners will
collide (second attachment). Additionally (but this is already present
in your code) when using make-with-dimensions-markup (where is this
defined? I don't find this with git grep???) the spanner will have no
vertical extent as well, which can cause it to be cut off from the page
(or collide with the previous system).

I don't see why the horizontal behaviour is any different in my version,
and I can only speculate that it *does* have something to do with the
way \endTextSpanners handles the events.

Any ideas?

PS:
I assume it is *not* possible to write a function that can be written as
post-event that will add the \startTextSpan event to the current note
*and* adds the <>\stopTextSpan as the next note? I'm asking because I
would actually like to have this function as a drop-in replacement for
\upbow and \downbow.

>
> Cheers,
>    Harm


_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user

document.png (13K) Download Attachment
document.png (12K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Force text on line without using \textLengthOn

Davide Liessi-2
Il giorno ven 26 ott 2018 alle ore 11:55 Urs Liska
<[hidden email]> ha scritto:
> make-with-dimensions-markup (where is this
> defined? I don't find this with git grep???)

`git grep with-dimensions` finds
scm/define-markup-commands.scm:(define-markup-command (with-dimensions
layout props x y arg)

I might have a similar problem, i.e., automatically add
\stopTextSpanner commands to mimick \tempo with TextSpanner (see
https://lists.gnu.org/archive/html/lilypond-user/2018-10/msg00238.html)
Although I can offer no insights at present, I'm definitely interested.

Best wishes.
Davide

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: Force text on line without using \textLengthOn

Thomas Morley-2
In reply to this post by Urs Liska-3
Hi Urs,

currently I've not the time to dive deeper in your code, maybe later
today or during the upcoming weekend.
For now only about:

Am Fr., 26. Okt. 2018 um 11:54 Uhr schrieb Urs Liska <[hidden email]>:
> Additionally (but this is already present
> in your code) when using make-with-dimensions-markup (where is this
> defined? I don't find this with git grep???)

For demonstration purpose I use make-italic-markup, less typing ;)

If you define a markup command using the macro 'define-markup-command'
from 'markup-macros.scm', then this macro returns two procedures.
From its doc-string (shortened)
"
* Define a COMMAND-markup function after command-and-args and body
* define a make-COMMAND-markup function.
"

So after having done
(define-markup-command (italic layout props arg) ...)
we get the procedures 'italic-markup' and 'make-italic-markup'

How they differ can be watched easily by displaying them in the scheme-sandbox:

guile> (display make-italic-markup)
#<procedure make-italic-markup args>

guile> (display italic-markup)
#<procedure italic-markup (layout props arg)

Note the different arguments.

In usage '(make-italic-markup "foo") will return a procedure, in a
ly-file it can be called directly with $(make-italic-markup "foo")
Whereas 'italic-markup' needs to get proper layout/props-arguments and
it will return a stencil!
Example:
\displayScheme
\markup \stencil
$(italic-markup
  $defaultpaper
  (list
    (cons
      '(font-encoding . latin1)
      (ly:output-def-lookup $defaultlayout 'text-font-defaults)))
  "buzz")

Also, note they difference here:[1]
#(pretty-print (procedure-source make-italic-markup))
->
(lambda args
  (#<procedure make-markup (markup-function make-name args)>
   italic-markup
   "make-italic-markup"
   args))


#(pretty-print (procedure-source italic-markup))
->
(lambda (layout props arg)
  "(arg)
Use italic @code{font-shape} for @var{arg}.

@lilypond[verbatim,quote]
\\markup {
  default
  \\hspace #2
  \\italic
  italic
}
@end lilypond"
  (let ()
    (interpret-markup
      layout
      (prepend-alist-chain
        'font-shape
        'italic
        props)
      arg)))
The latter returns the code from define-markup-commands.

Apart from that we have this syntax as well:
(markup #:italic "foo")
with:
#(pretty-print (markup #:italic "foo"))
returning a procedure(!)
(#<procedure line-markup (layout props args)>
 ((#<procedure italic-markup (layout props arg)>
   "foo")))
callable in a ly-file with $(markup #:italic "foo")

So the italic-markup is wrapped into a line-markup and the
"markup-mode" provides the layout/props-arguments.

All pretty confusing at first glance, but I've found use-cases for all
possibilities.


For basic use: if you happen to see some 'make-whatever-markup' drop
'make-' and '-markup' and see the name of the markup-command-name as
defined in the source or by the user.

HTH a bit,
  Harm

[1]
Regrettable 'procedure-source' is disabled in guilev2, see the thread
starting here:
https://lists.gnu.org/archive/html/guile-user/2012-09/msg00020.html
With the consequence our display-lily-procedures will not always work as before:

\void
\displayLilyMusic
\applyContext #(lambda (ctx) (ly:context-set-property ctx 'fontSize 6))

with guilev1:
\applyContext #(lambda (ctx)
  (ly:context-set-property ctx (quote fontSize) 6))

with guilev2:
\applyContext ##f

I already tried to implement something like ly:procedure-source in
general-scheme.cc based on the old guilev1-coding.
Not sure if it would be possible at all. But pretty sure it's
impossible for me with my lack of C++-knowledge.

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: Force text on line without using \textLengthOn

Urs Liska-3
Hi Harm


Am 26.10.2018 um 13:58 schrieb Thomas Morley:

> Hi Urs,
>
> currently I've not the time to dive deeper in your code, maybe later
> today or during the upcoming weekend.
> For now only about:
>
> Am Fr., 26. Okt. 2018 um 11:54 Uhr schrieb Urs Liska <[hidden email]>:
>> Additionally (but this is already present
>> in your code) when using make-with-dimensions-markup (where is this
>> defined? I don't find this with git grep???)

Thank you for these explanations. Without *really* understanding
everything I was able to create 'make-with-empty-x-markup' that produces
a markup with an empty X and the original Y extent:

%%%
#(define-markup-command (with-empty-x layout props arg)(markup?)
    "Create a markup with empty X and native Y extent."
    (let*
     ((stencil (interpret-markup layout props arg))
      (y-extent (ly:stencil-extent stencil Y)))
     (ly:stencil-outline
      stencil
      (make-filled-box-stencil '(0 . 0) y-extent))))
%%%

and replace the call with (basically)

-\tweak bound-details.left.text #(make-with-empty-x-markup txt))

This makes the problem of the vertical alignment and extent go away, but
of course not the horizontal aspects.

Best
Urs

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: Force text on line without using \textLengthOn

Kieren MacMillan
Hi Urs,

Sorry I didn’t get in on this thread earlier — too much going on!

> Without *really* understanding everything I was able to create 'make-with-empty-x-markup' that produces a markup with an empty X and the original Y extent:

Not sure if these functions are helpful to you, but I use these to create markups that bypass the horizontal and/or vertical spacing algorithm(s):

ignoreH =
   \propertyTweak horizontal-skylines ##f
   \propertyTweak extra-spacing-width #empty-interval
   \etc

ignoreV =
   \propertyTweak vertical-skylines ##f
   \propertyTweak extra-spacing-height #empty-interval
   \etc

ignore = \ignoreH \ignoreV \etc

Just in case they’re helpful!
Kieren.
________________________________

Kieren MacMillan, composer
‣ website: www.kierenmacmillan.info
‣ email: [hidden email]


_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: Force text on line without using \textLengthOn

Kieren MacMillan
p.s.

> I use these to create markups that bypass the horizontal and/or vertical spacing algorithm(s):

Actually, I use those functions to make *any* grob bypass the respective spacing algorithm(s)!

Kieren.
________________________________

Kieren MacMillan, composer
‣ website: www.kierenmacmillan.info
‣ email: [hidden email]


_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: Force text on line without using \textLengthOn

Thomas Morley-2
In reply to this post by Thomas Morley-2
Am Fr., 26. Okt. 2018 um 13:58 Uhr schrieb Thomas Morley
<[hidden email]>:

> currently I've not the time to dive deeper in your code, maybe later
> today or during the upcoming weekend.

Hi Urs,

I haven't looked deeply into your code, but I think it will not work as desired.

First some general words about (Text)Spanner.
A (Text)Spanner is spanned between it's left/right bound, usually
without affecting spacing of the spanned NoteColumns at all.
If you enlarge the (Text)Spanners width, Lilypond will now use this to
space the covered NoteColumns following the built-in rules.

Example:
{
  c'8 c' c' c'
  \override TextSpanner.springs-and-rods = #ly:spanner::set-spacing-rods
  \override TextSpanner.minimum-length = 20
  c'8\startTextSpan c' c' c'\stopTextSpan
}
Here the different spacing is obvious but each is even.


In my approach I therefore tried to end (Text)Spanners as late as
possible to benefit from this behaviour.

I'm aware I mentioned the possibility to insert <>\stopTextSpanner via
a function right after the \startTextSpan, i.e. before the next event.
Your function follows those lines.
Though, now you don't benefit from the even spacing of the covered
NoteColumn, because you only have the start and end.
{
  c'8 c' c' c'
  \override TextSpanner.springs-and-rods = #ly:spanner::set-spacing-rods
  \override TextSpanner.minimum-length = 20
  c'8\startTextSpan <>\stopTextSpan c' c' c'
}

The fiddling to find the correct minimum-length of the (Text)Spanner
is of secondary importance. With or without empty dimensions of the
(Text)Spanners text.

Sorry, if I pointed in a wrong direction.
I currently don't have further insights or hints as well :(

Though, Kieren pointed to his ignore(H/V)-definitions.

Admittedly I don't know what they are about.

Testing them with

ignoreH =
   \propertyTweak horizontal-skylines ##f
   \propertyTweak extra-spacing-width #empty-interval
   \etc

ignoreV =
   \propertyTweak vertical-skylines ##f
   \propertyTweak extra-spacing-height #empty-interval
   \etc

ignore = \ignoreH \ignoreV \etc

{
  c'8-\ignore ^"foo"
  c'8-\ignore ^"bar"
}

returns a segfault:

warning: cannot find skylines - strange alignment will follow
  c'8
     -\ignore ^"foo"
lilypond: /home/gub/NewGub/gub/target/linux-64/src/lilypond-git.sv.gnu.org--lilypond.git-stable-2.20/lily/skyline.cc:660:
Real Skyline::internal_distance(const Skyline&, Real*) const:
Assertion `sky_ == -other.sky_' failed.
Aborted (core dumped)

Kieren, could you propose some use-cases?


Cheers,
  Harm

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user