lilypond-user
[Top][All Lists]
Advanced

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

Re: Changing Header Mid-Score


From: Jacques Menu
Subject: Re: Changing Header Mid-Score
Date: Sun, 11 Dec 2022 10:32:36 +0100

Thumbs up, Jean, this is worth being in the LPNR!

JM

Le 11 déc. 2022 à 04:05, brin solomon <amphion13@gmail.com> a écrit :



On Sat, Dec 10, 2022 at 6:09 AM Jean Abou Samra <jean@abou-samra.fr> wrote:
Le 09/12/2022 à 23:04, Kieren MacMillan a écrit :
> As far as I know:
> 1. a separate bookpart is required to change the properties that the titling mechanism can read; and
> 2. a bookpart will always force a page break.
>
> Cue Jean providing code to contradict my claim in 3… 2… 1…  ;)


[Although 2.23 is the unstable release series, the stable
release 2.24 is going to come out of it very soon, so I
will stick with it.]


For a start, you can use \if \on-page #2 to print some
text only on page 2, so you could get along manually with

   \if \on-page #1 ...
   \if \on-page #2 ...
   ...


Doing that automatically is ... not exactly straightforward,
but possible too.


\version "2.23.82"

sceneMark = \tweak details.is-scene-mark ##t \textMark \etc

\layout {
   \context {
     \Score
     \consists
       #(lambda (context)
          (let ((scene-text ""))
            (make-engraver
             (acknowledgers
              ((text-mark-interface engraver grob source-engraver)
               (when (assq-ref (ly:grob-property grob 'details)
                               'is-scene-mark)
                 (set! scene-text (ly:grob-property grob 'text)))))
             ((stop-translation-timestep engraver)
              (let ((col (ly:context-property context
'currentCommandColumn)))
                (ly:grob-set-nested-property!
                 col
                 '(details scene-text)
                 scene-text))))))
   }
}

#(define-markup-command (scene-text layout props gauge) (markup?)
    (let ((page-number (chain-assoc-get 'page:page-number props))
          (gauge-stil (interpret-markup layout props gauge)))
      (ly:make-stencil
       `(delay-stencil-evaluation
         ,(delay
           (ly:stencil-expr
            (interpret-markup
             layout
             props
             (hashv-ref (ly:output-def-lookup layout
'page-number-scene-text-table)
                        page-number)))))
       (ly:stencil-extent gauge-stil X)
       (ly:stencil-extent gauge-stil Y))))

\paper {
   oddHeaderMarkup = \markup
   \fill-line {
     ""
     \unless \on-first-page-of-part \fontsize #2 \concat {
       \fromproperty #'header:title
       ": "
       %% The argument to \scene-text is used to approximate the dimensions
       %% of the final text.
       \scene-text "Act X, Scene X"
     }
     \if \should-print-page-number \fromproperty #'page:page-number-string
   }
   evenHeaderMarkup = \markup
   \fill-line {
     \if \should-print-page-number \fromproperty #'page:page-number-string
     \unless \on-first-page-of-part \fontsize #2 \concat {
       \fromproperty #'header:title
       ": "
       \scene-text "Act X, Scene X"
     }
     ""
   }
   #(use-modules (srfi srfi-1))
   page-post-process =
     #(lambda (paper pages)
        (for-each
         (lambda (page)
           (let* ((page-number (ly:prob-property page 'page-number))
                  (lines (ly:prob-property page 'lines))
                  (table (or (ly:output-def-lookup paper
'page-number-scene-text-table #f)
                             (let ((table (make-hash-table)))
                               (ly:output-def-set-variable! paper
'page-number-scene-text-table table)
                               table)))
                  (first-system
                   (any (lambda (line)
                          (ly:prob-property line 'system-grob #f))
                        lines))
                  (scene-text
                   (if first-system
                       (let ((first-column (ly:spanner-bound
first-system LEFT)))
                         (assq-ref (ly:grob-property first-column 'details)
                                   'scene-text))
                       "")))
             (hashv-set! table page-number scene-text)))
         pages))
}


%%%%%%% EXAMPLE

\header {
   title = "Silly Opera"
}

{
   \sceneMark "Act I, Scene i"
   c'1 1 1
   \pageBreak
   c'1 1 1
   \pageBreak
   c'1 1 \sceneMark "Act I, Scene ii" 1
   \pageBreak
   c'1 1 1
}




Cheers,
Jean


Hi Jean,

Wow, this is really phenomenal! Thank you so much for this code! This should work perfectly for what I need.

Many many thanks,
brin


reply via email to

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