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 20:39:18 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/25.1.50 (gnu/linux)

David Kastrup <address@hidden> writes:

> 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.

Here is a version with slightly nicer use syntax because \bar-keeper
does not return an engraver here but rather a context modification.

\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 rest))))))
   

bar-keeper =
#(define-scheme-function (numbers) (index-list?)
   "Create a context mod for consisting a Timing-level engraver
breaking after bar group lengths specified in the list.  If the list
is exhausted, it starts over from the start or from after a 0 marker
contained in the list.  If the list @emph{ends} address@hidden, line
breaking reverts to normal after using up the list."
   (ly:make-context-mod
    `((consists
       ,(lambda (c)
          (let ((target #f) (numbers (index-pattern numbers)))
            (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 \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 \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 \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 \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]