+magnifyMusic =
+#(define-music-function (parser location mag music) (positive? ly:music?)
+ (_i "Magnify the notation of @var{music} without changing the
+staff-size, using @var{mag} as a size factor. Stems, beams,
+slurs, ties, and horizontal spacing are adjusted automatically.")
+
+ ;; these props are NOT allowed to shrink below default size
+ (define unshrinkable-props
+ '(
+ ;; stems
+ (Stem thickness)
+
+ ;; slurs
+ (Slur line-thickness)
+ (Slur thickness)
+ (PhrasingSlur line-thickness)
+ (PhrasingSlur thickness)
+
+ ;; ties
+ (Tie line-thickness)
+ (Tie thickness)
+ (LaissezVibrerTie line-thickness)
+ (LaissezVibrerTie thickness)
+ (RepeatTie line-thickness)
+ (RepeatTie thickness)
+ ))
+
+ ;; these props ARE allowed to shrink below default size
+ (define shrinkable-props
+ (let ((baseline-skip-props
+ (find-named-props 'baseline-skip all-grob-descriptions))
+ (word-space-props
+ (find-named-props 'word-space all-grob-descriptions)))
+ (append
+ baseline-skip-props
+ word-space-props
+ '(
+ ;; TODO: uncomment spacing-increment here once Issue 3987 is fixed
+ ;; override at the 'Score level
+ ;(SpacingSpanner spacing-increment)
+
+ ;; lengths and heights
+ (Beam length-fraction)
+ (Stem length-fraction)
+ (Stem beamlet-default-length)
+ (Stem double-stem-separation)
+ (Slur height-limit)
+ (Slur minimum-length)
+ (PhrasingSlur height-limit)
+ (PhrasingSlur minimum-length)
+
+ ;; Beam.beam-thickness is dealt with separately below
+ ))))
+ #{
+ \context Bottom {
+ %% TODO: uncomment \newSpacingSection once Issue 3990 is fixed
+ %\newSpacingSection
+ #(scale-fontSize 'magnifyMusic mag)
+ #(scale-props 'magnifyMusic mag #f unshrinkable-props)
+ #(scale-props 'magnifyMusic mag #t shrinkable-props)
+ #(scale-beam-thickness mag)
+
+ #music
+
+ %% TODO: uncomment \newSpacingSection once Issue 3990 is fixed
+ %\newSpacingSection
+ %% reverse engineer the former fontSize value instead of using \unset
+ #(revert-fontSize 'magnifyMusic mag)
+ #(revert-props 'magnifyMusic mag (append unshrinkable-props
+ shrinkable-props
+ '((Beam beam-thickness))))
+ }
+ #})
+
+magnifyStaff =
+#(define-music-function (parser location mag) (positive?)
+ (_i "Change the size of the staff, adjusting notation size and
+horizontal spacing automatically, using @var{mag} as a size factor.")
+
+ ;; these props are NOT allowed to shrink below default size
+ (define unshrinkable-props
+ '((StaffSymbol thickness)))
+
+ ;; these props ARE allowed to shrink below default size
+ (define shrinkable-props
+ (let* ((baseline-skip-props
+ (find-named-props 'baseline-skip all-grob-descriptions))
+ (word-space-props
+ (find-named-props 'word-space all-grob-descriptions))
+ (space-alist-props
+ (find-named-props 'space-alist all-grob-descriptions)))
+ (append
+ baseline-skip-props
+ word-space-props
+ space-alist-props
+ '(
+ ;; override at the 'Score level
+ (SpacingSpanner spacing-increment)
+
+ (StaffSymbol staff-space)
+ (BarLine kern)
+ (BarLine segno-kern)
+ (BarLine hair-thickness)
+ (BarLine thick-thickness)
+ (Stem beamlet-default-length)
+ (Stem double-stem-separation)
+ ))))
+
+ #{
+ \stopStaff
+
+ %% revert settings from last time
+ %% (but only if \magnifyStaff has already been used
+ %% and the staff magnification is changing)
+ #(revert-fontSize 'magnifyStaff mag)
+ #(revert-props 'magnifyStaff mag (append unshrinkable-props
+ shrinkable-props))
+
+ %% scale settings
+ %% (but only if staff magnification is changing
+ %% and does not equal 1)
+ #(scale-fontSize 'magnifyStaff mag)
+ #(scale-props 'magnifyStaff mag #f unshrinkable-props)
+ #(scale-props 'magnifyStaff mag #t shrinkable-props)
+
+ %% this might cause problems until Issue 3990 is fixed
+ \newSpacingSection
+
+ \startStaff
+ \set Staff.magnifyStaffValue = #mag
+ #})
+