Automatically identify beats

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

Automatically identify beats

Daniel Sales
Hi, is it possible to identify the beats on each different timing
automatically, in order to set a different color for strong, medium and
weak beats ?

something like

\coloredBeats <color_for_strong_beat> <color_for_medium_beat>
<color_for_weak_beat> (black as default)
...

For example, the expected output for

\score {
   \new Staff  {
     \coloredBeats #red #green #black
     \time 2/4 a4 b |
     \time 3/4 a4 b c |
     \time 4/4 a4 b c d |
     \time 6/8 f8 g a b c d
   }
}

  would be equivalent to:

strongBeat = {
     \override NoteHead.color = #red
     \override Stem.color = #red
}
mediumBeat = {
     \override NoteHead.color = #green
     \override Stem.color = #green
}
weakBeat = {
     \override NoteHead.color = #black
     \override Stem.color = #black
}
\score {
   \new Staff  {
     \time 2/4 \strongBeat a4 \weakBeat b |
     \time 3/4 \strongBeat a4 \mediumBeat b \weakBeat c |
     \time 4/4 \strongBeat a4 \weakBeat b \mediumBeat c \weakBeat d |
     \time 6/8 \strongBeat f8 \mediumBeat g \weakBeat a \strongBeat b
\mediumBeat c \weakBeat d
   }
}





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

Re: Automatically identify beats

Kieren MacMillan
Hi Daniel,

> is it possible to identify the beats on each different timing automatically, in order to set a different color for strong, medium and weak beats ?

This looks like a job for… Scheme!  =)

Much like auto-beaming has rules that are applied by time signature, what you want can be done using a callback function for NoteHead.color, which figured out which beat of which time signature it was and colored itself accordingly.

Way beyond my current Scheme-fu… but there are definitely people on the list who could whip up an example for you, if you can’t get there yourself (by adapting similar functions from the docs).

Cheers,
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: Automatically identify beats

Aaron Hill
In reply to this post by Daniel Sales
On 2018-10-06 10:01 am, Daniel Sales wrote:

> Hi, is it possible to identify the beats on each different timing
> automatically, in order to set a different color for strong, medium
> and weak beats ?
>
> something like
>
> \coloredBeats <color_for_strong_beat> <color_for_medium_beat>
> <color_for_weak_beat> (black as default)
> ...
>
> For example, the expected output for
>
> \score {
>   \new Staff  {
>     \coloredBeats #red #green #black
>     \time 2/4 a4 b |
>     \time 3/4 a4 b c |
>     \time 4/4 a4 b c d |
>     \time 6/8 f8 g a b c d
>   }
> }
>
>  would be equivalent to:
>
> strongBeat = {
>     \override NoteHead.color = #red
>     \override Stem.color = #red
> }
> mediumBeat = {
>     \override NoteHead.color = #green
>     \override Stem.color = #green
> }
> weakBeat = {
>     \override NoteHead.color = #black
>     \override Stem.color = #black
> }
> \score {
>   \new Staff  {
>     \time 2/4 \strongBeat a4 \weakBeat b |
>     \time 3/4 \strongBeat a4 \mediumBeat b \weakBeat c |
>     \time 4/4 \strongBeat a4 \weakBeat b \mediumBeat c \weakBeat d |
>     \time 6/8 \strongBeat f8 \mediumBeat g \weakBeat a \strongBeat b
> \mediumBeat c \weakBeat d
>   }
> }
Hi Daniel,

The biggest hurdle as I see it is computationally determining what is
meant by "strong", "medium", and "weak".  Those labels might have an
intuitive understanding by musicians, but for computers they require
additional input.

For instance, 6/8 timing could be thought of as "1 2 3 / 4 5 6" or "1 2
/ 3 4 / 5 6".  Aside from other possible subdivisions, these two timing
options each could have different degrees of emphasis applied (e.g. "S M
W / S M W", "S W W / M W W", "S W / M W / M W" ...).  As such, the time
signature alone is not enough information for a computer to be able to
color note heads correctly.

So, let me propose an alternative to your original interface that will
hopefully be both useful and easier to implement/maintain:

%%%%
\version "2.19.82"

#(define (rational-color-pair? x)
   (and (pair? x) (rational? (car x)) (color? (cdr x))))
#(define (rational-color-pair-list? x)
   (and (list? x) (rational-color-pair? (car x))
     (or (null? (cdr x)) (rational-color-pair-list? (cdr x)))))
colorizeBeats = #(define-music-function (args)
   (rational-color-pair-list?)
   "Conditionally overrides the color of the note head based on
    its position within a measure."
   #{ \override NoteHead.color = #(lambda (grob)
        (let* ((moment (grob::rhythmic-location grob))
               (matches? (lambda (m r)
                 (eqv? 0 (ly:moment-main-numerator
                   (ly:moment-mod m (ly:make-moment r))))))
               (color (assoc (cdr moment) args matches?)))
         (if color (cdr color)))) #} )

{
   \colorizeBeats #(list (cons 1/2 (x11-color 'red))
                         (cons 3/8 (x11-color 'orange)))
   \time 4/4 \repeat unfold 16 { b'8 }
   \colorizeBeats #(list (cons 3/8 (x11-color 'red))
                         (cons 3/16 (x11-color 'orange)))
   \time 6/8 \repeat unfold 2 { b'8 8 8 8. 8. }
   \colorizeBeats #(list (cons 1/4 (x11-color 'red))
                         (cons 1/12 (x11-color 'orange)))
   \time 5/4 \repeat unfold 2 { b'2 \tuplet 3/2 { 8 8 8 } 4 8 8 }
}
%%%%

This approach does not attempt to parse the time signature but rather
requires the user to provide a list of time intervals and their desired
color.  Note that the first rule in the list that matches will be
applied, so the ordering within the list is important.

In the example provided, the first section highlights in red every half
note (or more precisely, every note that *aligns* to a half note) and in
orange every dotted quarter.  The second highlights dotted quarters and
dotted eighths in a similar manner.  The third example shows the effect
working with tuplets by coloring so-called "twelfth" notes.

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

beatcolor.cropped.png (14K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Automatically identify beats

Thomas Morley-2
Am So., 7. Okt. 2018 um 07:31 Uhr schrieb Aaron Hill <[hidden email]>:
>
> On 2018-10-06 10:01 am, Daniel Sales wrote:
> > Hi, is it possible to identify the beats on each different timing
> > automatically, in order to set a different color for strong, medium
> > and weak beats ?

> The biggest hurdle as I see it is computationally determining what is
> meant by "strong", "medium", and "weak".  Those labels might have an
> intuitive understanding by musicians, but for computers they require
> additional input.
>
> For instance, 6/8 timing could be thought of as "1 2 3 / 4 5 6" or "1 2
> / 3 4 / 5 6".

I disagree.
"1 2 / 3 4 / 5 6" feels like 3/4. No matter what is actual printed.

Even with Daniels manual coloring I disagree, more, the (not
demonstrated) 5/8 can be done as 2-3 or 3-2, etc

So I think one _must_ specify which colors are to be used and where.

Aaron's approach does so:

> So, let me propose an alternative to your original interface that will
> hopefully be both useful and easier to implement/maintain:
>
> %%%%
> \version "2.19.82"
>
> #(define (rational-color-pair? x)
>    (and (pair? x) (rational? (car x)) (color? (cdr x))))
> #(define (rational-color-pair-list? x)
>    (and (list? x) (rational-color-pair? (car x))
>      (or (null? (cdr x)) (rational-color-pair-list? (cdr x)))))
> colorizeBeats = #(define-music-function (args)
>    (rational-color-pair-list?)
>    "Conditionally overrides the color of the note head based on
>     its position within a measure."
>    #{ \override NoteHead.color = #(lambda (grob)
>         (let* ((moment (grob::rhythmic-location grob))
>                (matches? (lambda (m r)
>                  (eqv? 0 (ly:moment-main-numerator
>                    (ly:moment-mod m (ly:make-moment r))))))
>                (color (assoc (cdr moment) args matches?)))
>          (if color (cdr color)))) #} )
>
> {
>    \colorizeBeats #(list (cons 1/2 (x11-color 'red))
>                          (cons 3/8 (x11-color 'orange)))
>    \time 4/4 \repeat unfold 16 { b'8 }
>    \colorizeBeats #(list (cons 3/8 (x11-color 'red))
>                          (cons 3/16 (x11-color 'orange)))
>    \time 6/8 \repeat unfold 2 { b'8 8 8 8. 8. }
>    \colorizeBeats #(list (cons 1/4 (x11-color 'red))
>                          (cons 1/12 (x11-color 'orange)))
>    \time 5/4 \repeat unfold 2 { b'2 \tuplet 3/2 { 8 8 8 } 4 8 8 }
> }
> %%%%
>
> This approach does not attempt to parse the time signature but rather
> requires the user to provide a list of time intervals and their desired
> color.  Note that the first rule in the list that matches will be
> applied, so the ordering within the list is important.
>
> In the example provided, the first section highlights in red every half
> note (or more precisely, every note that *aligns* to a half note) and in
> orange every dotted quarter.  The second highlights dotted quarters and
> dotted eighths in a similar manner.  The third example shows the effect
> working with tuplets by coloring so-called "twelfth" notes.
>
> -- Aaron Hill_______________________________________________

Though, I think it clutters the input. (And returns inconsistent
results for \partial, although this would be not too had to fix.)

Below my own attempt using an engraver (to have access to the
'timeSignatureFraction, a context-property, and to Stem/NoteHead-grobs
in one go).
The colors are stored/mapped in a predefined list. The newly defined
context-property 'colorLikeTiming is set to this list. Making it
user-adjustable where needed.

Ofcourse there's wide room for improvements.
One example: _Every_ TimeSignature will have a strong emphasis at
first beat. Thus one could reflect this in the coding, currently
you'll have to explicitely set colors on every beat you want.
Or a better user-interface to adjust 'colorLikeTiming where needed.
But I'm lazy today ... ;)

\version "2.19.82"

#(define (define-translator-property symbol type? description)
  (if (not (and (symbol? symbol)
                (procedure? type?)
                (string? description)))
      (ly:error "error in call of define-translator-property"))
  (if (not (equal? (object-property symbol 'translation-doc) #f))
      (ly:error (_ "symbol ~S redefined") symbol))

  (set-object-property! symbol 'translation-type? type?)
  (set-object-property! symbol 'translation-doc description)
  symbol)

#(for-each
  (lambda (x)
    (apply define-translator-property x))
    `((colorLikeTiming
       ,list?
       "An alist which maps color-symbols to bar-position-fractions, relying
on time-signature-fractions.")))

#(define my-color-like-timing-list
  '(
    ;; 4/4
    ((4 . 4)
     .
     ((0 . red)
      (1/2 . green)))
    ;; 3/4
    ((3 . 4)
     .
     ((0 . red)
      (1/8 . orange)
      (1/4 . cyan)
      (3/8 . orange)
      (2/4 . cyan)
      (5/8 . orange)))
    ;; 2/2
    ((2 . 2)
     .
     ((0 . red)))
    ;; 8/8
    ((8 . 8)
     .
     ((0 . red)
      (1/8 . orange)
      (3/8 . orange)
      (1/2 . green)
      (5/8 . orange)
      (7/8 . orange)))
    ;; 6/8
    ((6 . 8)
     .
     ((0 . red)
      (3/8 . green)))
    ;; 5/8
    ((5 . 8)
     .
     ((0 . red)
      (3/8 . green)))
      ))

#(define (color-according-to-time-sig time-sig timing-color-ctx-prop)
  (lambda (grob)
    (ly:grob-set-property! grob 'color
      (lambda (grob)
        (let* ((loc (grob::rhythmic-location grob))
               (raw-in-bar-position (ly:moment-main (cdr loc)))
               ;; Care about negative position in \partial
               (in-bar-position
                 (if (negative? raw-in-bar-position)
                     (- (/ (car time-sig) (cdr time-sig))
                        (abs raw-in-bar-position))
                     raw-in-bar-position))
               ;; get the positions/colors from the predefined alist,
               ;; according to the relevant TimeSignature
               (timing-colors
                 (assoc-get time-sig timing-color-ctx-prop '()))
               ;; get the relevant color from timing-colors, according
               ;; to current position in bar
               (clr
                 (assoc-get in-bar-position timing-colors)))
          ;; Throw a warning, if no colors defined for this TimeSignature.
          ;; TODO Needed? Probably delete/comment
          (if (null? timing-colors)
              (ly:warning "No colors set for \\time ~a/~a"
                          (car time-sig) (cdr time-sig)))
          (if clr
              (x11-color clr)
              '()))))))

Color_like_time_signature_engraver =
#(lambda (context)
  (let ((time-sig-frac #f))
    (make-engraver
      (listeners
        ((rhythmic-event engraver event)
         ;; TODO
         ;; Will it always be sufficient to get 'timeSignatureFraction here?
         (set! time-sig-frac
               (ly:context-property context 'timeSignatureFraction))))
      (acknowledgers
        ((stem-interface engraver grob source-engraver)
         (let ((current-time-sig time-sig-frac)
               (time-sig-colors
                 (ly:context-property context 'colorLikeTiming)))
           ;; Stem shouldn't be printed on top of Beam
           (ly:grob-set-property! grob 'layer -100)
           ((color-according-to-time-sig current-time-sig time-sig-colors)
             grob)))
        ((note-head-interface engraver grob source-engraver)
         (let ((current-time-sig time-sig-frac)
               (time-sig-colors
                 (ly:context-property context 'colorLikeTiming)))
           ((color-according-to-time-sig current-time-sig time-sig-colors)
             grob))))
      ((finalize engraver)
       ;; Need to clear time-sig-fracs?
       ;; Better be paranoid
       (set! time-sig-frac #f)))))


\score {
  {
    \time 8/8
    \partial 8*7
    c'8[ 8 8] 8[ 8 8 8]
    c'1
    \repeat unfold 4 cis'4
    %\displayMusic
    \time 6/8
    d'4. 4.
    e'8 8 8 f'8 8 8
    \time 5/8
    g'8 8 8 8 8

    \time 2,3 5/8
    %% This 5/8 has different settings, so adjust 'colorLikeTiming
    \set Staff.colorLikeTiming =
      #'(((5 . 8)
         .
         ((0 . red)
          (2/8 . green))))

    g'8 8 8 8 8

    %% return to previous 'colorLikeTiming
    \set Staff.colorLikeTiming = \my-color-like-timing-list
    \time 5/8
    a'8 8 8 8 8

    \set beamExceptions = #'()
    \time  3/4
    b'8 8 8 8 8 8
    c''8 2 8

    \time 3/16
    d''16 16 16
  }
  \layout {
    \context {
      \Staff
      %% set the context-property 'colorLikeTiming
      colorLikeTiming = \my-color-like-timing-list
      %% consist the engraver in Staff
      \consists #Color_like_time_signature_engraver
    }
  }
}


HTH,
  Harm

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

Re: Automatically identify beats

Aaron Hill
On 2018-10-07 4:29 am, Thomas Morley wrote:
> Am So., 7. Okt. 2018 um 07:31 Uhr schrieb Aaron Hill
> <[hidden email]>:
>> For instance, 6/8 timing could be thought of as "1 2 3 / 4 5 6" or "1
>> 2
>> / 3 4 / 5 6".
>
> I disagree.
> "1 2 / 3 4 / 5 6" feels like 3/4. No matter what is actual printed.

Of course it would feel like 3/4.  3/4 is simply "1 2 3" but "1 + 2 + 3
+" if we count the ANDs.  3/4 and 6/8 are the same rational value so
it's not surprising to see overlap.  Things get more interesting,
however, when you have songs that are in 6/8 but have a 4/4 feel due to
use of dotted eighths.  Or would that be 4/(5 1/3)? ;-)

> Though, I think it clutters the input. (And returns inconsistent
> results for \partial, although this would be not too had to fix.)

Oops, didn't think about that case.  I guess I was just happy that
tuplets worked providing you do the math and specify the correct
rational number.  But I wouldn't doubt that more interesting music would
exhibit odd behavior because I oversimplified something.

> Below my own attempt using an engraver (to have access to the
> 'timeSignatureFraction, a context-property, and to Stem/NoteHead-grobs
> in one go).
> [ . . . ]

That is definitely something I will have to review in detail, as I have
not yet worked with engravers and contexts obviously still have a lot to
learn.


-- 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: Automatically identify beats

Thomas Morley-2
Am So., 7. Okt. 2018 um 15:59 Uhr schrieb Aaron Hill <[hidden email]>:
>
> On 2018-10-07 4:29 am, Thomas Morley wrote:

> > Below my own attempt using an engraver (to have access to the
> > 'timeSignatureFraction, a context-property, and to Stem/NoteHead-grobs
> > in one go).
> > [ . . . ]
>
> That is definitely something I will have to review in detail, as I have
> not yet worked with engravers and contexts obviously still have a lot to
> learn.
>
>
> -- Aaron Hill

There are not many ways to access grobs and contexts at the same time.
I think, engravers are the most general.
We have some examples of scheme-engravers in the regression-tests.
(And in the archives of the mailing-list ofcourse.)
A good starting point is ‘scheme-engraver.ly’ from:
http://lilypond.org/doc/v2.19/input/regression/collated-files.html
It demonstrates all possible "entry-points".

http://lilypond.org/doc/v2.19/Documentation/contributor-big-page#engraver-tutorial
gives some documentation. It's for C++, but things are not very
different for scheme.

If you have too much time, you may have a look at ‘scheme-engraver.ly’ from
http://lilypond.org/doc/v2.13/input/regression/collated-files.html
The newer file uses the great 'make-engraver'-macro (by David Kastrup).
Otoh, this macro hides an engraver _is_ a list (which is obvious, if
you look in the older file).
I had found it useful to observe the list-syntax for a long time, even
after the make-engraver-macro was out.
Helped me learning.

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: Automatically identify beats

David Kastrup
Thomas Morley <[hidden email]> writes:

> If you have too much time, you may have a look at ‘scheme-engraver.ly’
> from
> http://lilypond.org/doc/v2.13/input/regression/collated-files.html The
> newer file uses the great 'make-engraver'-macro (by David Kastrup).
> Otoh, this macro hides an engraver _is_ a list (which is obvious, if
> you look in the older file).

An engraver is not a list, just like it isn't a string like
"Note_engraver".  That's just how you _specify_ an engraver.  If it's a
list, the Scheme_engraver type will be used for actually instantiating
an engraver (which is bound to a particular context), initialized using
the list contents.

--
David Kastrup

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

Re: Automatically identify beats

Thomas Morley-2
Am So., 7. Okt. 2018 um 18:00 Uhr schrieb David Kastrup <[hidden email]>:

>
> Thomas Morley <[hidden email]> writes:
>
> > If you have too much time, you may have a look at ‘scheme-engraver.ly’
> > from
> > http://lilypond.org/doc/v2.13/input/regression/collated-files.html The
> > newer file uses the great 'make-engraver'-macro (by David Kastrup).
> > Otoh, this macro hides an engraver _is_ a list (which is obvious, if
> > you look in the older file).
>
> An engraver is not a list, just like it isn't a string like
> "Note_engraver".  That's just how you _specify_ an engraver.  If it's a
> list, the Scheme_engraver type will be used for actually instantiating
> an engraver (which is bound to a particular context), initialized using
> the list contents.

Hi David,

I don't understand the subtleties.
Could you elaborate a bit using the examples below.

testI =
  #(list
    (cons 'initialize
     (lambda (trans)
       (write trans))))

testII =
  #(lambda (ctx) testI)

\layout {
  \context {
    \Voice
    \consists #testI
    \consists #testII
  }
}

{ R1 }

testI is a list, testII a procedure using testI.
Both return #<Translator Scheme_engraver >, though.

Thanks,
  Harm

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

Re: Automatically identify beats

David Kastrup
Thomas Morley <[hidden email]> writes:

> Am So., 7. Okt. 2018 um 18:00 Uhr schrieb David Kastrup <[hidden email]>:
>>
>> Thomas Morley <[hidden email]> writes:
>>
>> > If you have too much time, you may have a look at ‘scheme-engraver.ly’
>> > from
>> > http://lilypond.org/doc/v2.13/input/regression/collated-files.html The
>> > newer file uses the great 'make-engraver'-macro (by David Kastrup).
>> > Otoh, this macro hides an engraver _is_ a list (which is obvious, if
>> > you look in the older file).
>>
>> An engraver is not a list, just like it isn't a string like
>> "Note_engraver".  That's just how you _specify_ an engraver.  If it's a
>> list, the Scheme_engraver type will be used for actually instantiating
>> an engraver (which is bound to a particular context), initialized using
>> the list contents.
>
> Hi David,
>
> I don't understand the subtleties.
> Could you elaborate a bit using the examples below.
>
> testI =
>   #(list
>     (cons 'initialize
>      (lambda (trans)
>        (write trans))))
>
> testII =
>   #(lambda (ctx) testI)
>
> \layout {
>   \context {
>     \Voice
>     \consists #testI
>     \consists #testII
>   }
> }
>
> { R1 }
>
> testI is a list, testII a procedure using testI.
> Both return #<Translator Scheme_engraver >, though.

They don't "return" the Translator but rather cause it to be created
when specified after \consists , like a Notehead_engraver instance is
created when specifying the string "Notehead_engraver".

Basically there is the _specification_, \consists looks up (or in your
example creates) a suitable translator creator given a specification.
This translator creator is called with a suitable context to actually
create a translator instance when a context is instantiated, and that
creator instance is what you see listed rather unspecifically as
#<Translator Scheme_engraver > or #<Engraver Notehead_engraver> or
whatever else (to get to see those, create a suitable Scheme engraver
and look at the "source-engraver" argument of one of your grob
acknowledgers).

One of the more problematic bits in history was making a
\consists/\removes pair work for ad-hoc defined engravers (rather than
those registered under a name) since at the time of the \removes call,
the translator creator did not carry information about its originating
expression (particularly so if its list expression was the result of
calling a lambda function) and creating a fresh translator creator from
the same expression led to a different translator creator unsuitable for
looking up the preexisting translator creator.

--
David Kastrup

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

Re: Automatically identify beats

Daniel Sales
In reply to this post by Thomas Morley-2
On 2018-10-07 8:29 a.m., Thomas Morley wrote:
>
> I disagree.
> "1 2 / 3 4 / 5 6" feels like 3/4. No matter what is actual printed.
>
> Even with Daniels manual coloring I disagree, more, the (not
> demonstrated) 5/8 can be done as 2-3 or 3-2, etc
>
> So I think one _must_ specify which colors are to be used and where.
Indeed, it seems there's no consensus on a fixed rule to apply for all
cases. The example wasn't really to define a mandatory coloring, but
just to show what I wanted to achieve by coloring beats differently :)

> Below my own attempt using an engraver (to have access to the
> 'timeSignatureFraction, a context-property, and to Stem/NoteHead-grobs
> in one go).
> The colors are stored/mapped in a predefined list. The newly defined
> context-property 'colorLikeTiming is set to this list. Making it
> user-adjustable where needed.
>
> Ofcourse there's wide room for improvements.
> One example: _Every_ TimeSignature will have a strong emphasis at
> first beat. Thus one could reflect this in the coding, currently
> you'll have to explicitely set colors on every beat you want.
> Or a better user-interface to adjust 'colorLikeTiming where needed.
> But I'm lazy today ... ;)
>
It was almost perfect, thanks a lot!. I just needed to make a few
changes and add some missing time signatures. Now that I see it working
I'm thinking that I should also add color to the corresponding
lyrics...but I'm also too lazy today ;)

Many thanks to Aaron as well.

Best Regards,
Daniel

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

Re: Automatically identify beats

Thomas Morley-2
In reply to this post by David Kastrup
Am So., 7. Okt. 2018 um 22:28 Uhr schrieb David Kastrup <[hidden email]>:

>
> Thomas Morley <[hidden email]> writes:
>
> > Am So., 7. Okt. 2018 um 18:00 Uhr schrieb David Kastrup <[hidden email]>:
> >>
> >> Thomas Morley <[hidden email]> writes:
> >>
> >> > If you have too much time, you may have a look at ‘scheme-engraver.ly’
> >> > from
> >> > http://lilypond.org/doc/v2.13/input/regression/collated-files.html The
> >> > newer file uses the great 'make-engraver'-macro (by David Kastrup).
> >> > Otoh, this macro hides an engraver _is_ a list (which is obvious, if
> >> > you look in the older file).
> >>
> >> An engraver is not a list, just like it isn't a string like
> >> "Note_engraver".  That's just how you _specify_ an engraver.  If it's a
> >> list, the Scheme_engraver type will be used for actually instantiating
> >> an engraver (which is bound to a particular context), initialized using
> >> the list contents.
> >
> > Hi David,
> >
> > I don't understand the subtleties.
> > Could you elaborate a bit using the examples below.
> >
> > testI =
> >   #(list
> >     (cons 'initialize
> >      (lambda (trans)
> >        (write trans))))
> >
> > testII =
> >   #(lambda (ctx) testI)
> >
> > \layout {
> >   \context {
> >     \Voice
> >     \consists #testI
> >     \consists #testII
> >   }
> > }
> >
> > { R1 }
> >
> > testI is a list, testII a procedure using testI.
> > Both return #<Translator Scheme_engraver >, though.
>
> They don't "return" the Translator but rather cause it to be created
> when specified after \consists , like a Notehead_engraver instance is
> created when specifying the string "Notehead_engraver".
>
> Basically there is the _specification_, \consists looks up (or in your
> example creates) a suitable translator creator given a specification.
> This translator creator is called with a suitable context to actually
> create a translator instance when a context is instantiated, and that
> creator instance is what you see listed rather unspecifically as
> #<Translator Scheme_engraver > or #<Engraver Notehead_engraver> or
> whatever else (to get to see those, create a suitable Scheme engraver
> and look at the "source-engraver" argument of one of your grob
> acknowledgers).
>
> One of the more problematic bits in history was making a
> \consists/\removes pair work for ad-hoc defined engravers (rather than
> those registered under a name) since at the time of the \removes call,
> the translator creator did not carry information about its originating
> expression (particularly so if its list expression was the result of
> calling a lambda function) and creating a fresh translator creator from
> the same expression led to a different translator creator unsuitable for
> looking up the preexisting translator creator.
>
> --
> David Kastrup

Hi David,

thanks a lot for your explanations.

I try to repeat/summarize in my own words:

Defining some code like #(define my-code ...) will not create a
translator, before \consists has done its work in some context.

But with (for example)
\layout {
  \context {
    \Voice
    \consists #my-code
  }
}
an unnamed and unregistered translator is created. Assumed 'my-code'
is suitable, ofcourse.

Below some musing.
Don't read unless you're very interested ;)

So the two codings below will not create any engraver.

testI =
  #(list
    (cons 'initialize
      (lambda (engraver)
        (newline)
        (pretty-print (list 'from-initialize: (cons 'engraver engraver)))))
    (cons 'acknowledgers
      (list
        (cons 'note-head-interface
          (lambda (engraver grob source-engraver)
            (pretty-print
              (list
                'from-acknowledgers:
                (cons 'engraver engraver)
                (cons 'source-engraver source-engraver))))))))

testII =
  #(lambda (ctx) testI)


But as soon as I do:
\layout {
  \context {
    \Voice
    \consists #testI
    \consists #testII
  }
}

Two translators are created.
Which can be checked with some code you once tailored for me
http://lilypond.1069038.n5.nabble.com/catching-layout-content-tc213339.html
Ofcourse adjusted to fit here, thanks again for it.

#(define all-Voice-translators
  (assoc
    'Voice
    (map
      (lambda (x)
        (if (ly:context-def? (cdr x))
            (cons (car x) (ly:context-def-lookup (cdr x) 'consists))
            x))
      (sort
        (ly:module->alist (ly:output-def-scope $defaultlayout))
        (lambda (p q) (symbol<? (car p) (car q)))))))
#(newline)
#(format #t "\nAll Voice-translator:\n~y"
  (cdr all-Voice-translators))

Though:
#(pretty-print (ly:get-all-translators))
doesn't show them.

Is this expected?

%%%%%
%%%%%

Things are different for registered translators:
#(ly:register-translator
 testI 'testI
 '((grobs-created . ())
   (events-accepted . ())
   (properties-read . ())
   (properties-written . ())
   (description . "")))

#(ly:register-translator
 testII 'testII
 '((grobs-created . ())
   (events-accepted . ())
   (properties-read . ())
   (properties-written . ())
   (description . "")))

Now (ly:get-all-translators) sees them as:
testII:
 #<procedure #f (ctx)>
testI:
 ((initialize . #<procedure #f (engraver)>)
  (acknowledgers
    (note-head-interface
      .
      #<procedure #f (engraver grob source-engraver)>)))

Their names can be found with
#(format #t "\nAll translator-names:\n~y"
  (sort
    (map ly:translator-name (ly:get-all-translators))
    symbol<?))

So _registering_ them makes testI/II translators, \consists may look them up.


Many thanks,
  Harm

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

Re: Automatically identify beats

David Kastrup
Thomas Morley <[hidden email]> writes:

> I try to repeat/summarize in my own words:
>
> Defining some code like #(define my-code ...) will not create a
> translator, before \consists has done its work in some context.
>
> But with (for example)
> \layout {
>   \context {
>     \Voice
>     \consists #my-code
>   }
> }
> an unnamed and unregistered translator is created.

Not really.  This creates a context definition, and the context
definition actually still contains the expression after \consists, a
string or a list or an anonymous function.

It's when the Translator_group (typically an Engraver_group) component
of a context is called upon initializing an actual context that a
context creator is looked up (if we have a string) or created from a
list or an anonymous function with a single context argument that
returns such a list.

The details for a Scheme_engraver changed over some iterations, but that
is how things happen these days.

> Assumed 'my-code' is suitable, ofcourse.
>
> Below some musing.
> Don't read unless you're very interested ;)
>
> So the two codings below will not create any engraver.
>
> testI =
>   #(list
>     (cons 'initialize
>       (lambda (engraver)
>         (newline)
>         (pretty-print (list 'from-initialize: (cons 'engraver engraver)))))
>     (cons 'acknowledgers
>       (list
>         (cons 'note-head-interface
>           (lambda (engraver grob source-engraver)
>             (pretty-print
>               (list
>                 'from-acknowledgers:
>                 (cons 'engraver engraver)
>                 (cons 'source-engraver source-engraver))))))))
>
> testII =
>   #(lambda (ctx) testI)
>
>
> But as soon as I do:
> \layout {
>   \context {
>     \Voice
>     \consists #testI
>     \consists #testII
>   }
> }
>
> Two translators are created.

Nope.  A layout definition is created (as a copy of $defaultlayout) and
contains a context definition internally containing testI and testII as
part of a series of context modifications.  But there is no translator
or translator creator or anything other than the original expressions in
it.

> Which can be checked with some code you once tailored for me
> http://lilypond.1069038.n5.nabble.com/catching-layout-content-tc213339.html
> Ofcourse adjusted to fit here, thanks again for it.
>
> #(define all-Voice-translators
>   (assoc
>     'Voice
>     (map
>       (lambda (x)
>         (if (ly:context-def? (cdr x))
>             (cons (car x) (ly:context-def-lookup (cdr x) 'consists))
>             x))
>       (sort
>         (ly:module->alist (ly:output-def-scope $defaultlayout))
>         (lambda (p q) (symbol<? (car p) (car q)))))))
> #(newline)
> #(format #t "\nAll Voice-translator:\n~y"
>   (cdr all-Voice-translators))
>
> Though:
> #(pretty-print (ly:get-all-translators))
> doesn't show them.
>
> Is this expected?

ly:get-all-translators gets the _globally_ registered translators, those
you can access with a _string_ as reference (should be a symbol,
really).

> So _registering_ them makes testI/II translators,

No, translator creators (which are functions called with a "context"
argument).  Some years ago, those were actual translators without a
working context and LilyPond created a copy when instantiating a context
and then and changed the context in the copy.  That scheme was not
suitable for registering Scheme-defined translators/engravers so it had
to be changed.

Since the implementation details changed under the hood in that time and
basically nobody was actually affected, most of those details are pretty
academical and are of interest basically to answer questions of the "but
how could this possibly work with user-defined engravers" kind.  That no
longer has the simple answer "badly".  Scheme_engraver is no longer
listed as an engraver (which it was in 2.16 or possibly even 2.18 or
so), and several individual Scheme-defined engravers _are_ listed (and
previously weren't).  Which is a consequence of changing "badly" into
"it's involved".

--
David Kastrup

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

Re: Automatically identify beats

Thomas Morley-2
Am Mo., 8. Okt. 2018 um 23:50 Uhr schrieb David Kastrup <[hidden email]>:

> ly:get-all-translators gets the _globally_ registered translators, those
> you can access with a _string_ as reference (should be a symbol,
> really).
>
> > So _registering_ them makes testI/II translators,
>
> No, translator creators (which are functions called with a "context"
> argument).  Some years ago, those were actual translators without a
> working context and LilyPond created a copy when instantiating a context
> and then and changed the context in the copy.  That scheme was not
> suitable for registering Scheme-defined translators/engravers so it had
> to be changed.

Well, I'm a little confused about translators and translator-creators
(I use the hyphen to make the wording more obvious).
Not the least reason is:
#(pretty-print (filter-map ly:translator? (ly:get-all-translators)))
returns '()

Could it be the changed implementation details were not really
reflected in the naming and description of those scheme-function
related to translators, i.e.: ly:translator-whatever
?

> Since the implementation details changed under the hood in that time and
> basically nobody was actually affected, most of those details are pretty
> academical and are of interest basically to answer questions of the "but
> how could this possibly work with user-defined engravers" kind.  That no
> longer has the simple answer "badly".  Scheme_engraver is no longer
> listed as an engraver (which it was in 2.16 or possibly even 2.18 or
> so), and several individual Scheme-defined engravers _are_ listed (and
> previously weren't).  Which is a consequence of changing "badly" into
> "it's involved".

Yeah...

> --
> David Kastrup

I'll (re)think/experiment more another day ...


Thanks,
  Harm

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

Re: Automatically identify beats

David Kastrup
Thomas Morley <[hidden email]> writes:

> Am Mo., 8. Okt. 2018 um 23:50 Uhr schrieb David Kastrup <[hidden email]>:
>
>> ly:get-all-translators gets the _globally_ registered translators, those
>> you can access with a _string_ as reference (should be a symbol,
>> really).
>>
>> > So _registering_ them makes testI/II translators,
>>
>> No, translator creators (which are functions called with a "context"
>> argument).  Some years ago, those were actual translators without a
>> working context and LilyPond created a copy when instantiating a context
>> and then and changed the context in the copy.  That scheme was not
>> suitable for registering Scheme-defined translators/engravers so it had
>> to be changed.
>
> Well, I'm a little confused about translators and translator-creators
> (I use the hyphen to make the wording more obvious).
> Not the least reason is:
> #(pretty-print (filter-map ly:translator? (ly:get-all-translators)))
> returns '()
>
> Could it be the changed implementation details were not really
> reflected in the naming and description of those scheme-function
> related to translators, i.e.: ly:translator-whatever
> ?

Yes, it could be.  The result would have been different in 2.18.

>> Since the implementation details changed under the hood in that time
>> and basically nobody was actually affected, most of those details are
>> pretty academical and are of interest basically to answer questions
>> of the "but how could this possibly work with user-defined engravers"
>> kind.  That no longer has the simple answer "badly".  Scheme_engraver
>> is no longer listed as an engraver (which it was in 2.16 or possibly
>> even 2.18 or so), and several individual Scheme-defined engravers
>> _are_ listed (and previously weren't).  Which is a consequence of
>> changing "badly" into "it's involved".
>
> Yeah...

It's probably been easier to understand.  But the Scheme used previously
just did not map sensibly to Scheme engravers: you could not possibly
have registered them, \consists/\removes was a pretty awkward mess, and
the list of engravers contained "Scheme_engraver" (which you could
actually \consist and get a real mess) but none of the Scheme engravers.

You now get:

dak@lola:/usr/local/tmp/lilypond$ lilypond scheme-sandbox
GNU LilyPond 2.21.0
Processing `/usr/local/share/lilypond/2.21.0/ly/scheme-sandbox.ly'
Parsing...
guile> (ly:get-all-translators)
(#<Translator_creator> #<procedure Measure_counter_engraver (context)>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<procedure Merge_rests_engraver (context)>
#<Translator_creator> #<Translator_creator> #<procedure
Span_stem_engraver (ctx)> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator> #<Translator_creator> #<Translator_creator>
#<Translator_creator>)
guile>

namely a bunch of Translator_creator s creating C++ engravers (maybe the
print expression should at least mention _which_ C++ engraver in order
to make them look less similar) and the procedures registered as
translator-creators.  Which don't really create translators but lists,
but at the point they are called, the list is then further converted to
an actual translator.  If you did not need a closure, you could register
a list in the first place (I think) and then _that_ would be used at the
time of lookup.

In 2.18, this looks like

dak@lola:/usr/local/tmp/lilypond$ /usr/bin/lilypond scheme-sandbox
GNU LilyPond 2.18.2
Processing `/usr/share/lilypond/2.18.2/ly/scheme-sandbox.ly'
Parsing...
guile> (ly:get-all-translators)
(#<Translator Control_track_performer > #<Translator
Drum_note_performer > #<Translator Key_performer > #<Translator
Output_property_engraver > #<Translator Timing_translator >
#<Translator Text_spanner_engraver > #<Translator
Multi_measure_rest_engraver > #<Translator Staff_performer >
#<Translator Pure_from_neighbor_engraver > #<Translator
Note_heads_engraver > #<Translator Span_bar_engraver > #<Translator
Tie_engraver > #<Translator Arpeggio_engraver > #<Translator
Chord_tremolo_engraver > #<Translator Text_engraver > #<Translator
Dynamic_performer > #<Translator Note_head_line_engraver > #<Translator
Cue_clef_engraver > #<Translator Span_bar_stub_engraver > #<Translator
Pitched_trill_engraver > #<Translator Paper_column_engraver >
#<Translator Note_performer > #<Translator Accidental_engraver >
#<Translator Grid_point_engraver > #<Translator Melody_engraver >
#<Translator Metronome_mark_engraver > #<Translator Bar_number_engraver
> #<Translator Hyphen_engraver > #<Translator Beam_performer >
#<Translator Breathing_sign_engraver > #<Translator
Piano_pedal_engraver > #<Translator Tuplet_engraver > #<Translator
Lyric_performer > #<Translator Script_engraver > #<Translator
Lyric_engraver > #<Translator Repeat_tie_engraver > #<Translator
Engraver > #<Translator Auto_beam_engraver > #<Translator
Repeat_acknowledge_engraver > #<Translator Staff_symbol_engraver >
#<Translator Fingering_column_engraver > #<Translator Beam_engraver >
#<Translator Dot_column_engraver > #<Translator
Ligature_bracket_engraver > #<Translator Tweak_engraver > #<Translator
Slur_engraver > #<Translator Separating_line_group_engraver >
#<Translator Horizontal_bracket_engraver > #<Translator
Page_turn_engraver > #<Translator Vaticana_ligature_engraver >
#<Translator Dynamic_engraver > #<Translator
Double_percent_repeat_engraver > #<Translator Axis_group_engraver >
#<Translator Tie_performer > #<Translator
System_start_delimiter_engraver > #<Translator Ambitus_engraver >
#<Translator Scheme_engraver > #<Translator Staff_collecting_engraver >
#<Translator Midi_control_function_performer > #<Translator
Part_combine_engraver > #<Translator Trill_spanner_engraver >
#<Translator Keep_alive_together_engraver > #<Translator
Stanza_number_align_engraver > #<Translator Balloon_engraver >
#<Translator Spacing_engraver > #<Translator
Spanner_break_forbid_engraver > #<Translator Script_column_engraver >
#<Translator Laissez_vibrer_engraver > #<Translator
Note_spacing_engraver > #<Translator Slur_performer > #<Translator
Tab_tie_follow_engraver > #<Translator Grid_line_span_engraver >
#<Translator Cluster_spanner_engraver > #<Translator Grob_pq_engraver >
#<Translator Fingering_engraver > #<Translator Stanza_number_engraver >
#<Translator Mark_engraver > #<Translator Grace_auto_beam_engraver >
#<Translator Ottava_spanner_engraver > #<Translator Chord_name_engraver
> #<Translator Grace_engraver > #<Translator Grace_beam_engraver >
#<Translator Note_name_engraver > #<Translator Rhythmic_column_engraver
> #<Translator Parenthesis_engraver > #<Translator Bend_engraver >
#<Translator Instrument_switch_engraver > #<Translator
Drum_notes_engraver > #<Translator Completion_heads_engraver >
#<Translator Bar_engraver > #<Translator Custos_engraver > #<Translator
Episema_engraver > #<Translator Piano_pedal_performer > #<Translator
Time_signature_performer > #<Translator Tempo_performer > #<Translator
Pitch_squash_engraver > #<Translator Kievan_ligature_engraver >
#<Translator Dynamic_align_engraver > #<Translator
New_fingering_engraver > #<Translator Clef_engraver > #<Translator
Figured_bass_engraver > #<Translator Slash_repeat_engraver >
#<Translator Stem_engraver > #<Translator Collision_engraver >
#<Translator Measure_grouping_engraver > #<Translator
Completion_rest_engraver > #<Translator Font_size_engraver >
#<Translator Instrument_name_engraver > #<Translator Volta_engraver >
#<Translator Rest_engraver > #<Translator Script_row_engraver >
#<Translator Glissando_engraver > #<Translator Span_arpeggio_engraver >
#<Translator Forbid_line_break_engraver > #<Translator
Concurrent_hairpin_engraver > #<Translator Break_align_engraver >
#<Translator Rest_collision_engraver > #<Translator Extender_engraver >
#<Translator Time_signature_engraver > #<Translator
Piano_pedal_align_engraver > #<Translator
Figured_bass_position_engraver > #<Translator Tab_staff_symbol_engraver
> #<Translator Tab_note_heads_engraver > #<Translator
Beam_collision_engraver > #<Translator Key_engraver > #<Translator
Vertical_align_engraver > #<Translator Fretboard_engraver >
#<Translator Footnote_engraver > #<Translator
Mensural_ligature_engraver > #<Translator Grace_spacing_engraver >
#<Translator Percent_repeat_engraver > #<Translator Dots_engraver >
#<Translator Default_bar_line_engraver > #<Translator
Phrasing_slur_engraver > #<Translator Ledger_line_engraver >
#<Translator Translator >)
guile>

You'll notice that there is a #<Translator Scheme_engraver > in there,
and (yuch!) a #<Translator Translator > (I have no idea what the latter
did).  Even a #<Translator Engraver > but no #<Translator Performer >.
Walk away slowly, make no sudden movements and avoid eye contact.

--
David Kastrup

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

Re: Automatically identify beats

David Kastrup
David Kastrup <[hidden email]> writes:

> namely a bunch of Translator_creator s creating C++ engravers (maybe the
> print expression should at least mention _which_ C++ engraver in order
> to make them look less similar)

which is actually pretty hard since the Translator_creator type is
identical for all C++ translators and is just instantiated with an
allocator function able to create the required type of C++ translator.
So basically all a Translator_creator instance can do is, well, create a
translator.  It has no other type-dependent information and I would not
want to create a translator when printing just so that I can look up its
name.

So 2.21 material.

--
David Kastrup

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

Re: Automatically identify beats

Thomas Morley-2
In reply to this post by David Kastrup
Am Di., 9. Okt. 2018 um 00:47 Uhr schrieb David Kastrup <[hidden email]>:
>
> Thomas Morley <[hidden email]> writes:
>
> > Well, I'm a little confused about translators and translator-creators
> > (I use the hyphen to make the wording more obvious).
> > Not the least reason is:
> > #(pretty-print (filter-map ly:translator? (ly:get-all-translators)))
> > returns '()

> In 2.18, this looks like
>
> dak@lola:/usr/local/tmp/lilypond$ /usr/bin/lilypond scheme-sandbox
> GNU LilyPond 2.18.2
> Processing `/usr/share/lilypond/2.18.2/ly/scheme-sandbox.ly'
> Parsing...
> guile> (ly:get-all-translators)
[...]
> You'll notice that there is a #<Translator Scheme_engraver > in there,
> and (yuch!) a #<Translator Translator > (I have no idea what the latter
> did).  Even a #<Translator Engraver > but no #<Translator Performer >.
> Walk away slowly, make no sudden movements and avoid eye contact.

ROFLMAO

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: Automatically identify beats

Thomas Morley-2
In reply to this post by David Kastrup
Am Di., 9. Okt. 2018 um 01:24 Uhr schrieb David Kastrup <[hidden email]>:

>
> David Kastrup <[hidden email]> writes:
>
> > namely a bunch of Translator_creator s creating C++ engravers (maybe the
> > print expression should at least mention _which_ C++ engraver in order
> > to make them look less similar)
>
> which is actually pretty hard since the Translator_creator type is
> identical for all C++ translators and is just instantiated with an
> allocator function able to create the required type of C++ translator.
> So basically all a Translator_creator instance can do is, well, create a
> translator.  It has no other type-dependent information and I would not
> want to create a translator when printing just so that I can look up its
> name.
>
> So 2.21 material.
>
> --
> David Kastrup

For the record.

From a users point of view, you can already use ly:translator-name.
(Works for all tested guile-versions)

~$ lilypond-git-guile-3.0 scheme-sandbox
GNU LilyPond 2.21.0
Processing `/home/hermann/lilypond-git-guile-3.0/build/out/share/lilypond/current/ly/scheme-sandbox.ly'
Parsing...
GNU Guile 2.9.1
Copyright (C) 1995-2017 Free Software Foundation, Inc.

Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.
This program is free software, and you are welcome to redistribute it
under certain conditions; type `,show c' for details.

Enter `,help' for help.
scheme@(#{ g166}#)> (format #t "\nAll translator-names:\n~y"
  (sort
    (map ly:translator-name (ly:get-all-translators))
    symbol<?))

All translator-names:
(Accidental_engraver
  Ambitus_engraver
  Arpeggio_engraver
  Auto_beam_engraver
  Axis_group_engraver
  Balloon_engraver
  Bar_engraver
  Bar_number_engraver
  Beam_collision_engraver
  Beam_engraver
  Beam_performer
  Bend_engraver
  Break_align_engraver
  Breathing_sign_engraver
  Chord_name_engraver
  Chord_tremolo_engraver
  Clef_engraver
  Cluster_spanner_engraver
  Collision_engraver
  Completion_heads_engraver
  Completion_rest_engraver
  Concurrent_hairpin_engraver
  Control_track_performer
  Cue_clef_engraver
  Custos_engraver
  Default_bar_line_engraver
  Dot_column_engraver
  Dots_engraver
  Double_percent_repeat_engraver
  Drum_note_performer
  Drum_notes_engraver
  Dynamic_align_engraver
  Dynamic_engraver
  Dynamic_performer
  Episema_engraver
  Extender_engraver
  Figured_bass_engraver
  Figured_bass_position_engraver
  Fingering_column_engraver
  Fingering_engraver
  Font_size_engraver
  Footnote_engraver
  Forbid_line_break_engraver
  Fretboard_engraver
  Glissando_engraver
  Grace_auto_beam_engraver
  Grace_beam_engraver
  Grace_engraver
  Grace_spacing_engraver
  Grid_line_span_engraver
  Grid_point_engraver
  Grob_pq_engraver
  Horizontal_bracket_engraver
  Hyphen_engraver
  Instrument_name_engraver
  Instrument_switch_engraver
  Keep_alive_together_engraver
  Key_engraver
  Key_performer
  Kievan_ligature_engraver
  Laissez_vibrer_engraver
  Ledger_line_engraver
  Ligature_bracket_engraver
  Lyric_engraver
  Lyric_performer
  Mark_engraver
  Measure_counter_engraver
  Measure_grouping_engraver
  Melody_engraver
  Mensural_ligature_engraver
  Merge_rests_engraver
  Metronome_mark_engraver
  Midi_control_change_performer
  Multi_measure_rest_engraver
  New_fingering_engraver
  Note_head_line_engraver
  Note_heads_engraver
  Note_name_engraver
  Note_performer
  Note_spacing_engraver
  Ottava_spanner_engraver
  Output_property_engraver
  Page_turn_engraver
  Paper_column_engraver
  Parenthesis_engraver
  Part_combine_engraver
  Percent_repeat_engraver
  Phrasing_slur_engraver
  Piano_pedal_align_engraver
  Piano_pedal_engraver
  Piano_pedal_performer
  Pitch_squash_engraver
  Pitched_trill_engraver
  Pure_from_neighbor_engraver
  Repeat_acknowledge_engraver
  Repeat_tie_engraver
  Rest_collision_engraver
  Rest_engraver
  Rhythmic_column_engraver
  Script_column_engraver
  Script_engraver
  Script_row_engraver
  Separating_line_group_engraver
  Slash_repeat_engraver
  Slur_engraver
  Slur_performer
  Spacing_engraver
  Span_arpeggio_engraver
  Span_bar_engraver
  Span_bar_stub_engraver
  Span_stem_engraver
  Spanner_break_forbid_engraver
  Staff_collecting_engraver
  Staff_performer
  Staff_symbol_engraver
  Stanza_number_align_engraver
  Stanza_number_engraver
  Stem_engraver
  System_start_delimiter_engraver
  Tab_note_heads_engraver
  Tab_staff_symbol_engraver
  Tab_tie_follow_engraver
  Tempo_performer
  Text_engraver
  Text_spanner_engraver
  Tie_engraver
  Tie_performer
  Time_signature_engraver
  Time_signature_performer
  Timing_translator
  Trill_spanner_engraver
  Tuplet_engraver
  Tweak_engraver
  Vaticana_ligature_engraver
  Vertical_align_engraver
  Volta_engraver)

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: Automatically identify beats

David Kastrup
Thomas Morley <[hidden email]> writes:

> Am Di., 9. Okt. 2018 um 01:24 Uhr schrieb David Kastrup <[hidden email]>:
>>
>> David Kastrup <[hidden email]> writes:
>>
>> > namely a bunch of Translator_creator s creating C++ engravers (maybe the
>> > print expression should at least mention _which_ C++ engraver in order
>> > to make them look less similar)
>>
>> which is actually pretty hard since the Translator_creator type is
>> identical for all C++ translators and is just instantiated with an
>> allocator function able to create the required type of C++ translator.
>> So basically all a Translator_creator instance can do is, well, create a
>> translator.  It has no other type-dependent information and I would not
>> want to create a translator when printing just so that I can look up its
>> name.
>>
>> So 2.21 material.
>>
>> --
>> David Kastrup
>
> For the record.
>
>>From a users point of view, you can already use ly:translator-name.
> (Works for all tested guile-versions)

Oh.  Well, that's for registered translator creators, apparently.  That
would imply that ly:translator-name no longer works for actual
translators, just for registered translator creators.

I think that this may be a regression as compared to previous behavior
where you could get the name of an actual translator (the first argument
of most engraver callbacks).

More involved than I remembered.

--
David Kastrup

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

Re: Automatically identify beats

Thomas Morley-2
Am Do., 25. Okt. 2018 um 14:30 Uhr schrieb David Kastrup <[hidden email]>:

>
> Thomas Morley <[hidden email]> writes:
>
> > Am Di., 9. Okt. 2018 um 01:24 Uhr schrieb David Kastrup <[hidden email]>:
> >>
> >> David Kastrup <[hidden email]> writes:
> >>
> >> > namely a bunch of Translator_creator s creating C++ engravers (maybe the
> >> > print expression should at least mention _which_ C++ engraver in order
> >> > to make them look less similar)
> >>
> >> which is actually pretty hard since the Translator_creator type is
> >> identical for all C++ translators and is just instantiated with an
> >> allocator function able to create the required type of C++ translator.
> >> So basically all a Translator_creator instance can do is, well, create a
> >> translator.  It has no other type-dependent information and I would not
> >> want to create a translator when printing just so that I can look up its
> >> name.
> >>
> >> So 2.21 material.
> >>
> >> --
> >> David Kastrup
> >
> > For the record.
> >
> >>From a users point of view, you can already use ly:translator-name.
> > (Works for all tested guile-versions)
>
> Oh.  Well, that's for registered translator creators, apparently.  That
> would imply that ly:translator-name no longer works for actual
> translators, just for registered translator creators.
>
> I think that this may be a regression as compared to previous behavior
> where you could get the name of an actual translator (the first argument
> of most engraver callbacks).
>
> More involved than I remembered.
>
> --
> David Kastrup

Hi David,

nothing new, merely to confirm:

I checked several ly-versions (since 2.8.0) with

#(let*  ((all-trans (ly:get-all-translators))
         (first-three (take all-trans 3)))
(format #t
"\n\nLilyPond-version:\n\t~a
First three from (ly:get-all-translators):\n\t~a
Check with ly:translator?:\n\t~a
Their names from ly:translator-name:\n\t~a"
  (lilypond-version)
  first-three
  (map ly:translator? first-three)
  (map ly:translator-name first-three)))

The results differ somewhere after 2.18.2:

LilyPond-version:
    2.18.2
First three from (ly:get-all-translators):
    (#<Translator Dynamic_align_engraver > #<Translator
Custos_engraver > #<Translator Cluster_spanner_engraver >)
Check with ly:translator?:
    (#t #t #t)
Their names from ly:translator-name:
    (Dynamic_align_engraver Custos_engraver Cluster_spanner_engraver)

LilyPond-version:
    2.19.82
First three from (ly:get-all-translators):
    (#<Translator_creator> #<Translator_creator> #<Translator_creator>)
Check with ly:translator?:
    (#f #f #f)
Their names from ly:translator-name:
    (Bend_engraver Grace_beam_engraver Figured_bass_position_engraver)

Cheers,
  Harm

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