lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Custom scheme engraver (Barline) problem


From: Jean Abou Samra
Subject: Re: Custom scheme engraver (Barline) problem
Date: Mon, 25 Jul 2022 08:50:18 +0200



Le 25 juil. 2022 à 08:23, Kyle Baldwin <g.pit.kyle@gmail.com> a écrit :


I'm trying to create a custom bar number engraver that will respond to couple of different events, but wanted to initially try and clone the Bar number engraver in c to scheme. Everything seems to work the way I want it to, except for the positioning seems to be wrong. The numbers appear in line with the top staff as opposed to above the top staff. 

If someone can help me get these numbers into the "correct" place, it would be greatly appreciated. I think that it may have something to do with the side-support not working correctly, but not sure why. 

Thanks 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#(define (Bar_number_ten_engraver context)
  ; main let 
  (let*
    ; main let defs  
    (
      ; we need two variables to hold information about current bar number grobs.  
      ; The bar-text is for regular bar numbers and the bar-span is for spanning 
      ; bar number - i.e., "centered" bar numbers. Default values we can just 
      ; mark as empty lists to make error checking easier. (with null?)
      (bar-text '())
      (bar-span '())
      ; The next set of variables are just used for internal state. 
      (considered-numbering #f) ; flag to mark if we have already processed this barline 
      (saw-bar-line #t)         ; flag to set when we see a barline. This makes it 
                                ; so the same barline isn't processed multiple times. 
                                ; although the first barline will never have a number, 
                                ; this should run the check to get things started 
      (break-allowed-now #f)    ; store the value read in process-music. This is 
                                ; explained in the default bar number engraved to 
                                ; to avoid engraver order dependance. 
      ; there are the "class" helper functions
      ; this will get the alternate bar number to send to the bar number formatter 
      (get-alt-number (lambda (ctx) 
        (let 
          (
            (alt-number (ly:context-property ctx 'alternativeNumber 0))
            (numbering-style (ly:context-property ctx 'alternativeNumberingStyle)))
          ; if alt-number > 0 and numbering-style != 'numbers-with-letters
          (if 
            (and 
              (> alt-number 0) 
              (not (eqv? numbering-style 'numbers-with-letters)))
            0
            alt-number))))
      ; this function either creates the actual bar number if a simple grob (smob)
      ; or starts the spanner if using centered bar numbers. 
      (create-bar-number (lambda (engr ctx txt)
        (let
          (
            (are-centered-bars (ly:context-property ctx 'centerBarNumbers #f)))
          (if (eqv? are-centered-bars #t)
            ; if we're using centered bar numbers 
            (begin  
                (set! bar-span (ly:engraver-make-grob engr 'CenteredBarNumber '()))
                (ly:spanner-set-bound! bar-span LEFT (ly:context-property ctx 'currentCommandColumn))
                (ly:grob-set-property! bar-span 'text txt)
            )
            ; regular bar numbers 
            (begin 
                (set! bar-text (ly:engraver-make-grob engr 'BarNumber '()))
                (ly:grob-set-property! bar-text 'text txt)
            )))))
      (consider-creating-bar-number (lambda (engr ctx) 
        (format #t "Considering creating bar number...~%") 
        ; note that we considered a bar number here 
        (set! considered-numbering #t)
        
        ; if there is a center bar number pending, close it out now as we are now 
        ; at the next bar line
        (when (ly:grob? bar-span) ( 
            ; set right (end) column 
            (ly:spanner-set-bound! bar-span RIGHT (ly:context-property ctx 'currentCommandColumn))
            ; announce 
            (ly:engraver-announce-end-grob engr bar-span '())
            ; reset bar-span 
            (set! bar-span '()))         
        ) ; end close bar span block 

        ; actual bar number consider logic 
        (let (
          (cur-bar (ly:context-property ctx 'currentBarNumber))
          (measure-pos (ly:context-property ctx 'measurePosition (ly:make-moment 0)))
          ; bar number formatter 
          (formatter (ly:context-property ctx 'barNumberFormatter))
        )
          ; if bar num mod 10 = 0, then we can put a bar number here 
          (when 
            (eqv? (modulo cur-bar 10) 0) 
            (create-bar-number 
              engr 
              ctx 
              (formatter 
                cur-bar 
                measure-pos 
                (- (get-alt-number ctx) 1)
                ctx)))))))
    ; main let body 
    (make-engraver
      (acknowledgers 
        (
          (bar-line-interface engraver grob source-engraver)
          (begin 
            (format #t "Acknowledged barline.~%")
            (set! saw-bar-line #t)
          )
        )
      )
      ((process-acknowledged engraver)
        (begin
          ; if we saw a barline and we haven't considered numbering here yet...  
          (if 
            (and saw-bar-line (not considered-numbering))
            (consider-creating-bar-number engraver context)
            (format #t "INFO: not considering bar number (process-acknowledged)~%")
          )
        )
      )
      ((process-music engraver)
        (let*
          (
            (forbid-break (ly:context-property context 'forbidBreak #f))
            (force-break (ly:context-property context 'forceBreak #f))
            ; break is allow if force break is true or forbid break is false 
            (break-allowed (or force-break (not forbid-break)))
            ; check if we have centered bar numbers or not 
            (centered-bar-numbers (ly:context-property context 'centerBarNumbers #f))
          ) 
          (begin  
            (display "Processing music in engraver...")
            (newline)
            (format #t "forbid-break: ~a; force-break: ~a; break-allowed: ~a~%" forbid-break force-break break-allowed)
            ; set break allowed because we can't read this in other places properly 
            (set! break-allowed-now break-allowed)
            ; if we have a break allowed, consider making a bar number here 
            (if 
              (and break-allowed (not centered-bar-numbers))
              (consider-creating-bar-number engraver context)
              (format #t "INFO: not considering bar number (process music)~%")
            )
          )
        )
      )
      ((stop-translation-timestep engraver) 
        ; if we have text to write, place it in the correct place 
        (when (not (null? bar-text)) 
          (let* 
            (
              (staves-found (ly:context-property context 'stavesFound))
              (support-array (ly:grob-list->grob-array staves-found))
            )
            ; set support for bar number  
            (ly:grob-set-property! bar-text 'side-support-elements support-array)



I can’t comment extensively right now (maybe someone else can), but try ly:grob-set-object! here, and see https://extending-lilypond.readthedocs.io/en/latest/backend.html#grob-pointers about the difference.

Best,
Jean



            ; set break vis for the object 
            (when 
              (and 
                break-allowed-now
                (not saw-bar-line)
                (not (ly:context-property context 'centerBarNumbers)))

              (let 
                ((bk-vis (ly:grob-property bar-text 'break-visibility)))
                ; do some vector checking for break-vis 
                (if 
                  ; if break-vis is not a vector, force it to be a vector 
                  (eqv? (not (vector? bk-vis)) #t)
                  (set! bk-vis #(#t #t #t))
                  ; not sure if this needs to be a copy, but it is in the C code 
                  (set! bk-vis (vector-copy bk-vis)) 
                )

                (vector-set! bk-vis 1 #f)
                (ly:grob-set-property! bar-text 'break-visibility bk-vis)
              )  
            )
            
            (set! bar-text '())
          )
        )
        (set! considered-numbering #f)
        (set! saw-bar-line #f)
      )
    
  ) ; end main let body / make engraver
) ; end main let 
) % End Bar_number_ten_engraver 



\score {
      \new Staff {
        \repeat unfold 10 { R1 R1 R1 R1 R1 R1 R1 R1 R1 \break R1  }
      } 
    
   
    
    \layout {
        \context {
            \Score
            \remove "Bar_number_engraver"
            \consists #Bar_number_ten_engraver
        }
    }
}




\version "2.23.8"
%%%%%%%%%%%%%%%%%%%%%

-kwb

reply via email to

[Prev in Thread] Current Thread [Next in Thread]