lilypond-user
[Top][All Lists]
Advanced

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

Re: Custom footers


From: Thomas Morley
Subject: Re: Custom footers
Date: Thu, 21 Mar 2013 02:47:03 +0100

2013/3/20 Marc Hohl <address@hidden>:
> Am 20.03.2013 19:19, schrieb Jérôme Plût:
>
>> Decimo tertio Kalendas Apriles MMXIII scripsit Thomas Morley :
>>>
>>> in the code below you'll see increasing page-numbers throughout the
>>> book as usual.
>>
>>
>> Ooh, now that I have had the time to read your code, I see what you
>> did, and I like it. The \on-the-fly side-effect is devious (and
>> un-Scheme-like, but who cares). Thanks!
>>
>>> Though, I didn't manage to code "(1/3)" for consecutive bookparts,
>>> because I didn't understand how to get or calculate the
>>> bookpart-last-page-number.
>>
>>
>> The simplest way to do it would be the TeX way: saving the page count
>> for each section in a .aux file and reading this again on second
>> compilation. Unless, of course, the (open) Scheme function is disabled
>> in Lilypond. I will have a try at this.
>>
> Sorry for chiming in so late, but perhaps
>
> http://lists.gnu.org/archive/html/lilypond-user/2013-01/msg00812.html
>
> gives some ideas? You could use \label for defining where a part starts
> and get the page number for this page. With these informations
> calculating the offset/number of pages per part seems to be
> straightforward ;-)
>
> HTH,
>
> Marc

Hi Marc,

I don't think it is that straightforward.
The problem is that one would want to print only that labeled
page-number which ends the bookparts.
It's not that easy to detemine what to print.

Below a first approach.
Several comments are inserted to explain drawbacks and how to make it
work with 2.12.3

I'd really prefer to directly read out the last bookpart-page-number somehow.
Any hint would be great.

Though, here the present code:


\version "2.16.2"
%\version "2.12.3"

#(define (looking-up layout props symbol)
   (define (ancestor layout)
     "Return the topmost layout ancestor"
     (let ((parent (ly:output-def-parent layout)))
       (if (not (ly:output-def? parent))
           layout
           (ancestor parent))))
   (ly:output-def-lookup (ancestor layout) symbol))

#(define (book-second-page? layout props)
   "Return #t iff the current page number, got from @code{props}, is the
    book second one."
   (= (chain-assoc-get 'page:page-number props -1)
      (+ (looking-up layout props 'first-page-number) 1)))

#(define (not-second-page layout props arg)
   (if (not (book-second-page? layout props))
       (interpret-markup layout props arg)
       empty-stencil))

#(define (print-bookpart-numbers layout props arg)
   (let* ((book-page-number
            (chain-assoc-get 'page:page-number props -1))
          (bookpart-first-page-number
            (ly:output-def-lookup layout 'first-page-number))
          (book-part-numbers
            (number->string (- book-page-number bookpart-first-page-number -1)))
          (book-part-number-markup
            (markup book-part-numbers)))
      (interpret-markup layout props book-part-number-markup)))

#(define (get-equal-or-greater n l)
 "Return the first element of list, which is greater than n.
  l is supposed to be an ordered list of numbers."
  (if (null? l)
      0
      (if (< n (car l))
          (car l)
          (get-equal-or-greater n (cdr l)))))

%% Inserted to make it work with 2.12.3
#(define-markup-command (vspace layout props amount)
  (number?)
  "Create an invisible object taking up vertical space
   of @var{amount} multiplied by 3."
   (let ((amount (* amount 3.0)))
     (ly:make-stencil "" (cons 0 0) (cons 0 amount))))

#(define-markup-command
  (print-bookpart-last-page layout props label gauge default)
  (symbol? markup? markup?)
  "
  Depends on correctly set @code{\\label} command.
  @code{\\tocItem} is not disturbed, though, other settings of @code{\\label}
  will give unwanted results.

  Reference to a page number.  @var{label} is the label set on the referenced
  page (using the @code{\\label} command), @var{gauge} a markup used to estimate
  the maximum width of the page number, and @var{default} the value to display
  when @var{label} is not found."
  (let* ((gauge-stencil (interpret-markup layout props gauge))
         (x-ext (ly:stencil-extent gauge-stencil X))
         (y-ext (ly:stencil-extent gauge-stencil Y)))
    (ly:make-stencil
     `(delay-stencil-evaluation
       ,(delay (ly:stencil-expr
                 (let* ((table (ly:output-def-lookup layout 'label-page-table))
                        (label-page-number-list
                           (sort (map (lambda (x) (cdr x)) table) <))
                        (part-first-page-number
                           (ly:output-def-lookup layout 'first-page-number))
                        ;; get the first, labeled page-number greater than
                        ;; part-first-page-number.
                        ;; Will be disturbed if additional labels are used.
                        ;; TODO better method
                        (greater-than-part-first-page-number
                           (if (null? label-page-number-list)
                              0
                              (get-equal-or-greater
                                 part-first-page-number
                                 label-page-number-list)))
                        (bookpart-last-page-number
                           (- greater-than-part-first-page-number
                              part-first-page-number -1))
                        (page-number (if (list? table)
                                         (assoc-get label table)
                                         #f))
                        (page-markup
                           (if page-number
                               (format #f "~a" bookpart-last-page-number)
                               default))
                        (page-stencil
                           (interpret-markup layout props page-markup))
                        (gap (- (interval-length x-ext)
                                (interval-length
                                   (ly:stencil-extent page-stencil X)))))

                   (if (null? table)
                       (ly:warning "\\label not set?"))
                   (interpret-markup layout props
                     (markup #:concat (#:hspace gap page-markup)))))))
     x-ext
     y-ext)))


\paper {
  %% works with different settings of `first-page-number´
  %% currently the default is set
  first-page-number = 1

  %% For now page-header are set #f
  oddHeaderMarkup = ##f
  evenHeaderMarkup = ##f

  oddFooterMarkup = \markup {
    %% Don't print on first and second book-page
    \on-the-fly #not-first-page
    \on-the-fly #not-second-page
    \column {
      \fill-line {
        \fromproperty #'header:title
        \fontsize #2 \italic \fromproperty #'header:instrument
        %% \parenthesize or \bracket. Choose one.
        %% \parenthesize will not work here with 2.12.3
        %% Perhaps use "(" <arg> ")"
        \parenthesize
        %\bracket
        \concat {
                \fromproperty #'header:instrument
                "-part, page "
                %% "" needs to be here! because
                %% \on-the-fly expects _two_ arguments.
                \on-the-fly #print-bookpart-numbers ""
                "/"
                %% Using "X" will cause collisions with the bracket, if the
                %% page-number to print is greater than 9.
                %% Using "XX" will cause unwanted white space, if the page-
                %% number is smaller than 10.
                %% No clue how to solve this.
                \print-bookpart-last-page #'end-bookpart "X" "?"
        }
      }
      \fill-line {
              \concat {
                      "- page "
                      \fromproperty #'page:page-number-string
                      " -"
              }
      }
    }
  }
}

\book {
  \bookpart {
          \markup \column {
                \vspace #8
               \fill-line { \fontsize #12 "Music" }
               \vspace #30

               \fill-line { \override #'(span-factor . 1/3) \draw-hline }
               %% \draw-hline is not defined in "2.12.3".
               %% Use next line instead.
               %\fill-line { \postscript #"-20 0 moveto 40 0 rlineto stroke" }

               \vspace #4
               \fill-line {
                       \fontsize #1
                       \center-column {
                               "edited"
                               "by"
                               "me"
                       }
               }
          }
  }
  \bookpart {
          \markuplist \table-of-contents
          %% With 2.12.3 use:
          %\markuplines \table-of-contents
  }
  \bookpart {
          \tocItem \markup "First Piece"
          %% header on bookpart-top-level.
          %% Otherwise instrument-setting isn't recognized
          %% by page-headers/footers
          \header {
                  title = "First Piece"
                  instrument = "Trombone"
          }
          \score {
            \new Staff {
                  \repeat unfold 2 { c''1 \pageBreak } c''
            }
          }
          \label #'end-bookpart
          %% needs to be here, otherwise \label sometimes doesnt work.
          \markup \null
  }
  \bookpart {
          \tocItem \markup "Second Piece"
          \header {
                  title = "Second Piece"
                  instrument = "Saxophone"
          }
          \score {
            \new Staff {
                  \repeat unfold 3 { cis''1 \pageBreak } cis''
            }
          }
          \label #'end-bookpart
          \markup \null
  }
  \bookpart {
          \tocItem \markup "Third Piece"
          \header {
                  title = "Third Piece"
                  instrument = "Saxophone"
          }
          \score {
            \new Staff {
                  \repeat unfold 2 { d''1 \pageBreak } d''
            }
          }
          \label #'end-bookpart
          \markup \null
  }
  \bookpart {
          \tocItem \markup "Fourth Piece"
          \header {
                  title = "Fourth Piece"
                  instrument = "Saxophone"
          }
          \score {
            \new Staff {
                  \repeat unfold 6 { dis''1 \pageBreak } dis''
            }
          }
          \label #'end-bookpart
          \markup \null
  }
}


Cheers,
  Harm



reply via email to

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