Hi Harm,

I found the attached file on my computer, which is for parenthesizing all kinds of grobs. It does a really good job on many grobs; with NoteColumns and NoteHeads it doesn’t work anymore (in v2.19.65), and it’s not designed for glissando (the glissando in the example is my own addition). I hope you don’t mind me bringing this up – it’s just because it might be a good starting point for future work.

Best, Simon
\version "2.19.24"
% courtesy of Thomas Morley
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% The following untouched defs need to be here, because they aren’t public.

#(define (make-bezier-sandwich-stencil coords thick xext yext)
   (let* ((command-list `(moveto
                          ,(car (list-ref coords 3))
                          ,(cdr (list-ref coords 3))
                          curveto
                          ,(car (list-ref coords 0))
                          ,(cdr (list-ref coords 0))
                          ,(car (list-ref coords 1))
                          ,(cdr (list-ref coords 1))
                          ,(car (list-ref coords 2))
                          ,(cdr (list-ref coords 2))
                          curveto
                          ,(car (list-ref coords 4))
                          ,(cdr (list-ref coords 4))
                          ,(car (list-ref coords 5))
                          ,(cdr (list-ref coords 5))
                          ,(car (list-ref coords 6))
                          ,(cdr (list-ref coords 6))
                          closepath)))
     (ly:make-stencil
      `(path ,thick `(,@' ,command-list) 'round 'round #t)
      xext
      yext)))

#(define (make-parenthesis-stencil
          y-extent half-thickness width angularity)
   "Create a parenthesis stencil.
@var{y-extent} is the Y extent of the markup inside the parenthesis.
@var{half-thickness} is the half thickness of the parenthesis.
@var{width} is the width of a parenthesis.
The higher the value of number @var{angularity},
the more angular the shape of the parenthesis."
   (let* ((line-width 0.1)
          ;; Horizontal position of baseline that end points run through.
          (base-x
           (if (< width 0)
               (- width)
               0))
          ;; X value farthest from baseline on outside  of curve
          (outer-x (+ base-x width))
          ;; X extent of bezier sandwich centerline curves
          (x-extent (ordered-cons base-x outer-x))

          (bottom-y (interval-start y-extent))
          (top-y (interval-end y-extent))

          (lower-end-point (cons base-x bottom-y))
          (upper-end-point (cons base-x top-y))

          (outer-control-x (+ base-x (* 4/3 width)))
          (inner-control-x (+ outer-control-x
                             (if (< width 0)
                                 half-thickness
                                 (- half-thickness))))

          ;; Vertical distance between a control point
          ;; and the end point it connects to.
          (offset-index (- (* 0.6 angularity) 0.8))
          (lower-control-y (interval-index y-extent offset-index))
          (upper-control-y (interval-index y-extent (- offset-index)))

          (lower-outer-control-point
           (cons outer-control-x lower-control-y))
          (upper-outer-control-point
           (cons outer-control-x upper-control-y))
          (upper-inner-control-point
           (cons inner-control-x upper-control-y))
          (lower-inner-control-point
           (cons inner-control-x lower-control-y)))

     (make-bezier-sandwich-stencil
      (list
       ;; Step 4: curve through inner control points
       ;; to lower end point.
       upper-inner-control-point
       lower-inner-control-point
       lower-end-point
       ;; Step 3: move to upper end point.
       upper-end-point
       ;; Step 2: curve through outer control points
       ;; to upper end point.
       lower-outer-control-point
       upper-outer-control-point
       upper-end-point
       ;; Step 1: move to lower end point.
       lower-end-point)
      line-width
      (interval-widen x-extent (/ line-width 2))
      (interval-widen y-extent (/ line-width 2)))))

#(define (other-axis a)
   (remainder (+ a 1) 2))

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

#(define-public (parenthesize-stencil
                 stencil half-thickness width angularity padding size)
   "Add parentheses around @var{stencil}, returning a new stencil."
   (let* ((y-extent (interval-widen (ly:stencil-extent stencil Y) size))
          (lp (make-parenthesis-stencil
               y-extent half-thickness (- width) angularity))
          (rp (make-parenthesis-stencil
               y-extent half-thickness width angularity)))
     (ly:stencil-combine-at-edge
      (ly:stencil-combine-at-edge stencil X LEFT lp padding)
      X RIGHT rp padding)))

par =
#(define-music-function (arg)(symbol-list-or-music?)
   (if (symbol-list? arg)
       (let ((context-name 'Bottom)
             (grob-name #f))

         (if (> 2 (length arg))
             (set! grob-name (car arg))
             (begin
              (set! grob-name (list-ref arg 1))
              (set! context-name (list-ref arg 0))))
         
         (propertyOverride `(,context-name ,grob-name stencil)
           (lambda (grob)
             (let* ((function (assoc-get 'stencil (reverse (ly:grob-basic-properties grob))))
                    (staff-space (ly:staff-symbol-staff-space grob))
                    (staff-line-thickness (ly:staff-symbol-line-thickness grob)))

               (if (and (procedure-name function)
                        (ly:stencil? (function grob)))
                   (let* ((stil (function grob))
                          (stem-pos (ly:grob-property grob 'stem-attachment))
                          (y-extent (ly:stencil-extent stil Y))
                          (y-length (interval-length y-extent))
                          (factor (if (<= y-length (* staff-space 1.5)) 0.5 1)))
                     (if (equal? grob-name 'NoteHead)
                         (begin
                          (ly:input-warning (*location*) (_ "better use simple \\parenthesize for ~a") grob-name)
                          stil)
                         (parenthesize-stencil
                          stil
                          staff-line-thickness
                          (* 4 staff-line-thickness factor)
                          (* staff-line-thickness 4)
                          (* staff-line-thickness 3)
                          (* staff-line-thickness 2))))
                   (begin
                    (ly:input-warning (*location*) (_ "cannot find 'stencil of ~a to parenthesize") grob-name)
                    '())
                   )))
           ))
       (begin
        (if (memq 'event-chord (ly:music-property arg 'types))
            ;; arg is an EventChord -> set the parenthesize property
            ;; on all child notes and rests
            (for-each
             (lambda (ev)
               (if (or (memq 'note-event (ly:music-property ev 'types))
                       (memq 'rest-event (ly:music-property ev 'types)))
                   (set! (ly:music-property ev 'parenthesize) #t)))
             (ly:music-property arg 'elements))
            ;; No chord, simply set property for this expression:
            (set! (ly:music-property arg 'parenthesize) #t))
        arg)
       ))

revertStencil =
#(define-music-function (name)(symbol-list?)
   (let ((context-name 'Bottom)
         (grob-name #f))

     (if (> 2 (length name))
         (set! grob-name (car name))
         (begin
          (set! grob-name (list-ref name 1))
          (set! context-name (list-ref name 0))))
     (propertyRevert `(,context-name ,grob-name stencil))))


%%{
\relative c' {
  \par Score.BarNumber
  \par Score.RehearsalMark
  \once\par Staff.Clef
  \par Staff.TimeSignature
  \par Score.MetronomeMark

  \key g\major
  \tempo "Allegro"

  \compressFullBarRests
  \par TextSpanner
  \override TextSpanner.bound-details.left.text = "showing par "
  %\par Script
  c1-\par -> %-\par -!
  \startTextSpan
  \par MultiMeasureRest
  \par MultiMeasureRestNumber
  R
  R1*2
  R1*3
  R1*4
  R1*5
  R1*6
  R1*7
  \mark\default
  \revertStencil MultiMeasureRestNumber
  R1*8
  R1*9
  R1*10
  R1*11
  \once \par Staff.KeySignature
  \once \par Staff.KeyCancellation
  \key bes\major
  \par Hairpin
  c1\<
  \par BreathingSign
  \breathe
  \par "Stem"
  d1
  dis8[ e]
  \revertStencil Stem
  \par Flag
  dis8 \noBeam e s2
  \once\par Staff.BarLine
  \bar ":..:"
  e1\!
  \par TrillSpanner
  \par Tie
  c1\startTrillSpan ~
  c~
  c1*7/8 s1*1/8
  \stopTrillSpan
  d1
  \stopTextSpan
  \par TupletBracket
  \par TupletNumber
  \once\override TupletNumber.text =
  #(tuplet-number::non-default-fraction-with-notes 12 "8" 4 "4")
  \tuplet 3/2 { c4. d e f }
  %\par
  \par TextScript
  e1_\markup \override #'(line-width . 50) \wordwrap {
    Some text. Some text. Some text. Some text.
    Some text. Some text. Some text. Some text.
    Some text. Some text. Some text. Some text.
  }
  \once\par NoteColumn
  <c e g>
  \once\par Score.VerticalAxisGroup
  <c e g>4
  \once\par Glissando
  \par NoteHead
  c\glissando
  c'
}

Attachment: par-grobs-06.pdf
Description: Adobe PDF document

_______________________________________________
lilypond-user mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to