Re: Tags for contexts without duration

2022-04-15 Thread Jean Abou Samra

Le 15/04/2022 à 14:12, Kieren MacMillan a écrit :

Hi Dimitris,

If you get into more numerous and complex tweaks, I highly recommend using the 
edition-engraver — keeping presentation tweaks (e.g., moving a RehearsalMark) 
out of the note code is my primary use-case for the EE.

Hope that helps!
Kieren.




Surprisingly, I could predict this comment of yours would come. =)

Cheers,
Jean




Re: Custom Spanner with variable length sections

2022-04-15 Thread Jean Abou Samra

Le 15/04/2022 à 22:41, Dimitris Marinakis a écrit :

Thank you, much better now :)

The only thing to improve here would be to have separate paddings for 
each system. For some reason the staff-padding currently behaves more 
like a fixed offset. If you have very high notes they get clipped.




Well, that's exactly the meaning of staff-padding -- the padding
from the staff symbol. The setting for the distance from note heads
and such is padding. I just didn't implement distancing from note
heads because I didn't know if I had to. I thought you'd be putting
the grob on its own in some Dynamics-like context. See below for
an implementation that has it; it's just one added line of code.

What are you using this spanner for, by the way?



I'm using 2.23.0. I can't use the latest versions for all of my 
projects yet because I'm using a font that doesn't have the new 
microtonal accidentals. I hope the creator of the font finds the time 
to update it or I'll need to do it myself.
Besides, I have over 12K lines of code with custom stuff that some of 
it will most likely break with the version change.




Ok, ok, the code below works in 2.23.0. I am surprised
by the font issue though. Is LilyPond preventing you from
using a font because it lacks some accidentals even if
you are not using these accidentals?

Jean



\version "2.23.0"

#(define (define-grob! grob-name grob-entry)
   (set! all-grob-descriptions
 (cons ((@@ (lily) completize-grob-entry)
    (cons grob-name grob-entry))
   all-grob-descriptions)))

#(define (partial-sums lst)
   (cdr (reverse! (fold
   (lambda (new previous)
 (cons (+ new (car previous))
   previous))
   (list 0)
   lst

#(define (symbol-filler::print grob)
   (let* ((widths (ly:grob-property grob 'widths))
  (symbols (ly:grob-property grob 'symbols))
  (orig (ly:grob-original grob))
  (proto-siblings (ly:spanner-broken-into orig))
  (siblings (if (null? proto-siblings)
    (list grob)
    proto-siblings))
  (sib-exts-to-fill
   (map
    (lambda (sib)
  (define (on-dir sym dir)
    (let* ((details (ly:grob-property sib sym))
   (x (assoc-get 'X details))
   (pding (assoc-get 'padding details)))
  (+ x (* -1 dir pding
  (cons (on-dir 'left-bound-info LEFT)
    (on-dir 'right-bound-info RIGHT)))
    siblings))
  (sib-widths (map interval-length sib-exts-to-fill))
  (sib-changes (partial-sums sib-widths))
  (total-spanner-width (apply + sib-widths))
  (total-sym-width (apply + widths))
  (normalized-syms (map (lambda (x)
   (* x (/ total-spanner-width 
total-sym-width)))

 widths))
  (sym-changes (partial-sums normalized-syms))
  (sib-stil empty-stencil)
  (len-so-far 0)
  (retval #f))
 ;; Let's do an exception.  This is easier written in imperative style.
 (while (and (pair? sib-changes)
 (pair? sym-changes))
   (let* ((sib (car siblings))
  (next-sym-maybe (car symbols))
  (next-stil-maybe (grob-interpret-markup sib next-sym-maybe))
  (len (interval-length (ly:stencil-extent next-stil-maybe X)))
  (new-len-so-far (+ len len-so-far)))
 (cond
  ((> new-len-so-far (car sib-changes))
   ;; Used full length of this broken piece.  Set
   ;; its stencil and start using the next.
   (let* ((sys (ly:grob-system sib))
  (tr (- (interval-start (car sib-exts-to-fill))
 (ly:grob-relative-coordinate sib sys X)))
  (tr-stil (ly:stencil-translate-axis sib-stil tr X)))
 (if (eq? grob (car siblings))
 (set! retval tr-stil)
 (ly:grob-set-property! (car siblings)
    'stencil
    tr-stil)))
   (set! sib-changes (cdr sib-changes))
   (set! siblings (cdr siblings))
   (set! sib-stil empty-stencil)
   (set! sib-exts-to-fill (cdr sib-exts-to-fill)))
  ((> new-len-so-far (car sym-changes))
   ;; Done with this symbol, start using the next.
   (set! sym-changes (cdr sym-changes))
   (set! symbols (cdr symbols)))
  (else
   (set! sib-stil (ly:stencil-stack sib-stil X RIGHT 
next-stil-maybe 0))

   (set! len-so-far new-len-so-far)
 retval))

#(define-grob! 'SymbolFiller
   `((bound-details . ((left . ((padding . 0)
    (Y . 0)))
   (right . ((padding . 0)
 (Y . 0)
 (direction . ,DOWN)

Re: Custom Spanner with variable length sections

2022-04-15 Thread Dimitris Marinakis
Thank you, much better now :)

The only thing to improve here would be to have separate paddings for each
system. For some reason the staff-padding currently behaves more like a
fixed offset. If you have very high notes they get clipped.
[image: customspannerclippednotes.jpg]


I'm using 2.23.0. I can't use the latest versions for all of my projects
yet because I'm using a font that doesn't have the new microtonal
accidentals. I hope the creator of the font finds the time to update it or
I'll need to do it myself.
Besides, I have over 12K lines of code with custom stuff that some of it
will most likely break with the version change.

I'll do must best to update to the latest version as soon as possible.
Thanks again for your help.

Best,
Dimitris

On Fri, Apr 15, 2022 at 10:07 PM Jean Abou Samra  wrote:

> Le 15/04/2022 à 16:35, Dimitris Marinakis a écrit :
> > Thank you so much Jean. That looks amazing for a first try. Great work!
> >
> > Sorry it took me a while to test it.
>
>
> Less than a day? I didn't find that long :-)
>
>
> > Upon testing I found out that it only works when there are line breaks
> > (not on a single system).
>
>
>
> Right, I intended to add this code, but forgot it along the way.
>
>
>
> > Also it would be useful to have control over the broken.left/right
> > paddings. This is an issue especially if the spanner is used above the
> > stave (clef collisions).
> >
> > Is it too hard to an option to align the broken sections on the first
> > and last notes in the system instead of the system edges? The current
> > behaviour isn't wrong. It's just not suitable for all use cases.
>
>
>
> See the second attempt below. This SymbolFiller implements a subset
> of the horizontal-line-spanner-interface. You can override padding and
> end-on-note in bound-details.
>
> I hope you don't mind that this now requires a development version.
>
> Best,
> Jean
>
>
>
> \version "2.23.7"
>
> #(define (define-grob! grob-name grob-entry)
> (set! all-grob-descriptions
>   (cons ((@@ (lily) completize-grob-entry)
>  (cons grob-name grob-entry))
> all-grob-descriptions)))
>
> #(define (partial-sums lst)
> (cdr (reverse! (fold
> (lambda (new previous)
>   (cons (+ new (car previous))
> previous))
> (list 0)
> lst
>
> #(define (symbol-filler::print grob)
> (let* ((widths (ly:grob-property grob 'widths))
>(symbols (ly:grob-property grob 'symbols))
>(orig (ly:grob-original grob))
>(proto-siblings (ly:spanner-broken-into orig))
>(siblings (if (null? proto-siblings)
>  (list grob)
>  proto-siblings))
>(sib-exts-to-fill
> (map
>  (lambda (sib)
>(define (on-dir sym dir)
>  (let* ((details (ly:grob-property sib sym))
> (x (assoc-get 'X details))
> (pding (assoc-get 'padding details)))
>(+ x (* -1 dir pding
>(cons (on-dir 'left-bound-info LEFT)
>  (on-dir 'right-bound-info RIGHT)))
>  siblings))
>(sib-widths (map interval-length sib-exts-to-fill))
>(sib-changes (partial-sums sib-widths))
>(total-spanner-width (apply + sib-widths))
>(total-sym-width (apply + widths))
>(normalized-syms (map (lambda (x)
> (* x (/ total-spanner-width
> total-sym-width)))
>   widths))
>(sym-changes (partial-sums normalized-syms))
>(sib-stil empty-stencil)
>(len-so-far 0)
>(retval #f))
>   ;; Let's do an exception.  This is easier written in imperative
> style.
>   (while (and (pair? sib-changes)
>   (pair? sym-changes))
> (let* ((sib (car siblings))
>(next-sym-maybe (car symbols))
>(next-stil-maybe (grob-interpret-markup sib next-sym-maybe))
>(len (interval-length (ly:stencil-extent next-stil-maybe
> X)))
>(new-len-so-far (+ len len-so-far)))
>   (cond
>((> new-len-so-far (car sib-changes))
> ;; Used full length of this broken piece.  Set
> ;; its stencil and start using the next.
> (let* ((tr (- (interval-start (car sib-exts-to-fill))
>   (ly:grob-relative-coordinate sib
> (ly:grob-system sib)
>X)))
>(tr-stil (ly:stencil-translate-axis sib-stil tr X)))
>   (if (eq? grob (car siblings))
>   (set! retval tr-stil)
>   (ly:grob-set-property! (car siblings)
>  'stencil
>  

Re: Unwanted font ligature

2022-04-15 Thread Werner LEMBERG

> I am trying to write the dynamic "sfffz".  But when I write
> \markup\dynamic"sfffz" the first sf is made a ligature, then the
> last two are made another ligature - the difference in spacing of
> the f's is ugly, as in the attached image - is there anything I can
> do about it?

A quick would be to insert U+200B, ZERO WIDTH SPACE (ZWSP) between the
letters to break up the ligatures.  However, I don't get this with the
current development version, see attached image for the code below.


Werner


==


\markup \dynamic "sfffz"

sfffz = #(make-dynamic-script "sfffz")

{ c''\sfffz }


Re: Unwanted font ligature

2022-04-15 Thread David Kastrup
Jean Abou Samra  writes:

> Le 15/04/2022 à 22:01, Paul Hodges a écrit :
>> I am trying to write the dynamic "sfffz".  But when I write
>> \markup\dynamic"sfffz" the first sf is made a ligature, then the
>> last two are made another ligature - the difference in spacing of
>> the f's is ugly, as in the attached image - is there anything I can
>> do about it?
>>
>> Paul
>
>
>
> \markup \concat { \dynamic s \dynamic f \dynamic f \dynamic f \dynamic z }
>
> ?

Easier to write as

\markup \concat \dynamic { s f f f z }

and should be perfectly equivalent.

> See
> http://lilypond.org/doc/v2.23/Documentation/notation/formatting-text.html
>
> Best,
> Jean
>
>
>

-- 
David Kastrup



Re: Unwanted font ligature

2022-04-15 Thread Jean Abou Samra

Le 15/04/2022 à 22:01, Paul Hodges a écrit :
I am trying to write the dynamic "sfffz".  But when I write 
\markup\dynamic"sfffz" the first sf is made a ligature, then the last 
two are made another ligature - the difference in spacing of the f's 
is ugly, as in the attached image - is there anything I can do about it?


Paul




\markup \concat { \dynamic s \dynamic f \dynamic f \dynamic f \dynamic z }

?

See 
http://lilypond.org/doc/v2.23/Documentation/notation/formatting-text.html


Best,
Jean




Unwanted font ligature

2022-04-15 Thread Paul Hodges
I am trying to write the dynamic "sfffz".  But when I write 
\markup\dynamic"sfffz" the first sf is made a ligature, then the last two are 
made another ligature - the difference in spacing of the f's is ugly, as in the 
attached image - is there anything I can do about it?


Paul

Re: Custom Spanner with variable length sections

2022-04-15 Thread Jean Abou Samra

Le 15/04/2022 à 16:35, Dimitris Marinakis a écrit :

Thank you so much Jean. That looks amazing for a first try. Great work!

Sorry it took me a while to test it.



Less than a day? I didn't find that long :-)


Upon testing I found out that it only works when there are line breaks 
(not on a single system).




Right, I intended to add this code, but forgot it along the way.



Also it would be useful to have control over the broken.left/right 
paddings. This is an issue especially if the spanner is used above the 
stave (clef collisions).


Is it too hard to an option to align the broken sections on the first 
and last notes in the system instead of the system edges? The current 
behaviour isn't wrong. It's just not suitable for all use cases.




See the second attempt below. This SymbolFiller implements a subset
of the horizontal-line-spanner-interface. You can override padding and
end-on-note in bound-details.

I hope you don't mind that this now requires a development version.

Best,
Jean



\version "2.23.7"

#(define (define-grob! grob-name grob-entry)
   (set! all-grob-descriptions
 (cons ((@@ (lily) completize-grob-entry)
    (cons grob-name grob-entry))
   all-grob-descriptions)))

#(define (partial-sums lst)
   (cdr (reverse! (fold
   (lambda (new previous)
 (cons (+ new (car previous))
   previous))
   (list 0)
   lst

#(define (symbol-filler::print grob)
   (let* ((widths (ly:grob-property grob 'widths))
  (symbols (ly:grob-property grob 'symbols))
  (orig (ly:grob-original grob))
  (proto-siblings (ly:spanner-broken-into orig))
  (siblings (if (null? proto-siblings)
    (list grob)
    proto-siblings))
  (sib-exts-to-fill
   (map
    (lambda (sib)
  (define (on-dir sym dir)
    (let* ((details (ly:grob-property sib sym))
   (x (assoc-get 'X details))
   (pding (assoc-get 'padding details)))
  (+ x (* -1 dir pding
  (cons (on-dir 'left-bound-info LEFT)
    (on-dir 'right-bound-info RIGHT)))
    siblings))
  (sib-widths (map interval-length sib-exts-to-fill))
  (sib-changes (partial-sums sib-widths))
  (total-spanner-width (apply + sib-widths))
  (total-sym-width (apply + widths))
  (normalized-syms (map (lambda (x)
   (* x (/ total-spanner-width 
total-sym-width)))

 widths))
  (sym-changes (partial-sums normalized-syms))
  (sib-stil empty-stencil)
  (len-so-far 0)
  (retval #f))
 ;; Let's do an exception.  This is easier written in imperative style.
 (while (and (pair? sib-changes)
 (pair? sym-changes))
   (let* ((sib (car siblings))
  (next-sym-maybe (car symbols))
  (next-stil-maybe (grob-interpret-markup sib next-sym-maybe))
  (len (interval-length (ly:stencil-extent next-stil-maybe X)))
  (new-len-so-far (+ len len-so-far)))
 (cond
  ((> new-len-so-far (car sib-changes))
   ;; Used full length of this broken piece.  Set
   ;; its stencil and start using the next.
   (let* ((tr (- (interval-start (car sib-exts-to-fill))
 (ly:grob-relative-coordinate sib
(ly:grob-system sib)
  X)))
  (tr-stil (ly:stencil-translate-axis sib-stil tr X)))
 (if (eq? grob (car siblings))
 (set! retval tr-stil)
 (ly:grob-set-property! (car siblings)
    'stencil
    tr-stil)))
   (set! sib-changes (cdr sib-changes))
   (set! siblings (cdr siblings))
   (set! sib-stil empty-stencil)
   (set! sib-exts-to-fill (cdr sib-exts-to-fill)))
  ((> new-len-so-far (car sym-changes))
   ;; Done with this symbol, start using the next.
   (set! sym-changes (cdr sym-changes))
   (set! symbols (cdr symbols)))
  (else
   (set! sib-stil (ly:stencil-stack sib-stil X RIGHT 
next-stil-maybe 0))

   (set! len-so-far new-len-so-far)
 retval))

#(define-grob! 'SymbolFiller
   `((bound-details . ((left . ((padding . 0)))
   (right . ((padding . 0)
 (direction . ,DOWN)
 (left-bound-info . ,ly:horizontal-line-spanner::calc-left-bound-info)
 (normalized-endpoints . ,ly:spanner::calc-normalized-endpoints)
 (right-bound-info . 
,ly:horizontal-line-spanner::calc-right-bound-info)

 (stencil . ,symbol-filler::print)
 (staff-padding . 3.0)
 (symbols . ,(grob::calc-property-by-copy 'symbols))
 (widths . 

Re: DurationLine avoiding RehearsalMarks

2022-04-15 Thread Jean Abou Samra

Le 15/04/2022 à 20:03, Thomas Morley a écrit :

My concern at first glance was for the right side: Only the last
broken spanner should use right, all the others right-broken.




Yup, that's the meaning of the C++ code

  Lily::Variable checker = ((dir == LEFT)
    ? Lily::unbroken_or_first_broken_spanner_p
    : Lily::unbroken_or_last_broken_spanner_p);
  if (!from_scm (checker (smob)))
    {
  ...
    }

which in Scheme would be spelt

  (let ((checker (if (eqv? dir LEFT)
         unbroken-or-first-broken-spanner?
         unbroken-or-last-broken-spanner?)))
    (if (not (checker grob))
        (begin
      ...)))



Though, I've tested it now, doing a full regtest-comparison with your
patch on top of my own (patch attached).
All works nicely, afaict.




Thanks. I'll review this on GitLab.



Now, how should we upload our work?
I.e. in which sequence and who does it?
I'd volunteer to upload both, although I'm not sure how gitlab deals
with patches from different authors in one MR (or doing it
separately?)



Mine is a minor fix supporting yours which is the main part, so
I'd suggest that you upload them both. As long as you push on
a branch on the shared repository (not a GitLab fork, as I usually
do), I will be able to address review comments on that minor
preliminary patch, should they arise.

Cheers,
Jean




Re: DurationLine avoiding RehearsalMarks

2022-04-15 Thread Thomas Morley
Am Fr., 15. Apr. 2022 um 13:27 Uhr schrieb Jean Abou Samra :
>
>
>
> Le 15/04/2022 à 13:17, Thomas Morley a écrit :
> > Am Fr., 15. Apr. 2022 um 12:52 Uhr schrieb Jean Abou Samra 
> > :
> >>
> >>
> >> Le 15/04/2022 à 11:45, Thomas Morley a écrit :
> >>> Am Fr., 15. Apr. 2022 um 10:39 Uhr schrieb Jean Abou Samra 
> >>> :
> 
>  Le 15/04/2022 à 10:13, Thomas Morley a écrit :
> > Am Mi., 13. Apr. 2022 um 17:57 Uhr schrieb Jean Abou Samra 
> > :
> >> Le 13/04/2022 à 17:03, Thomas Morley a écrit :
> >>> Am Di., 12. Apr. 2022 um 11:54 Uhr schrieb Jean Abou Samra 
> >>> :
>  Le 12/04/2022 à 11:16, Thomas Morley a écrit :
> >>> [...]
> > In many details DurationLine was tailored after Glissando and
> > Glissando _is_ effected by the breathing sign.
> >>> [...]
> >>>
>  Well, if the goal is to have DurationLine similar to Glissando,
>  how about reusing line-spanner-interface code? I haven't reviewed
>  the code very thoroughly, but I assumed there was a difference
>  warranting a different code path. If you put
>  ly:line-spanner::calc-{left,right}-bound-info in
>  DurationLine.{left,righ}-bound-info, that gives you X values for free
>  in the bound info properties. Would that solve the problem?
> >>> If I go for ly:line-spanner::calc-{left,right}-bound-info then
> >>>
> >>> \layout {
> >>>\context {
> >>>  \Voice
> >>>  \consists Duration_line_engraver
> >>>}
> >>> }
> >>>
> >>> { b1\- }
> >>>
> >>> errors with
> >>> "programming error: extremal broken spanner's bound has no 
> >>> parent
> >>> vertical axis group"
> >>> More complex examples may add:
> >>> "programming error: bound item has no parent vertical axis 
> >>> group"
> >>> Both coming from `ly:line-spanner::calc-right-bound-info' based upon
> >>> `Line_spanner::calc_bound_info' in /lily/line-spanner.cc
> >>>
> >>> As a mere user I'd say: "Nice error-message, but why should I 
> >>> care...?"
> >>>
> >>> As a programmer, I doubt the example above can be made working with
> >>> ly:line-spanner::calc-right-bound-info.
> >>> At least, I don't know how.
> >> Oh, I'm sorry, I missed that detail of my own code. A DurationLine will
> >> always be horizontal, thus you can and should use
> >> ly:horizontal-line-spanner::calc-{left,right}-bound-info (with 
> >> 'horizontal'
> >> in the name).  The difference is that the functions without 
> >> 'horizontal'
> >> try to compute vertical positions. This falls apart here, for 
> >> understandable
> >> reasons: the right bound of your DurationLine is a 
> >> NonMusicalPaperColumn,
> >> so how would one tell where the line should end vertically?
> > Using ly:horizontal-line-spanner::calc-{left,right}-bound-info makes
> > for huge simplifications.
> > Alas, it introduces a minor and reintroduces a major problem.
> >
> > The minor: the X-value depends now on attach-dir. For the start of the
> > DurationLine this is ofcourse RIGHT. But if starting at a skip,
> > left-bound is PaperColumn there we would want LEFT. Can be fixed by
> > accurate conditions. Count it as done.
> >
> > The major: `ly:horizontal-line-spanner::calc-right-bound-info' and
> > `unbroken-or-last-broken-spanner?' (and friends) don't agree what's
> > the last part of the spanner.
> > To illustrate:
> >
> > \version "2.23.7"
> >
> > \layout {
> >  \context {
> >\Voice
> >\consists "Duration_line_engraver"
> >  }
> > }
> >
> > {
> > \override DurationLine.bound-details.right.foo =
> >   "I am last part (bound-details)"
> > \override DurationLine.bound-details.right-broken.foo =
> >   "I am not last part (bound-details)"
> >
> > \override DurationLine.after-line-breaking =
> > #(lambda (grob)
> >   (pretty-print
> > (if (unbroken-or-last-broken-spanner? grob)
> > "I am last part (unbroken-or-last-broken-spanner?)"
> > "I am not last part (unbroken-or-last-broken-spanner?)"))
> >   (pretty-print
> > (assoc-get 'foo 
> > (ly:horizontal-line-spanner::calc-right-bound-info grob
> >
> > b1\-
> > }
> >
> > =>
> > "I am last part (unbroken-or-last-broken-spanner?)"
> > "I am not last part (bound-details)"
> >
> > The problem occurs if we have a broken DurationLine with end-items
> > running to the very end of the score.
> > To fix it one would again need something like:
> >
> > {
> >  \override DurationLine.bound-details =
> >  #(grob-transformer 'bound-details
> >(lambda (grob orig)
> > (if 

Re: Custom Spanner with variable length sections

2022-04-15 Thread Dimitris Marinakis
Thank you so much Jean. That looks amazing for a first try. Great work!

Sorry it took me a while to test it.

Upon testing I found out that it only works when there are line breaks (not
on a single system).

Also it would be useful to have control over the broken.left/right
paddings. This is an issue especially if the spanner is used above the
stave (clef collisions).

Is it too hard to an option to align the broken sections on the first and
last notes in the system instead of the system edges? The current behaviour
isn't wrong. It's just not suitable for all use cases.

Best,
Dimitris

On Thu, Apr 14, 2022 at 7:44 PM Jean Abou Samra  wrote:

> Le 14/04/2022 à 16:09, Kieren MacMillan a écrit :
> > Hi Dimitris,
> >
> >> I need a custom spanner that has x sections with different symbols.
> This is going to be tricky so any help is appreciated.
> > https://github.com/davidnalesnik/lilypond-text-spanner-inner-texts
>
>
> Ok, I'm not sure if this solves the problem fully, so I'll post what I had
> started writing anyway:
>
>
> \version "2.22.2"
>
> #(define (define-grob! grob-name grob-entry)
> (set! all-grob-descriptions
>   (cons ((@@ (lily) completize-grob-entry)
>  (cons grob-name grob-entry))
> all-grob-descriptions)))
>
> #(define (partial-sums lst)
> (cdr (reverse! (fold
> (lambda (new previous)
>   (cons (+ new (car previous))
> previous))
> (list 0)
> lst
>
> #(define (symbol-filler::print grob)
> (let* ((widths (ly:grob-property grob 'widths))
>(symbols (ly:grob-property grob 'symbols))
>(orig (ly:grob-original grob))
>(siblings (ly:spanner-broken-into orig))
>(sib-widths
> (map (lambda (sib)
>(let ((sys (ly:grob-system sib))
>  (left (ly:spanner-bound sib LEFT))
>  (right (ly:spanner-bound sib RIGHT)))
>  (- (ly:grob-relative-coordinate right sys X)
> (ly:grob-relative-coordinate left sys X
>  siblings))
>(sib-changes (partial-sums sib-widths))
>(total-spanner-width (apply + sib-widths))
>(total-sym-width (apply + widths))
>(normalized-syms (map (lambda (x)
> (* x (/ total-spanner-width
> total-sym-width)))
>   widths))
>(sym-changes (partial-sums normalized-syms))
>(sib-stil empty-stencil)
>(len-so-far 0)
>(retval #f))
>   ;; Let's do an exception.  This is easier written in imperative
> style.
>   (while (and (pair? sib-changes)
>   (pair? sym-changes))
> (let* ((sib (car siblings))
>(next-sym-maybe (car symbols))
>(next-stil-maybe (grob-interpret-markup sib next-sym-maybe))
>(len (interval-length (ly:stencil-extent next-stil-maybe
> X)))
>(new-len-so-far (+ len len-so-far)))
>   (cond
>((> new-len-so-far (car sib-changes))
> ;; Used full length of this broken piece.  Set
> ;; its stencil and start using the next.
> (if (eq? grob (car siblings))
>(set! retval sib-stil)
>(ly:grob-set-property! (car siblings)
>   'stencil
>   sib-stil))
> (set! sib-changes (cdr sib-changes))
> (set! siblings (cdr siblings))
> (set! sib-stil empty-stencil))
>((> new-len-so-far (car sym-changes))
> ;; Done with this symbol, start using the next.
> (set! sym-changes (cdr sym-changes))
> (set! symbols (cdr symbols)))
>(else
> (set! sib-stil (ly:stencil-stack sib-stil X RIGHT
> next-stil-maybe 0))
> (set! len-so-far new-len-so-far)
>   retval))
>
> #(define-grob! 'SymbolFiller
> `((direction . ,DOWN)
>   (normalized-endpoints . ,ly:spanner::calc-normalized-endpoints)
>   (stencil . ,symbol-filler::print)
>   (staff-padding . 3.0)
>   (symbols . ,(grob::calc-property-by-copy 'symbols))
>   (widths . ,(grob::calc-property-by-copy 'widths))
>   (Y-offset . ,ly:side-position-interface::y-aligned-side)
>   (meta . ((class . Spanner)
>(interfaces . (side-position-interface))
>
> #(define (Symbol_filler_engraver context)
> (let ((filler #f)
>   (ev #f))
>   (make-engraver
>(listeners
> ((symbol-filler-event engraver event)
>  (set! ev event)))
>((process-music engraver)
> (if ev
> (let ((d (ly:event-property ev 'span-direction)))
>   (if (eqv? d LEFT)
>   (begin
>(set! filler 

Re: Off-topic: What do you guys think of the upside-down music?

2022-04-15 Thread ole
Very cool!
It's mirrored around the Db/C# axis, right?
How to tweak your code to mirror around other notes (Sorry, although I knew a 
bit Lisp, Scheme code is all Greek to me)?

> Am 15.04.2022 um 13:55 schrieb Kira Garvie :
> 
> When I was a kid I would regularly turn piano scores upside down and try to 
> sight read through then, so I think this is fun!
> 
> On Thu, Apr 14, 2022 at 6:04 PM Kenneth Wolcott  
> wrote:
> Thanks, Jean!  This is cool!  Not that I would do anything with it,
> but it sure is nice to know that there seems to be no limit to what
> Lilypond can do :-)
> 
> On Thu, Apr 14, 2022 at 1:18 PM Jean Abou Samra  wrote:
> >
> >
> >
> > Le 14/04/2022 à 21:58, Kenneth Wolcott a écrit :
> > > Hi;
> > >
> > >Off-topic: What do you guys think of the upside-down music?
> > >
> > > On youtube:
> > >
> > > https://www.youtube.com/channel/UCrLBkLxyE7T1cyv_4ykGTrg
> > >
> > > Upside-down Scores
> > >
> > > Example:
> > > Für Elise Upside-down (new version, with Score)
> > > https://www.youtube.com/watch?v=q2vsAua8FxM
> > >
> > > How is this done?  Can this be done with Lilypond?  Just curious..
> > >
> > > Amusing...
> > >
> > > Ken Wolcott
> >
> > \version "2.22.2"
> >
> > upsideDown =
> > #(define-music-function (music) (ly:music?)
> > (for-some-music
> >  (lambda (m)
> >(let ((p (ly:music-property m 'pitch #f)))
> >  (if p
> >  (let ((n (ly:pitch-transpose #{ cis' #} (ly:pitch-diff #{
> > des' #} p
> >(ly:music-set-property! m 'pitch n
> >#f)
> >  music)
> > music)
> >
> > RH = \relative {
> >\time 3/8
> >\partial 8
> >e''16 dis
> >e dis e b d c
> >a8 r16 c, e a
> >b8 r16 e, gis b
> >c8 r16
> > }
> >
> > LH = \relative {
> >\time 3/8
> >\partial 8
> >s8
> >s4.
> >a,16 e' a r r8
> >e,16 e' gis r r8
> >a,16[ e' a]
> > }
> >
> >
> > \score {
> >\header {
> >  piece = "Lettre à Élise"
> >}
> ><<
> >  \new Staff \RH
> >  \new Staff { \clef bass \LH }
> >>>
> > }
> >
> > \score {
> >\header {
> >  piece = \markup \scale #'(1 . -1) "Lettre à Élise"
> >}
> >\upsideDown <<
> >  \new Staff { \key bes \major \LH }
> >  \new Staff { \clef bass \key bes \major \RH }
> >>>
> > }
> >
> >
> >
> >
> 




Re: Off-topic: What do you guys think of the upside-down music?

2022-04-15 Thread TamuraJun
There are some music intended to be played with a score upside down, including

1. "Canon triplex a 6” BWV 1076 or BWV 1087/13 by J. S. Bach
https://imslp.org/wiki/Canon_in_G_major,_BWV_1076_(Bach,_Johann_Sebastian) 

appears on the only authentic portrait of J. S. Bach painted by Elias Gottlob 
Haussmann.
https://commons.wikimedia.org/wiki/File:Johann_Sebastian_Bach.jpg 


2. Anonymous "4 Spiegelkanons”
https://imslp.org/wiki/4_Spiegelkanons%2C_K.Anh.10.16_(Mozart%2C_Wolfgang_Amadeus)
 


Jun
https://imslp.org/wiki/User:Jun_T 

> 2022/04/15 20:55、Kira Garvie のメール:
> 
> When I was a kid I would regularly turn piano scores upside down and try to 
> sight read through then, so I think this is fun!
> 
> On Thu, Apr 14, 2022 at 6:04 PM Kenneth Wolcott  > wrote:
> Thanks, Jean!  This is cool!  Not that I would do anything with it,
> but it sure is nice to know that there seems to be no limit to what
> Lilypond can do :-)
> 
> On Thu, Apr 14, 2022 at 1:18 PM Jean Abou Samra  > wrote:
> >
> >
> >
> > Le 14/04/2022 à 21:58, Kenneth Wolcott a écrit :
> > > Hi;
> > >
> > >Off-topic: What do you guys think of the upside-down music?
> > >
> > > On youtube:
> > >
> > > https://www.youtube.com/channel/UCrLBkLxyE7T1cyv_4ykGTrg 
> > > 
> > >
> > > Upside-down Scores
> > >
> > > Example:
> > > Für Elise Upside-down (new version, with Score)
> > > https://www.youtube.com/watch?v=q2vsAua8FxM 
> > > 
> > >
> > > How is this done?  Can this be done with Lilypond?  Just curious..
> > >
> > > Amusing...
> > >
> > > Ken Wolcott
> >
> > \version "2.22.2"
> >
> > upsideDown =
> > #(define-music-function (music) (ly:music?)
> > (for-some-music
> >  (lambda (m)
> >(let ((p (ly:music-property m 'pitch #f)))
> >  (if p
> >  (let ((n (ly:pitch-transpose #{ cis' #} (ly:pitch-diff #{
> > des' #} p
> >(ly:music-set-property! m 'pitch n
> >#f)
> >  music)
> > music)
> >
> > RH = \relative {
> >\time 3/8
> >\partial 8
> >e''16 dis
> >e dis e b d c
> >a8 r16 c, e a
> >b8 r16 e, gis b
> >c8 r16
> > }
> >
> > LH = \relative {
> >\time 3/8
> >\partial 8
> >s8
> >s4.
> >a,16 e' a r r8
> >e,16 e' gis r r8
> >a,16[ e' a]
> > }
> >
> >
> > \score {
> >\header {
> >  piece = "Lettre à Élise"
> >}
> ><<
> >  \new Staff \RH
> >  \new Staff { \clef bass \LH }
> >>>
> > }
> >
> > \score {
> >\header {
> >  piece = \markup \scale #'(1 . -1) "Lettre à Élise"
> >}
> >\upsideDown <<
> >  \new Staff { \key bes \major \LH }
> >  \new Staff { \clef bass \key bes \major \RH }
> >>>
> > }
> >
> >
> >
> >
> 



Re: Tags for contexts without duration

2022-04-15 Thread Kieren MacMillan
Hi Dimitris,

If you get into more numerous and complex tweaks, I highly recommend using the 
edition-engraver — keeping presentation tweaks (e.g., moving a RehearsalMark) 
out of the note code is my primary use-case for the EE.

Hope that helps!
Kieren.


Re: Off-topic: What do you guys think of the upside-down music?

2022-04-15 Thread Kira Garvie
When I was a kid I would regularly turn piano scores upside down and try to
sight read through then, so I think this is fun!

On Thu, Apr 14, 2022 at 6:04 PM Kenneth Wolcott 
wrote:

> Thanks, Jean!  This is cool!  Not that I would do anything with it,
> but it sure is nice to know that there seems to be no limit to what
> Lilypond can do :-)
>
> On Thu, Apr 14, 2022 at 1:18 PM Jean Abou Samra 
> wrote:
> >
> >
> >
> > Le 14/04/2022 à 21:58, Kenneth Wolcott a écrit :
> > > Hi;
> > >
> > >Off-topic: What do you guys think of the upside-down music?
> > >
> > > On youtube:
> > >
> > > https://www.youtube.com/channel/UCrLBkLxyE7T1cyv_4ykGTrg
> > >
> > > Upside-down Scores
> > >
> > > Example:
> > > Für Elise Upside-down (new version, with Score)
> > > https://www.youtube.com/watch?v=q2vsAua8FxM
> > >
> > > How is this done?  Can this be done with Lilypond?  Just curious..
> > >
> > > Amusing...
> > >
> > > Ken Wolcott
> >
> > \version "2.22.2"
> >
> > upsideDown =
> > #(define-music-function (music) (ly:music?)
> > (for-some-music
> >  (lambda (m)
> >(let ((p (ly:music-property m 'pitch #f)))
> >  (if p
> >  (let ((n (ly:pitch-transpose #{ cis' #} (ly:pitch-diff #{
> > des' #} p
> >(ly:music-set-property! m 'pitch n
> >#f)
> >  music)
> > music)
> >
> > RH = \relative {
> >\time 3/8
> >\partial 8
> >e''16 dis
> >e dis e b d c
> >a8 r16 c, e a
> >b8 r16 e, gis b
> >c8 r16
> > }
> >
> > LH = \relative {
> >\time 3/8
> >\partial 8
> >s8
> >s4.
> >a,16 e' a r r8
> >e,16 e' gis r r8
> >a,16[ e' a]
> > }
> >
> >
> > \score {
> >\header {
> >  piece = "Lettre à Élise"
> >}
> ><<
> >  \new Staff \RH
> >  \new Staff { \clef bass \LH }
> >>>
> > }
> >
> > \score {
> >\header {
> >  piece = \markup \scale #'(1 . -1) "Lettre à Élise"
> >}
> >\upsideDown <<
> >  \new Staff { \key bes \major \LH }
> >  \new Staff { \clef bass \key bes \major \RH }
> >>>
> > }
> >
> >
> >
> >
>
>


Re: DurationLine avoiding RehearsalMarks

2022-04-15 Thread Jean Abou Samra



Le 15/04/2022 à 13:17, Thomas Morley a écrit :

Am Fr., 15. Apr. 2022 um 12:52 Uhr schrieb Jean Abou Samra :



Le 15/04/2022 à 11:45, Thomas Morley a écrit :

Am Fr., 15. Apr. 2022 um 10:39 Uhr schrieb Jean Abou Samra :


Le 15/04/2022 à 10:13, Thomas Morley a écrit :

Am Mi., 13. Apr. 2022 um 17:57 Uhr schrieb Jean Abou Samra :

Le 13/04/2022 à 17:03, Thomas Morley a écrit :

Am Di., 12. Apr. 2022 um 11:54 Uhr schrieb Jean Abou Samra :

Le 12/04/2022 à 11:16, Thomas Morley a écrit :

[...]

In many details DurationLine was tailored after Glissando and
Glissando _is_ effected by the breathing sign.

[...]


Well, if the goal is to have DurationLine similar to Glissando,
how about reusing line-spanner-interface code? I haven't reviewed
the code very thoroughly, but I assumed there was a difference
warranting a different code path. If you put
ly:line-spanner::calc-{left,right}-bound-info in
DurationLine.{left,righ}-bound-info, that gives you X values for free
in the bound info properties. Would that solve the problem?

If I go for ly:line-spanner::calc-{left,right}-bound-info then

\layout {
   \context {
 \Voice
 \consists Duration_line_engraver
   }
}

{ b1\- }

errors with
"programming error: extremal broken spanner's bound has no parent
vertical axis group"
More complex examples may add:
"programming error: bound item has no parent vertical axis group"
Both coming from `ly:line-spanner::calc-right-bound-info' based upon
`Line_spanner::calc_bound_info' in /lily/line-spanner.cc

As a mere user I'd say: "Nice error-message, but why should I care...?"

As a programmer, I doubt the example above can be made working with
ly:line-spanner::calc-right-bound-info.
At least, I don't know how.

Oh, I'm sorry, I missed that detail of my own code. A DurationLine will
always be horizontal, thus you can and should use
ly:horizontal-line-spanner::calc-{left,right}-bound-info (with 'horizontal'
in the name).  The difference is that the functions without 'horizontal'
try to compute vertical positions. This falls apart here, for understandable
reasons: the right bound of your DurationLine is a NonMusicalPaperColumn,
so how would one tell where the line should end vertically?

Using ly:horizontal-line-spanner::calc-{left,right}-bound-info makes
for huge simplifications.
Alas, it introduces a minor and reintroduces a major problem.

The minor: the X-value depends now on attach-dir. For the start of the
DurationLine this is ofcourse RIGHT. But if starting at a skip,
left-bound is PaperColumn there we would want LEFT. Can be fixed by
accurate conditions. Count it as done.

The major: `ly:horizontal-line-spanner::calc-right-bound-info' and
`unbroken-or-last-broken-spanner?' (and friends) don't agree what's
the last part of the spanner.
To illustrate:

\version "2.23.7"

\layout {
 \context {
   \Voice
   \consists "Duration_line_engraver"
 }
}

{
\override DurationLine.bound-details.right.foo =
  "I am last part (bound-details)"
\override DurationLine.bound-details.right-broken.foo =
  "I am not last part (bound-details)"

\override DurationLine.after-line-breaking =
#(lambda (grob)
  (pretty-print
(if (unbroken-or-last-broken-spanner? grob)
"I am last part (unbroken-or-last-broken-spanner?)"
"I am not last part (unbroken-or-last-broken-spanner?)"))
  (pretty-print
(assoc-get 'foo (ly:horizontal-line-spanner::calc-right-bound-info 
grob

b1\-
}

=>
"I am last part (unbroken-or-last-broken-spanner?)"
"I am not last part (bound-details)"

The problem occurs if we have a broken DurationLine with end-items
running to the very end of the score.
To fix it one would again need something like:

{
 \override DurationLine.bound-details =
 #(grob-transformer 'bound-details
   (lambda (grob orig)
(if (end-broken-spanner? grob)
(cons
  (cons 'right-broken
(cons '(end-style . arrow) (assoc-get 'right-broken orig)))
  orig)
orig)))
 b1\-
 \break
 s1
 \break
 s1
 \bar "|."
}

Or like \lastEndStyle which you cleared with

commit 46671d13257f6ad68d1778a1cc850e59116c856a
Author: Jean Abou Samra 
Date:   Wed Dec 29 00:16:46 2021 +0100

   Fix broken spanner functions

   They were broken (pun intended) on spanners of which one bound is a
   non-musical column at a system boundary.  For example,
   unbroken-or-last-broken-spanner? would return false on a spanner
   running to the NonMusicalPaperColumn at the end of a score.  This
   fixes the known issue with duration lines running to the end of the
   piece, and will be needed in a refactoring of spanner-placement
   treatment for balloon-interface.

   While at it, document these functions.

This is unfortunate. Any chance making
`ly:horizontal-line-spanner::calc-right-bound-info' and friends
identify the last 

Re: DurationLine avoiding RehearsalMarks

2022-04-15 Thread Thomas Morley
Am Fr., 15. Apr. 2022 um 12:52 Uhr schrieb Jean Abou Samra :
>
>
>
> Le 15/04/2022 à 11:45, Thomas Morley a écrit :
> > Am Fr., 15. Apr. 2022 um 10:39 Uhr schrieb Jean Abou Samra 
> > :
> >>
> >>
> >> Le 15/04/2022 à 10:13, Thomas Morley a écrit :
> >>> Am Mi., 13. Apr. 2022 um 17:57 Uhr schrieb Jean Abou Samra 
> >>> :
>  Le 13/04/2022 à 17:03, Thomas Morley a écrit :
> > Am Di., 12. Apr. 2022 um 11:54 Uhr schrieb Jean Abou Samra 
> > :
> >> Le 12/04/2022 à 11:16, Thomas Morley a écrit :
> > [...]
> >>> In many details DurationLine was tailored after Glissando and
> >>> Glissando _is_ effected by the breathing sign.
> > [...]
> >
> >> Well, if the goal is to have DurationLine similar to Glissando,
> >> how about reusing line-spanner-interface code? I haven't reviewed
> >> the code very thoroughly, but I assumed there was a difference
> >> warranting a different code path. If you put
> >> ly:line-spanner::calc-{left,right}-bound-info in
> >> DurationLine.{left,righ}-bound-info, that gives you X values for free
> >> in the bound info properties. Would that solve the problem?
> > If I go for ly:line-spanner::calc-{left,right}-bound-info then
> >
> > \layout {
> >   \context {
> > \Voice
> > \consists Duration_line_engraver
> >   }
> > }
> >
> > { b1\- }
> >
> > errors with
> >"programming error: extremal broken spanner's bound has no parent
> > vertical axis group"
> > More complex examples may add:
> >"programming error: bound item has no parent vertical axis group"
> > Both coming from `ly:line-spanner::calc-right-bound-info' based upon
> > `Line_spanner::calc_bound_info' in /lily/line-spanner.cc
> >
> > As a mere user I'd say: "Nice error-message, but why should I care...?"
> >
> > As a programmer, I doubt the example above can be made working with
> > ly:line-spanner::calc-right-bound-info.
> > At least, I don't know how.
>  Oh, I'm sorry, I missed that detail of my own code. A DurationLine will
>  always be horizontal, thus you can and should use
>  ly:horizontal-line-spanner::calc-{left,right}-bound-info (with 
>  'horizontal'
>  in the name).  The difference is that the functions without 'horizontal'
>  try to compute vertical positions. This falls apart here, for 
>  understandable
>  reasons: the right bound of your DurationLine is a NonMusicalPaperColumn,
>  so how would one tell where the line should end vertically?
> >>> Using ly:horizontal-line-spanner::calc-{left,right}-bound-info makes
> >>> for huge simplifications.
> >>> Alas, it introduces a minor and reintroduces a major problem.
> >>>
> >>> The minor: the X-value depends now on attach-dir. For the start of the
> >>> DurationLine this is ofcourse RIGHT. But if starting at a skip,
> >>> left-bound is PaperColumn there we would want LEFT. Can be fixed by
> >>> accurate conditions. Count it as done.
> >>>
> >>> The major: `ly:horizontal-line-spanner::calc-right-bound-info' and
> >>> `unbroken-or-last-broken-spanner?' (and friends) don't agree what's
> >>> the last part of the spanner.
> >>> To illustrate:
> >>>
> >>> \version "2.23.7"
> >>>
> >>> \layout {
> >>> \context {
> >>>   \Voice
> >>>   \consists "Duration_line_engraver"
> >>> }
> >>> }
> >>>
> >>> {
> >>>\override DurationLine.bound-details.right.foo =
> >>>  "I am last part (bound-details)"
> >>>\override DurationLine.bound-details.right-broken.foo =
> >>>  "I am not last part (bound-details)"
> >>>
> >>>\override DurationLine.after-line-breaking =
> >>>#(lambda (grob)
> >>>  (pretty-print
> >>>(if (unbroken-or-last-broken-spanner? grob)
> >>>"I am last part (unbroken-or-last-broken-spanner?)"
> >>>"I am not last part (unbroken-or-last-broken-spanner?)"))
> >>>  (pretty-print
> >>>(assoc-get 'foo (ly:horizontal-line-spanner::calc-right-bound-info 
> >>> grob
> >>>
> >>>b1\-
> >>> }
> >>>
> >>> =>
> >>> "I am last part (unbroken-or-last-broken-spanner?)"
> >>> "I am not last part (bound-details)"
> >>>
> >>> The problem occurs if we have a broken DurationLine with end-items
> >>> running to the very end of the score.
> >>> To fix it one would again need something like:
> >>>
> >>> {
> >>> \override DurationLine.bound-details =
> >>> #(grob-transformer 'bound-details
> >>>   (lambda (grob orig)
> >>>(if (end-broken-spanner? grob)
> >>>(cons
> >>>  (cons 'right-broken
> >>>(cons '(end-style . arrow) (assoc-get 'right-broken orig)))
> >>>  orig)
> >>>orig)))
> >>> b1\-
> >>> \break
> >>> s1
> >>> \break
> >>> s1
> >>> \bar "|."
> >>> }
> >>>
> >>> Or like \lastEndStyle which you cleared with
> >>>
> >>> commit 46671d13257f6ad68d1778a1cc850e59116c856a
> 

Re: Tags for contexts without duration

2022-04-15 Thread Valentin Petzel
Chaire Demetrios!

tags work by assigning a special tag attribute to a music event and can 
therefore be applied to any music event by the syntax \tag tag music. But in 
my opinion tags are not always the best method to achieve such things, 
especially should you ever want to have something like multiple cases 
depending on the edition. So if you want to do more complex stuff it is 
feasible to use music functions as some sort of parametrized music, somewhat 
like this:

condTweak =
#(define-music-function (cond prop value music)
   (scheme? key-list-or-symbol? scheme? ly:music?)
   (if cond
   (tweak prop value music)
   music))

global =
#(define-music-function (edition) (symbol?)
   #{
 \condTweak #(memq edition '(strings-part brass-part))
Y-offset #(assoc-ref '((strings-part . 8) (brass-part . 16)) 
edition)
 \tempo "Allegro"
 s1
   #})

v = { c''1 }

<<
  \new Devnull \global full-score
  \new Staff \v
>>

<<
  \new Devnull \global strings-part
  \new Staff \v
>>

<<
  \new Devnull \global brass-part
  \new Staff \v
>>

Cheers,
Valentin

Am Freitag, 15. April 2022, 11:09:20 CEST schrieb Dimitris Marinakis:
> Oh wow I can't believe I missed this use of tags. I was trying to use the
> bracket syntax. Thanks Jean!
> 
> On Fri, Apr 15, 2022 at 12:43 AM Jean Abou Samra  wrote:
> > Le 14/04/2022 à 22:44, Dimitris Marinakis a écrit :
> > > I often find myself in need of offsetting some tempo or rehearsal
> > > marks for certain parts but not the full score but tags won't work in
> > > this case since I can't have two marks at the same location on a
> > > single context.
> > 
> > Not sure I understand the problem?
> > 
> > \version "2.22.2"
> > 
> > mus = {
> > 
> >\tag #'part \once \override Score.RehearsalMark.X-offset = 8
> >\mark \default
> >c'
> > 
> > }
> > 
> > % Conductor
> > \removeWithTag #'part \mus
> > 
> > % Parts
> > { \mus }
> > 
> > 
> > Best,
> > Jean



signature.asc
Description: This is a digitally signed message part.


Re: DurationLine avoiding RehearsalMarks

2022-04-15 Thread Jean Abou Samra



Le 15/04/2022 à 11:45, Thomas Morley a écrit :

Am Fr., 15. Apr. 2022 um 10:39 Uhr schrieb Jean Abou Samra :



Le 15/04/2022 à 10:13, Thomas Morley a écrit :

Am Mi., 13. Apr. 2022 um 17:57 Uhr schrieb Jean Abou Samra :

Le 13/04/2022 à 17:03, Thomas Morley a écrit :

Am Di., 12. Apr. 2022 um 11:54 Uhr schrieb Jean Abou Samra :

Le 12/04/2022 à 11:16, Thomas Morley a écrit :

[...]

In many details DurationLine was tailored after Glissando and
Glissando _is_ effected by the breathing sign.

[...]


Well, if the goal is to have DurationLine similar to Glissando,
how about reusing line-spanner-interface code? I haven't reviewed
the code very thoroughly, but I assumed there was a difference
warranting a different code path. If you put
ly:line-spanner::calc-{left,right}-bound-info in
DurationLine.{left,righ}-bound-info, that gives you X values for free
in the bound info properties. Would that solve the problem?

If I go for ly:line-spanner::calc-{left,right}-bound-info then

\layout {
  \context {
\Voice
\consists Duration_line_engraver
  }
}

{ b1\- }

errors with
   "programming error: extremal broken spanner's bound has no parent
vertical axis group"
More complex examples may add:
   "programming error: bound item has no parent vertical axis group"
Both coming from `ly:line-spanner::calc-right-bound-info' based upon
`Line_spanner::calc_bound_info' in /lily/line-spanner.cc

As a mere user I'd say: "Nice error-message, but why should I care...?"

As a programmer, I doubt the example above can be made working with
ly:line-spanner::calc-right-bound-info.
At least, I don't know how.

Oh, I'm sorry, I missed that detail of my own code. A DurationLine will
always be horizontal, thus you can and should use
ly:horizontal-line-spanner::calc-{left,right}-bound-info (with 'horizontal'
in the name).  The difference is that the functions without 'horizontal'
try to compute vertical positions. This falls apart here, for understandable
reasons: the right bound of your DurationLine is a NonMusicalPaperColumn,
so how would one tell where the line should end vertically?

Using ly:horizontal-line-spanner::calc-{left,right}-bound-info makes
for huge simplifications.
Alas, it introduces a minor and reintroduces a major problem.

The minor: the X-value depends now on attach-dir. For the start of the
DurationLine this is ofcourse RIGHT. But if starting at a skip,
left-bound is PaperColumn there we would want LEFT. Can be fixed by
accurate conditions. Count it as done.

The major: `ly:horizontal-line-spanner::calc-right-bound-info' and
`unbroken-or-last-broken-spanner?' (and friends) don't agree what's
the last part of the spanner.
To illustrate:

\version "2.23.7"

\layout {
\context {
  \Voice
  \consists "Duration_line_engraver"
}
}

{
   \override DurationLine.bound-details.right.foo =
 "I am last part (bound-details)"
   \override DurationLine.bound-details.right-broken.foo =
 "I am not last part (bound-details)"

   \override DurationLine.after-line-breaking =
   #(lambda (grob)
 (pretty-print
   (if (unbroken-or-last-broken-spanner? grob)
   "I am last part (unbroken-or-last-broken-spanner?)"
   "I am not last part (unbroken-or-last-broken-spanner?)"))
 (pretty-print
   (assoc-get 'foo (ly:horizontal-line-spanner::calc-right-bound-info 
grob

   b1\-
}

=>
"I am last part (unbroken-or-last-broken-spanner?)"
"I am not last part (bound-details)"

The problem occurs if we have a broken DurationLine with end-items
running to the very end of the score.
To fix it one would again need something like:

{
\override DurationLine.bound-details =
#(grob-transformer 'bound-details
  (lambda (grob orig)
   (if (end-broken-spanner? grob)
   (cons
 (cons 'right-broken
   (cons '(end-style . arrow) (assoc-get 'right-broken orig)))
 orig)
   orig)))
b1\-
\break
s1
\break
s1
\bar "|."
}

Or like \lastEndStyle which you cleared with

commit 46671d13257f6ad68d1778a1cc850e59116c856a
Author: Jean Abou Samra 
Date:   Wed Dec 29 00:16:46 2021 +0100

  Fix broken spanner functions

  They were broken (pun intended) on spanners of which one bound is a
  non-musical column at a system boundary.  For example,
  unbroken-or-last-broken-spanner? would return false on a spanner
  running to the NonMusicalPaperColumn at the end of a score.  This
  fixes the known issue with duration lines running to the end of the
  piece, and will be needed in a refactoring of spanner-placement
  treatment for balloon-interface.

  While at it, document these functions.

This is unfortunate. Any chance making
`ly:horizontal-line-spanner::calc-right-bound-info' and friends
identify the last spanner-part correctly, i.e. like
`unbroken-or-last-broken-spanner?'
?



Ah, this one is showing up again. Yes, this is not too hard to
fix (but please allow me 

Re: DurationLine avoiding RehearsalMarks

2022-04-15 Thread Thomas Morley
Am Fr., 15. Apr. 2022 um 10:39 Uhr schrieb Jean Abou Samra :
>
>
>
> Le 15/04/2022 à 10:13, Thomas Morley a écrit :
> > Am Mi., 13. Apr. 2022 um 17:57 Uhr schrieb Jean Abou Samra 
> > :
> >> Le 13/04/2022 à 17:03, Thomas Morley a écrit :
> >>> Am Di., 12. Apr. 2022 um 11:54 Uhr schrieb Jean Abou Samra 
> >>> :
>  Le 12/04/2022 à 11:16, Thomas Morley a écrit :
> >>> [...]
> > In many details DurationLine was tailored after Glissando and
> > Glissando _is_ effected by the breathing sign.
> >>> [...]
> >>>
>  Well, if the goal is to have DurationLine similar to Glissando,
>  how about reusing line-spanner-interface code? I haven't reviewed
>  the code very thoroughly, but I assumed there was a difference
>  warranting a different code path. If you put
>  ly:line-spanner::calc-{left,right}-bound-info in
>  DurationLine.{left,righ}-bound-info, that gives you X values for free
>  in the bound info properties. Would that solve the problem?
> >>> If I go for ly:line-spanner::calc-{left,right}-bound-info then
> >>>
> >>> \layout {
> >>>  \context {
> >>>\Voice
> >>>\consists Duration_line_engraver
> >>>  }
> >>> }
> >>>
> >>> { b1\- }
> >>>
> >>> errors with
> >>>   "programming error: extremal broken spanner's bound has no parent
> >>> vertical axis group"
> >>> More complex examples may add:
> >>>   "programming error: bound item has no parent vertical axis group"
> >>> Both coming from `ly:line-spanner::calc-right-bound-info' based upon
> >>> `Line_spanner::calc_bound_info' in /lily/line-spanner.cc
> >>>
> >>> As a mere user I'd say: "Nice error-message, but why should I care...?"
> >>>
> >>> As a programmer, I doubt the example above can be made working with
> >>> ly:line-spanner::calc-right-bound-info.
> >>> At least, I don't know how.
> >>
> >> Oh, I'm sorry, I missed that detail of my own code. A DurationLine will
> >> always be horizontal, thus you can and should use
> >> ly:horizontal-line-spanner::calc-{left,right}-bound-info (with 'horizontal'
> >> in the name).  The difference is that the functions without 'horizontal'
> >> try to compute vertical positions. This falls apart here, for 
> >> understandable
> >> reasons: the right bound of your DurationLine is a NonMusicalPaperColumn,
> >> so how would one tell where the line should end vertically?
> > Using ly:horizontal-line-spanner::calc-{left,right}-bound-info makes
> > for huge simplifications.
> > Alas, it introduces a minor and reintroduces a major problem.
> >
> > The minor: the X-value depends now on attach-dir. For the start of the
> > DurationLine this is ofcourse RIGHT. But if starting at a skip,
> > left-bound is PaperColumn there we would want LEFT. Can be fixed by
> > accurate conditions. Count it as done.
> >
> > The major: `ly:horizontal-line-spanner::calc-right-bound-info' and
> > `unbroken-or-last-broken-spanner?' (and friends) don't agree what's
> > the last part of the spanner.
> > To illustrate:
> >
> > \version "2.23.7"
> >
> > \layout {
> >\context {
> >  \Voice
> >  \consists "Duration_line_engraver"
> >}
> > }
> >
> > {
> >   \override DurationLine.bound-details.right.foo =
> > "I am last part (bound-details)"
> >   \override DurationLine.bound-details.right-broken.foo =
> > "I am not last part (bound-details)"
> >
> >   \override DurationLine.after-line-breaking =
> >   #(lambda (grob)
> > (pretty-print
> >   (if (unbroken-or-last-broken-spanner? grob)
> >   "I am last part (unbroken-or-last-broken-spanner?)"
> >   "I am not last part (unbroken-or-last-broken-spanner?)"))
> > (pretty-print
> >   (assoc-get 'foo (ly:horizontal-line-spanner::calc-right-bound-info 
> > grob
> >
> >   b1\-
> > }
> >
> > =>
> > "I am last part (unbroken-or-last-broken-spanner?)"
> > "I am not last part (bound-details)"
> >
> > The problem occurs if we have a broken DurationLine with end-items
> > running to the very end of the score.
> > To fix it one would again need something like:
> >
> > {
> >\override DurationLine.bound-details =
> >#(grob-transformer 'bound-details
> >  (lambda (grob orig)
> >   (if (end-broken-spanner? grob)
> >   (cons
> > (cons 'right-broken
> >   (cons '(end-style . arrow) (assoc-get 'right-broken orig)))
> > orig)
> >   orig)))
> >b1\-
> >\break
> >s1
> >\break
> >s1
> >\bar "|."
> > }
> >
> > Or like \lastEndStyle which you cleared with
> >
> > commit 46671d13257f6ad68d1778a1cc850e59116c856a
> > Author: Jean Abou Samra 
> > Date:   Wed Dec 29 00:16:46 2021 +0100
> >
> >  Fix broken spanner functions
> >
> >  They were broken (pun intended) on spanners of which one bound is a
> >  non-musical column at a system boundary.  For example,
> >  unbroken-or-last-broken-spanner? would return false on a spanner
> >  running to the NonMusicalPaperColumn at the end of a score.  This
> >  

Re: Tags for contexts without duration

2022-04-15 Thread Dimitris Marinakis
Oh wow I can't believe I missed this use of tags. I was trying to use the
bracket syntax. Thanks Jean!



On Fri, Apr 15, 2022 at 12:43 AM Jean Abou Samra  wrote:

> Le 14/04/2022 à 22:44, Dimitris Marinakis a écrit :
> > I often find myself in need of offsetting some tempo or rehearsal
> > marks for certain parts but not the full score but tags won't work in
> > this case since I can't have two marks at the same location on a
> > single context.
>
> Not sure I understand the problem?
>
> \version "2.22.2"
>
> mus = {
>\tag #'part \once \override Score.RehearsalMark.X-offset = 8
>\mark \default
>c'
> }
>
> % Conductor
> \removeWithTag #'part \mus
>
> % Parts
> { \mus }
>
>
> Best,
> Jean
>
>


Re: DurationLine avoiding RehearsalMarks

2022-04-15 Thread Jean Abou Samra




Le 15/04/2022 à 10:13, Thomas Morley a écrit :

Am Mi., 13. Apr. 2022 um 17:57 Uhr schrieb Jean Abou Samra :

Le 13/04/2022 à 17:03, Thomas Morley a écrit :

Am Di., 12. Apr. 2022 um 11:54 Uhr schrieb Jean Abou Samra :

Le 12/04/2022 à 11:16, Thomas Morley a écrit :

[...]

In many details DurationLine was tailored after Glissando and
Glissando _is_ effected by the breathing sign.

[...]


Well, if the goal is to have DurationLine similar to Glissando,
how about reusing line-spanner-interface code? I haven't reviewed
the code very thoroughly, but I assumed there was a difference
warranting a different code path. If you put
ly:line-spanner::calc-{left,right}-bound-info in
DurationLine.{left,righ}-bound-info, that gives you X values for free
in the bound info properties. Would that solve the problem?

If I go for ly:line-spanner::calc-{left,right}-bound-info then

\layout {
 \context {
   \Voice
   \consists Duration_line_engraver
 }
}

{ b1\- }

errors with
  "programming error: extremal broken spanner's bound has no parent
vertical axis group"
More complex examples may add:
  "programming error: bound item has no parent vertical axis group"
Both coming from `ly:line-spanner::calc-right-bound-info' based upon
`Line_spanner::calc_bound_info' in /lily/line-spanner.cc

As a mere user I'd say: "Nice error-message, but why should I care...?"

As a programmer, I doubt the example above can be made working with
ly:line-spanner::calc-right-bound-info.
At least, I don't know how.


Oh, I'm sorry, I missed that detail of my own code. A DurationLine will
always be horizontal, thus you can and should use
ly:horizontal-line-spanner::calc-{left,right}-bound-info (with 'horizontal'
in the name).  The difference is that the functions without 'horizontal'
try to compute vertical positions. This falls apart here, for understandable
reasons: the right bound of your DurationLine is a NonMusicalPaperColumn,
so how would one tell where the line should end vertically?

Using ly:horizontal-line-spanner::calc-{left,right}-bound-info makes
for huge simplifications.
Alas, it introduces a minor and reintroduces a major problem.

The minor: the X-value depends now on attach-dir. For the start of the
DurationLine this is ofcourse RIGHT. But if starting at a skip,
left-bound is PaperColumn there we would want LEFT. Can be fixed by
accurate conditions. Count it as done.

The major: `ly:horizontal-line-spanner::calc-right-bound-info' and
`unbroken-or-last-broken-spanner?' (and friends) don't agree what's
the last part of the spanner.
To illustrate:

\version "2.23.7"

\layout {
   \context {
 \Voice
 \consists "Duration_line_engraver"
   }
}

{
  \override DurationLine.bound-details.right.foo =
"I am last part (bound-details)"
  \override DurationLine.bound-details.right-broken.foo =
"I am not last part (bound-details)"

  \override DurationLine.after-line-breaking =
  #(lambda (grob)
(pretty-print
  (if (unbroken-or-last-broken-spanner? grob)
  "I am last part (unbroken-or-last-broken-spanner?)"
  "I am not last part (unbroken-or-last-broken-spanner?)"))
(pretty-print
  (assoc-get 'foo (ly:horizontal-line-spanner::calc-right-bound-info 
grob

  b1\-
}

=>
"I am last part (unbroken-or-last-broken-spanner?)"
"I am not last part (bound-details)"

The problem occurs if we have a broken DurationLine with end-items
running to the very end of the score.
To fix it one would again need something like:

{
   \override DurationLine.bound-details =
   #(grob-transformer 'bound-details
 (lambda (grob orig)
  (if (end-broken-spanner? grob)
  (cons
(cons 'right-broken
  (cons '(end-style . arrow) (assoc-get 'right-broken orig)))
orig)
  orig)))
   b1\-
   \break
   s1
   \break
   s1
   \bar "|."
}

Or like \lastEndStyle which you cleared with

commit 46671d13257f6ad68d1778a1cc850e59116c856a
Author: Jean Abou Samra 
Date:   Wed Dec 29 00:16:46 2021 +0100

 Fix broken spanner functions

 They were broken (pun intended) on spanners of which one bound is a
 non-musical column at a system boundary.  For example,
 unbroken-or-last-broken-spanner? would return false on a spanner
 running to the NonMusicalPaperColumn at the end of a score.  This
 fixes the known issue with duration lines running to the end of the
 piece, and will be needed in a refactoring of spanner-placement
 treatment for balloon-interface.

 While at it, document these functions.

This is unfortunate. Any chance making
`ly:horizontal-line-spanner::calc-right-bound-info' and friends
identify the last spanner-part correctly, i.e. like
`unbroken-or-last-broken-spanner?'
?




Ah, this one is showing up again. Yes, this is not too hard to
fix (but please allow me some time).




At any rate, many thanks for the hint to
ly:_horizontal:-line-spanner::calc-left/right-bound-info.
I may remember wrong, but I think I tried

Re: DurationLine avoiding RehearsalMarks

2022-04-15 Thread Thomas Morley
Am Mi., 13. Apr. 2022 um 17:57 Uhr schrieb Jean Abou Samra :
>
> Le 13/04/2022 à 17:03, Thomas Morley a écrit :
> > Am Di., 12. Apr. 2022 um 11:54 Uhr schrieb Jean Abou Samra 
> > :
> >> Le 12/04/2022 à 11:16, Thomas Morley a écrit :
> > [...]
> >>> In many details DurationLine was tailored after Glissando and
> >>> Glissando _is_ effected by the breathing sign.
> > [...]
> >
> >> Well, if the goal is to have DurationLine similar to Glissando,
> >> how about reusing line-spanner-interface code? I haven't reviewed
> >> the code very thoroughly, but I assumed there was a difference
> >> warranting a different code path. If you put
> >> ly:line-spanner::calc-{left,right}-bound-info in
> >> DurationLine.{left,righ}-bound-info, that gives you X values for free
> >> in the bound info properties. Would that solve the problem?
> > If I go for ly:line-spanner::calc-{left,right}-bound-info then
> >
> > \layout {
> > \context {
> >   \Voice
> >   \consists Duration_line_engraver
> > }
> > }
> >
> > { b1\- }
> >
> > errors with
> >  "programming error: extremal broken spanner's bound has no parent
> > vertical axis group"
> > More complex examples may add:
> >  "programming error: bound item has no parent vertical axis group"
> > Both coming from `ly:line-spanner::calc-right-bound-info' based upon
> > `Line_spanner::calc_bound_info' in /lily/line-spanner.cc
> >
> > As a mere user I'd say: "Nice error-message, but why should I care...?"
> >
> > As a programmer, I doubt the example above can be made working with
> > ly:line-spanner::calc-right-bound-info.
> > At least, I don't know how.
>
>
> Oh, I'm sorry, I missed that detail of my own code. A DurationLine will
> always be horizontal, thus you can and should use
> ly:horizontal-line-spanner::calc-{left,right}-bound-info (with 'horizontal'
> in the name).  The difference is that the functions without 'horizontal'
> try to compute vertical positions. This falls apart here, for understandable
> reasons: the right bound of your DurationLine is a NonMusicalPaperColumn,
> so how would one tell where the line should end vertically?

Using ly:horizontal-line-spanner::calc-{left,right}-bound-info makes
for huge simplifications.
Alas, it introduces a minor and reintroduces a major problem.

The minor: the X-value depends now on attach-dir. For the start of the
DurationLine this is ofcourse RIGHT. But if starting at a skip,
left-bound is PaperColumn there we would want LEFT. Can be fixed by
accurate conditions. Count it as done.

The major: `ly:horizontal-line-spanner::calc-right-bound-info' and
`unbroken-or-last-broken-spanner?' (and friends) don't agree what's
the last part of the spanner.
To illustrate:

\version "2.23.7"

\layout {
  \context {
\Voice
\consists "Duration_line_engraver"
  }
}

{
 \override DurationLine.bound-details.right.foo =
   "I am last part (bound-details)"
 \override DurationLine.bound-details.right-broken.foo =
   "I am not last part (bound-details)"

 \override DurationLine.after-line-breaking =
 #(lambda (grob)
   (pretty-print
 (if (unbroken-or-last-broken-spanner? grob)
 "I am last part (unbroken-or-last-broken-spanner?)"
 "I am not last part (unbroken-or-last-broken-spanner?)"))
   (pretty-print
 (assoc-get 'foo (ly:horizontal-line-spanner::calc-right-bound-info grob

 b1\-
}

=>
"I am last part (unbroken-or-last-broken-spanner?)"
"I am not last part (bound-details)"

The problem occurs if we have a broken DurationLine with end-items
running to the very end of the score.
To fix it one would again need something like:

{
  \override DurationLine.bound-details =
  #(grob-transformer 'bound-details
(lambda (grob orig)
 (if (end-broken-spanner? grob)
 (cons
   (cons 'right-broken
 (cons '(end-style . arrow) (assoc-get 'right-broken orig)))
   orig)
 orig)))
  b1\-
  \break
  s1
  \break
  s1
  \bar "|."
}

Or like \lastEndStyle which you cleared with

commit 46671d13257f6ad68d1778a1cc850e59116c856a
Author: Jean Abou Samra 
Date:   Wed Dec 29 00:16:46 2021 +0100

Fix broken spanner functions

They were broken (pun intended) on spanners of which one bound is a
non-musical column at a system boundary.  For example,
unbroken-or-last-broken-spanner? would return false on a spanner
running to the NonMusicalPaperColumn at the end of a score.  This
fixes the known issue with duration lines running to the end of the
piece, and will be needed in a refactoring of spanner-placement
treatment for balloon-interface.

While at it, document these functions.

This is unfortunate. Any chance making
`ly:horizontal-line-spanner::calc-right-bound-info' and friends
identify the last spanner-part correctly, i.e. like
`unbroken-or-last-broken-spanner?'
?

At any rate, many thanks for the hint to
ly:_horizontal:-line-spanner::calc-left/right-bound-info.
I may remember wrong, but I think I tried