On 14.03.2022 11:22, Robin Bannister wrote:
Patrick Martin wrote:

For example, in this picture, 22 follows directly on from the end of 21, and 23 from 22, etc. Or would this need to be implemented some other way?


Pseudoindent could help with the horizontal aspect.
https://lsr.di.unimi.it/LSR/Item?id=1098
You would choose an initial left-indent and a final right-indent for
each piece, and apply these manually.


Then get the appropriate vertical neighbours to overlap, without
involving enclosing StaffGroups and such.  I have no concrete
suggestions for that


Well, here is a way, using a NonMusicalPaperColumn override, such as
pseudoIndent already uses. The whole thing is rather clunky and includes a crude workaround which may need refining.

You copy the first part of pseudoIndentsYdemo.ly.
Choose a global-staff-size, set it, and don't change it later.
Then you work down the page, filling each line with system fragments.
   Each pseudoIndentsY call produces and places one fragment.
   Keep these calls in a separate voice in the first staff.
   All the parameters are in staff-spaces.
   In this inlay usage, the right-indent parameter can trip you up.
   Measures squeezed out by lack of space may jump out of sight.
   But the pagewise lookups make the line positioning easy to adjust.
When you reach the page bottom insert a manual pageBreak.

The whole thing is extremely manual.
Don't want to change anything bulky when you're done!
It should work ok with tame systems like your chorales example.


Cheers,
Robin


\version "2.22.0"

\include "pseudoIndent.ily" %  cf LSR1098

pseudoIndentsY = % applies vertical positioning to pseudoIndents result 
#(define-music-function (parser location name-tweaks left-indent right-indent 
    Y-pos) ; cf apply-Y-pos, which needs pseudoIndentsY in the _first_ staff
  ((markup-list? '()) number? number? number?)
  (let* ( 
    (apply-Y-pos ; position our system <Y-pos> staff-spaces from top of page
      (let* ((even-taller 10)) ; than the top of the tallest grob, we hope! 
       #{ % misusing barline to swamp unknown first_staff_min_translation
         \override Staff.BarLine.Y-extent = #(cons -2 even-taller)
         \overrideProperty Score.NonMusicalPaperColumn.line-break-system-details
          .Y-offset #(- Y-pos even-taller) % wonky if even-taller isn't taller
       #}))) % cf lilypond-user/2011-05/msg00366.html patch from Joe N.
  #{
    \pseudoIndents $name-tweaks $left-indent $right-indent 
    % try for explicit vertical positioning: 
    #apply-Y-pos 
  #}))

\paper { % needed for apply-Y-pos
  system-system-spacing = #'(
    (basic_distance . 0)
    (minimum_distance . 0)
    (padding . -10)
    (stretchability . 0))
  score-system-spacing =  #'(
    (basic_distance . 0)
    (minimum_distance . 0)
    (padding . -10)
    (stretchability . 0))
}

\layout { \autoPageBreaksOff } % but manual \pageBreak still effective

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

#(set-global-staff-size 20) % choose a value and stick to it!
\paper { indent = 8 } % or = 0, adjusting initial left-indents individually 
\layout { \override Score.InstrumentName.padding = #2 }
\header { title = "pseudoIndentsY  demo" }


% convenience pagewise lookups for desired Y-pos staff-spaces via line-number: 
%   the first value is the distance of line 1 below the page top 
%   the second value is the distance of line 2 below line 1, and so on
#(define (Y-p1 line-num) (apply + (take '(15 22 23 22 21 21 21 21) line-num)))
#(define (Y-p2 line-num) (apply + (take '(10 00 00 00 00 00 00 00) line-num)))

  
\score { 
  \new StaffGroup \with { instrumentName = "A" }
   <<
     \new Staff
     <<
       \new Voice { \repeat unfold 47 a'4 a'''4 }
       \new Voice {
         \pseudoIndentsY 00 00 #(Y-p1 1) s1*8 
         \pseudoIndentsY 00 55 #(Y-p1 2) s1*4 \bar"|." 
       }
     >>
     \new Staff { \clef bass \repeat unfold 23 a2 a''2 }
   >>
}

\noPageBreak

\score { 
  \new StaffGroup \with { instrumentName = "B" }
  <<
    \new Staff
    << 
      \new Voice { \repeat unfold 48 b'4 }
      \new Voice {
        \pseudoIndentsY 60 00 #(Y-p1 2) s1*3
        \pseudoIndentsY 00 00 #(Y-p1 3) s1*8 
        \pseudoIndentsY 00 90 #(Y-p1 4) s1*1\bar"|." 
      }
    >>
    \new Staff { \clef bass \repeat unfold 24 b2 }         
  >>
}

\noPageBreak

\score { 
  \new Staff \with { instrumentName = "C" }
  << 
    \new Voice { \repeat unfold 8 c''4 }
    \new Voice {
      \pseudoIndentsY 25 50 #(Y-p1 4) s1*2 \bar"|." 
    }
  >>
}

\noPageBreak

\score { 
  \new StaffGroup \with { instrumentName = "D" }
  <<
    \new Staff
    << 
      \new Voice { \repeat unfold 12 d''4 }
      \new Voice {
        \pseudoIndentsY 65 00 #(Y-p1 4) s1*3 \bar"|." 
      }
    >>
    \new Staff { \clef bass \repeat unfold 6 d2 }
  >>
}

\noPageBreak
  
\score { 
\new StaffGroup \with { instrumentName = "E" }
  <<
    \new Staff
    <<
      \new Voice { \repeat unfold 47 e'4 e'''4 }
      \new Voice {
        \pseudoIndentsY 00 00 #(Y-p1 5) s1*8 
        \pseudoIndentsY 00 55 #(Y-p1 6) s1*4 \bar"|." 
      }
    >>
    \new Staff { \clef bass \repeat unfold 23 e2 e''2 }
  >>
}

\noPageBreak

\score { 
  \new StaffGroup \with { instrumentName = "F" }
  <<
    \new Staff
    << 
      \new Voice { \repeat unfold 48 f'4 }
      \new Voice {
        \pseudoIndentsY 60 00 #(Y-p1 6) s1*3
        \pseudoIndentsY 00 00 #(Y-p1 7) s1*8           \pageBreak
        \pseudoIndentsY 00 90 #(Y-p2 1) s1*1 \bar"|." 
      }
    >>
    \new Staff { \clef bass \repeat unfold 24 f2 }         
  >>
}

\noPageBreak

\score { 
  \new Staff \with { instrumentName = "G" }
  << 
    \new Voice { \repeat unfold 24 g'4 }
    \new Voice {
      \pseudoIndentsY 25 00 #(Y-p2 1) s1*6 \bar"|." 
    }
  >>
}

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


Attachment: pseudoIndentsYdemo.pdf
Description: Adobe PDF document

%%%%%%%% PSEUDOINDENT FUNCTIONS %%%%%%%%

% these two functions are for indenting individual systems
% - to left-indent a system, apply \pseudoIndent before the music continues
% - \pseudoIndents is similar, but lets you also indent on the right
% - both provide an option for changing that system's instrument names

% N.B. these functions 
% - assume application to non-ragged lines (generally the default)
% - include a manual \break to ensure application at line start 
% - misbehave if called more than once at the same line start

% the parameters of the (full) pseudoIndents function are:
% 1: name-tweaks
%      usually omitted; accepts replacement \markup for instrument names 
%      as an ordered list; starred elements leave their i-names unchanged.
% 2: left-indent 
%      additional left-indentation, in staff-space units; can be negative, 
%      but avoid a total indentation which implies (unsupported) stretching. 
% 3: right-indent 
%      amount of right-indentation, in staff-space units; can be negative. 
%      - not offered by the (reduced) pseudoIndent function


pseudoIndents = % inline alternative to a new \score, also with right-indent
#(define-music-function (parser location name-tweaks left-indent right-indent) 
  ((markup-list? '()) number? number?)
  (define (warn-stretched p1 p2) (ly:input-warning location (_
    " pseudoIndents ~s ~s is stretching staff; expect distorted layout") p1 p2))
  (let* ( 
    (narrowing (+ left-indent right-indent)) ; of staff implied by args
    
    (set-staffsymbol! (lambda (staffsymbol-grob) ; change staff to new width 
      (let* (
        (left-bound (ly:spanner-bound staffsymbol-grob LEFT))
        (left-moment (ly:grob-property left-bound 'when))
        (capo? (moment<=? left-moment ZERO-MOMENT)) ; in first system of score
        (layout (ly:grob-layout staffsymbol-grob))
        (lw (ly:output-def-lookup layout 'line-width)) ; debugging info
        (indent (ly:output-def-lookup layout (if capo? 'indent 'short-indent)))
        (old-stil (ly:staff-symbol::print staffsymbol-grob))
        (staffsymbol-x-ext (ly:stencil-extent old-stil X))
        ;; >=2.19.16's first system has old-stil already narrowed [2]
        ;; compensate for this (ie being not pristine) when calculating 
        ;; - old leftmost-x (its value is needed when setting so-called 'width) 
        ;; - the new width and position (via local variable narrowing_) 
        (ss-t (ly:staff-symbol-line-thickness staffsymbol-grob))
        (pristine? (<= 0 (car staffsymbol-x-ext) ss-t)) ; would expect half
        (leftmost-x (+ indent (if pristine? 0 narrowing))) 
        (narrowing_ (if pristine? narrowing 0)) ; uses 0 if already narrowed
        (old-width (+ (interval-length staffsymbol-x-ext) ss-t))
        (new-width (- old-width narrowing_))
        (new-rightmost-x (+ leftmost-x new-width)) ; and set! this immediately
        (junk (ly:grob-set-property! staffsymbol-grob 'width new-rightmost-x))
        (in-situ-stil (ly:staff-symbol::print staffsymbol-grob))
        (new-stil (ly:stencil-translate-axis in-situ-stil narrowing_ X))
       ;(new-stil (stencil-with-color new-stil red)) ; for when debugging
        (new-x-ext (ly:stencil-extent new-stil X)))
      (ly:grob-set-property! staffsymbol-grob 'stencil new-stil)
      (ly:grob-set-property! staffsymbol-grob 'X-extent new-x-ext)
      )))
    
    (set-X-offset! (lambda (margin-grob) ; move grob across to line start 
      (let* (
        (old (ly:grob-property-data margin-grob 'X-offset))                             
        (new (lambda (grob) (+ (if (procedure? old) (old grob) old) narrowing))))
      (ly:grob-set-property! margin-grob 'X-offset new))))
    
    (tweak-text! (lambda (i-name-grob mkup) ; tweak both instrumentname texts   
      (if (and (markup? mkup) (not (string=? (markup->string mkup) "*")))
      (begin 
        (ly:grob-set-property! i-name-grob 'long-text mkup)
        (ly:grob-set-property! i-name-grob 'text mkup)
        )))) ; else retain existing text 
    
    (install-narrowing (lambda (leftedge-grob) ; on staves, + adapt left margin
      (define (grob-name x) (assq-ref (ly:grob-property x 'meta) 'name))
      (let* (
        (sys (ly:grob-system leftedge-grob))
        (all-grobs (ly:grob-array->list (ly:grob-object sys 'all-elements)))
        (grobs-named (lambda (name)
          (filter (lambda (x) (eq? name (grob-name x))) all-grobs)))
        (first-leftedge-grob (list-ref (grobs-named 'LeftEdge) 0))
        (relsys-x-of (lambda (g) (ly:grob-relative-coordinate g sys X)))
        (leftedge-x (relsys-x-of first-leftedge-grob))
        (leftedged? (lambda (g) (= (relsys-x-of g) leftedge-x)))        
        (leftedged-ss (filter leftedged? (grobs-named 'StaffSymbol))))
      (if (eq? leftedge-grob first-leftedge-grob) ; ignore other leftedges [1]        
       (begin 
         (for-each set-staffsymbol! leftedged-ss)
         (for-each set-X-offset! (grobs-named 'SystemStartBar))
         (for-each set-X-offset! (grobs-named 'InstrumentName))
         (for-each tweak-text! (grobs-named 'InstrumentName) name-tweaks)
       ))))))
    
  (if (negative? narrowing) (warn-stretched left-indent right-indent)) 
  #{ % and continue anyway
    % ensure that these overrides are applied only at begin-of-line 
    \break % (but this does not exclude unsupported multiple application) 
    % give the spacing engine notice regarding the loss of width for music
    \once \override Score.LeftEdge.X-extent = #(cons narrowing narrowing)
    % discard line start region of staff and reassemble left-margin elements 
    \once \override Score.LeftEdge.after-line-breaking = #install-narrowing 
    % shift the system to partition the narrowing between left and right
    \overrideProperty Score.NonMusicalPaperColumn.line-break-system-details
    .X-offset #(- right-indent)
    % prevent a leftmost barnumber entering a stretched staff 
    \once \override Score.BarNumber.horizon-padding = #(max 1 (- 1 narrowing))
  #}))                                        

pseudoIndent = % for changing just left-indent 
#(define-music-function (parser location name-tweaks left-indent) 
  ((markup-list? '()) number?) 
  #{ 
    \pseudoIndents $name-tweaks $left-indent 0 
  #})

% [1] versions <2.19.1 can have end-of-line leftedges too  
%     - these were eliminated in issue 3761 
% [2] versions >=2.19.16: the first system behaves differently from the rest
%     - a side effect of issue 660 ?

% this code excerpt from https://lsr.di.unimi.it/LSR/Item?id=1098 (as of v2.18)

Reply via email to