lilypond-user
[Top][All Lists]
Advanced

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

Re: Ask about the typesetting of Lilypond


From: David Kastrup
Subject: Re: Ask about the typesetting of Lilypond
Date: Thu, 16 Jun 2016 16:29:36 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/25.1.50 (gnu/linux)

Andrew Bernard <address@hidden> writes:

> Hi bb and OP,
>
> To be fair, the question is ambigous, and has two answers. He may be asking
> not simply how to break a line at a given location, but rather how to
> specify a certain numbers of bars per line - the latter not something that
> is obvious or simple in lilypond at all, and yet very frequently desired.
>
> The Lilypond Snippet Repository provides a solution to specifying a set
> number of bars per line in example LSR 838 - and non-trivial it is indeed.

Here is a variant with slightly nicer input syntax and several utility
functions that should likely be in LilyPond proper.

It requires a fairly recent version of LilyPond however.

\version "2.19.39"

#(define (index-list? x)
   (and (list? x)
        (every index? x)))

#(define (index-pattern numbers)
   "Convert an `index pattern' into a circular list.  Zeros are removed,
with the last zero preceding the part of the list that should become
circular.  If that list part is empty, the resulting list has no circular
end.  Without any zero, the whole list is turned into a circular one."
   (define (creverse! x y)
     "Reverse both x and y, make y circular and append to x."
     (if (pair? y)
         (let* ((rev-y (reverse! y))
                (rev-x (reverse! x rev-y)))
           (set-cdr! y rev-y)
           rev-x)
         (reverse! x y)))
   (let loop ((non-reps '()) (reps '()) (rest numbers))
     (cond ((null? rest) (creverse! non-reps reps))
           ((zero? (car rest))
            (loop (append! reps non-reps) '() (cdr rest)))
           ((index? (car rest))
            (loop non-reps (cons (car rest) reps) (cdr rest)))
           (else (ly:input-warning (*location*)
                                   (_ "Not an index: ~a") (car rest))
                 (loop non-reps reps (cdr numbers))))))
   

bar-keeper =
#(define-scheme-function ((numbers) c) (index-list?)
   "Create a Timing-level engraver breaking after the number of bars
specified in the list.  If the list is exhausted, it starts over
from the start or after a 0 marker contained in the list.  If the list
@emph{ends} address@hidden, line breaking reverts to normal at this point."
   (set! numbers (index-pattern numbers))
   (let ((target #f))
     (make-engraver
      (acknowledgers
       ((paper-column-interface eng grob from)
        (and (pair? numbers)
             (ly:grob-property grob 'non-musical #f)
             (let ((bar (ly:context-property (ly:translator-context eng)
                                             'internalBarNumber)))
               (if (not target)
                   (set! target bar)
                   (set! (ly:grob-property grob 'line-break-permission)
                         (and (>= bar (+ target (car numbers)))
                              (begin
                                (set! target (+ target (car numbers)))
                                (set! numbers (cdr numbers))
                                'force)))))))))))

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% EXAMPLE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

myMusic = \relative c' {
  \repeat unfold 4 {
    \time 5/4
    \acciaccatura { e16 d }
    c4 c c c c
    \time 3/4
    \acciaccatura { e16 d }
    c4 c c
    \time 3/2
    \acciaccatura { e16 d }
    c2 c c
  }
}

\score {
  \new Score \with { \consists \bar-keeper 4 }
  \new Staff { 
    \once\override Score.RehearsalMark.self-alignment-X = #LEFT
    \mark\markup\small\italic "4 measures per line:"
    \myMusic 
  }
}

\score {
  \new Score \with { \consists \bar-keeper 6 }
  \new Staff { 
    \once \override Score.RehearsalMark.self-alignment-X = #LEFT
    \mark\markup\small\italic "6 measures per line:"
    \myMusic 
  }
}

\score {
  \new Score \with { \consists \bar-keeper 1,3,0,4 }
    \new Staff { 
    \once \override Score.RehearsalMark.self-alignment-X = #LEFT
    \mark\markup\small\italic "1,3, finally 4 measures per line:"
    \myMusic 
  }
}

\score {
  \new Score \with { \consists \bar-keeper 1,3,0 }
    \new Staff { 
    \once \override Score.RehearsalMark.self-alignment-X = #LEFT
    \mark\markup\small\italic "1,3 measures per line, finally natural"
    \myMusic 
  }
}

-- 
David Kastrup

reply via email to

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