Jump to content

Transposing pitched rests

From LilyPond wiki
Revision as of 22:36, 26 October 2025 by Jean Abou Samra (talk | contribs) (Import snippet from LSR)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

If pitched rests (entered with \rest) are transposed, the \fixRests helper function ensures that rests are not positioned on staff lines

\version "2.24.0"

%% This code was originally written by Benkő Pál.
%%
%% Taken from
%%
%% https://gitlab.com/lilypond/lilypond/-/issues/2249#note_339764389

#(define (round-pitch p)
   "Move a rest half a space down if not on a line.

This is needed when transposing."
   (let* ((o (ly:pitch-octave p))
          (n (ly:pitch-notename p))
          (m (* (floor (/ (+ (* 7 o) n) 2)) 2))
          (a (remainder m 7))
          (b (/ (- m a) 7)))
     (ly:make-pitch b a 0)))

#(define (fix-rests music)
   "Prepare a single pitched rest for transposition."
   (let ((n (ly:music-property music 'name))
         (p (ly:music-property music 'pitch)))
     (if (and (ly:pitch? p) (eqv? n 'RestEvent))
         (ly:music-set-property! music 'pitch (round-pitch p)))
     music))

fixRests =
#(define-music-function (mus) (ly:music?)
   "Apply 'fix-rests' to MUS."
   (music-map (lambda (x) (fix-rests x)) mus))


mus = {
  g'2 g'\rest g'1\rest g'\breve\rest
  \break
}

{
  \omit Staff.TimeSignature
  \cadenzaOn

  <>^"original"
  \mus
  <>^"transposed without adjusting rest positions"
  \transpose g a \mus
  % Note that there is a ZWNJ character (U+200C) between 'f' and 'i'
  % to prevent the display of an 'fi' ligature.
  <>^\markup { transposed with \typewriter "\f‌ixRests" }
  \fixRests \transpose g a \mus
}

\paper {
  indent = 0
  line-width = 100\mm
  tagline = ##f
}