On 30.09.2015 01:28, Thomas Morley wrote:
Could you post a fully compilable example for follow readers?

Here’s a demo file showing the entire framework in action (since you seemed to be interested in more detail, I included all of it (except for style-sheet information), resulting in quite a lot of code). I’m working on a work by di Lasso with nine pieces divided in two or three ‘partes’ each; the framework is designed such as to give the possibility of printing any selection of _parts_ (i.e. voices), partes and pieces. For the latter, just use multiple \include "scoreN.ily" in your print.ly file. I don’t want to include the actual music, so I made a small, dummy example showing the use of some features. Uncomment the respective lines from the \scoreBox function definition to use it for SATB. I hope it becomes clear how the includes are nested; there are some TODOs, most notably I must stop using addlyrics, because it center-aligns syllables for melismata – that’s the only bug that I know of. Thanks to everybody for any help which allowed me to make this really useful setup.

Yours, Simon
\version "2.19.27"

%%%%%% from library/scm-utility.ily

#(define moment->duration
   (lambda (mom)
     (if (not (= 0 (ly:moment-grace mom)))
         (ly:warning "ly:moment->duration omits grace timing"))
     (ly:make-duration 0 0 (ly:moment-main mom))))
#(define duration-normalize
   (lambda (dur)
     (moment->duration (ly:duration-length dur))))
#(define music-length-diminish
   (lambda (mu ra) (ly:moment-sub (ly:music-length mu)
                     (ly:make-moment ra))))
#(define music-is-not-empty?
   (lambda (m) (not (equal? (ly:make-moment 0)
                            (ly:music-length m)))))

%%%%%%%%%%%%%%%% library/editorial.ily %%%%%%%%%%%%%%%%%%%%%%%%
\version "2.18"
%{
 With version 2.18.x, \ed Rest and \ed Mmr need the music
expression to be enclosed into {}. From 2.19.x on (at least .8),
this is not required anymore.
%}

editorsColor = #grey
ed =
#(define-music-function (parser location grob col mus)
   (symbol-list-or-symbol? (color? editorsColor) ly:music?)
   ;; for abbreviations, we need a symbol instead of a one-element list
   (let ((grob (if (and (list? grob) (= 1 (length grob)))
                   (car grob)
                   grob)))
     (case
      grob
      ;; define abbreviations
      ;; which call the function recursively with a value
      ;; leading into the (else) clause
      ;; (or to _another_ abbreviation)
      ;; be careful to avoid infinite recursion :-)
      ;; – abbreviation names must not be actual grob names
      ;; (at least if they’re used in the corresponding
      ;; clause) or recursion will be infinite also
      ;; It is recommended to use singular forms only
      ;; for abbreviations.
      ((Acc) #{ \ed Staff.Accidental
                \ed Staff.AccidentalCautionary
                \ed Staff.AccidentalSuggestion
                $mus #})
      ((Caut) #{ \ed Staff.AccidentalCautionary $mus #})
      ((LedgerLine) #{ % barline is workaround to issue 3949
        \once\hide Score.BarLine
        \once\hide Score.SpanBar
        \bar "|"
        \stopStaff
        \ed Staff.LedgerLineSpanner {
          \startStaff
          $mus
          \stopStaff
        }
        \once\hide Score.BarLine
        \once\hide Score.SpanBar
        \bar "|"
        \startStaff #})
      ((Lyrics) #{ \ed LyricText
                   \ed LyricHyphen
                   \ed LyricExtender
                   $mus #})
      ((Mmr) #{ \ed MultiMeasureRest $mus #})
      ((Note) #{ \ed Staff.Accidental
                 \ed Beam
                 \ed Dots
                 \ed Flag
                 %\ed LedgerLine
                 \ed NoteHead
                 \ed Rest
                 \ed Stem
                 $mus #})
      ((Pitch) #{ \ed NoteHead $mus #})
      ((Suggest) #{ \ed Staff.AccidentalSuggestion $mus #})
      ((StemWithFlag) #{ \ed Stem \ed Flag $mus #})
      ((Tuplet) #{ \ed TupletNumber \ed TupletBracket $mus #})
      ;; ‘normal’ case
      (else
       #{
         \override $grob . color = #col
         \override $grob . layer = -1
         $mus
         \revert $grob . color
         \revert $grob . layer
       #}))))
ted =
#(define-music-function (parser location col mus)
   ((color? editorsColor) ly:music?)
   #{
     \tweak color #col $mus
   #})

%{
\relative {
  \ed Note { c'8 d16. e32 fis g a16 r bes }
  \ed Script e,2\trill
  \ed Mmr { R1 } % brackets not required anymore in v.2.19.x
}
%}

suggest =
#(define-music-function (mus) (ly:music?)
   (ed 'Acc mus))
suggestNot =
#(define-music-function (mus) (ly:music?)
   #{
     \omit Staff.Accidental
     \omit Staff.AccidentalCautionary
     \omit Staff.AccidentalSuggestion
     $mus
     \undo\omit Staff.Accidental
     \undo\omit Staff.AccidentalCautionary
     \undo\omit Staff.AccidentalSuggestion
   #})

%%%%%%%%%%%%%%%%%% printI.ly %%%%%%%%%%%%%%%%%%%%

% load personal library files
% \include "standard-include.ily"
% include a file with e.g. font and paper size settings
% \include "style.ily"
use-modern-clefs = ##f

%%%%%%%%%%%%%%%%% scoreI.ily %%%%%%%%%%%%%%%%%%%%

title-markup = "First piece"
poet-markup = "The Bible"
% current choices: high, low
original-clef-set = #'low
number-of-partes = 3
% a list of numbers for the partes to be printed
pars-selection = #'(1 2 3)

%%%%%%%%%%%%%%%%%% defs.ily %%%%%%%%%%%%%%%%%%%%%

system-count-alist = #'((I . 1)
                        (II . #f)
                        (III . 3))

composer-markup = \markup { Orlando di Lasso }

% the following redefinitions make semantically almost adequate lilypond code
% (only with [, not \[ for ligatures)
% produce output in the style of 19th century editions of Renaissance music
% with slurs for ligatures (which is a notation used also in the Renaissance period, c.f.
% Manfred Hermann Schmid, Notationskunde [Bärenreiter (Kassel, Basel &c.) 2012])
% for ligatures
"[" = (
"]" = )
% for melismata
"(" = \melisma
")" = \melismaEnd

tripla = {
  \once\override Staff.TimeSignature.style = #'single-digit
  \time 3/1
  \newSpacingSection
}

allaBreve = {
  \time 2/2
  \set Timing.measureLength = #(ly:make-moment 2)
  \newSpacingSection
}

global =
#(define-music-function (parser location mus) (ly:music?)
   (if (equal? (ly:music-length mus) (ly:make-moment 0))
       #{#}
       #{
         <<
           \relative {
             \allaBreve
             \tag parts \compressFullBarRests
             $mus |
           }
           {
             \skip $(moment->duration (music-length-diminish mus 4))
             \set Timing.measureLength = #(ly:make-moment 4)
             s\longa
           }
         >>
       #} ))
globalNineB =
#(define-music-function (parser location mus) (ly:music?)
   #{ <<
     \relative {
       \time 2/2
       \set Timing.measureLength = #(ly:make-moment 2)
       \tag parts \compressFullBarRests
       $mus |
     }
     {
       \skip \breve*29
       \tripla
       \skip \breve.*23
       \set Timing.measureLength = #(ly:make-moment 4)
       s\longa
     }
      >>
   #})

% preset all possible music and lyric vars with empty music

sa = {}
sb = {}
sc = {}
aa = {}
ab = {}
ac = {}
ta = {}
tb = {}
tc = {}
ba = {}
bb = {}
bc = {}

sla = {}
slb = {}
slc = {}
ala = {}
alb = {}
alc = {}
tla = {}
tlb = {}
tlc = {}
bla = {}
blb = {}
blc = {}

\include "clef-sets.ily"

% TODO:
% implement pars-selection
#(define (part-box-internal voice)

   (let*
    ((satb-case (lambda (su al te bs)
                  (case voice
                    ((S) su)
                    ((A) al)
                    ((T) te)
                    ((B) bs))))

     (three-partes? (= number-of-partes 3))

     (print-a? (member 1 pars-selection))
     (print-b? (member 2 pars-selection))
     (print-c? (member 3 pars-selection))

     (secunda-mark #{ \tweak self-alignment-X -1
                      \mark "Secunda Pars" #})
     (tertia-mark #{ \tweak self-alignment-X -1
                     \mark "Tertia Pars" #})

     (clef-set (if use-modern-clefs 'modern original-clef-set))
     (clef-list (assoc-get clef-set clef-set-alist))
     (cl (lambda (str) #{ \clef $str #}))
     (sop-clef (cl (first clef-list)))
     (alt-clef (cl (second clef-list)))
     (ten-clef (cl (third clef-list)))
     (bas-clef (cl (fourth clef-list)))
     (clef (satb-case sop-clef alt-clef ten-clef bas-clef))

     (instr-name (satb-case "Superius" "Altus" "Tenor" "Bassus"))

     (music-a #{ $(satb-case sa aa ta ba)
                 \once\omit Staff.TimeSignature
       #})
     (music-b #{ $secunda-mark
                 $(satb-case sb ab tb bb)
                 \once\omit Staff.TimeSignature
       #})
     (music-c #{ $(if three-partes? tertia-mark)
                 $(satb-case sc ac tc bc) #})

     (lyr-a (satb-case sla ala tla bla))
     (lyr-b (satb-case slb alb tlb blb))
     (lyr-c (satb-case slc alc tlc blc))
     )

    ;; body
    #{
      <<
        \new Staff \with {
          instrumentName = $instr-name
        } {
          $clef
          $tone

          $(if print-a? music-a)
          $(if (and print-a?
                    (or print-b? print-c?))
               #{ \bar "||" #})
          $(if print-b? music-b)
          $(if (and three-partes?
                    print-c?
                    (or print-a? print-b?))
               #{ \bar "||" #})
          $(if print-c? music-c)
          \bar "|."
        }

        %%%% TODO: avoid \addlyrics
        \addlyrics {
          $(if print-a? lyr-a)
          $(if print-b? lyr-b)
          $(if print-c? lyr-c)
        }
      >>
    #}))

partBox =
#(define-scheme-function
  (parser location v) (symbol?)
  #{
    \score {
      \keepWithTag part
      $(part-box-internal v)

      \header {
        composer = \composer-markup
        title = \title-markup
        poet = \poet-markup
      }

      \layout {
        \context {
          \Voice
          \remove "Note_heads_engraver"
          \consists "Completion_heads_engraver"
          \remove "Rest_engraver"
          \consists "Completion_rest_engraver"
        }
      }
    }
  #})

scoreBox =
#(define-scheme-function
  (parser location) ()
  #{
    \score {
      \keepWithTag score
      \new StaffGroup <<
        %$translation-box
        $(part-box-internal 'S)
        %$(part-box-internal 'A)
        %$(part-box-internal 'T)
        %$(part-box-internal 'B)
      >>

      \header {
        composer = \composer-markup
        title = \title-markup
        poet = \poet-markup
      }

      \layout {
        \context {
          \Voice
          \remove "Note_heads_engraver"
          \consists "Completion_heads_engraver"
          \remove "Rest_engraver"
          \consists "Completion_rest_engraver"
        }
      }
    }
  #})

bookpartBox =
#(define-scheme-function (parser location roman) (symbol?)
   (collect-bookpart-for-book
   #{
     \bookpart {
       \paper {
         system-count = $(assoc-get roman system-count-alist)
         %systems-per-page = 4
       }
       \scoreBox
     }
   #}))

\layout {
  \context {
    \Staff
    \accidentalStyle forget
  }
}

%%%%%%%%%%%%%%%%%%% musicI.ily %%%%%%%%%%%%%%%%%%%%%%%

tone = { \key d \dorian }
sa = \global {
  d''\breve
  cis\longa
}
sb = \global {
  cis''1[ d1.] cis4( \suggest b \suggestNot cis\longa*3/4)
}
sc = \global {
  d'1[ cis]
  d\longa
}

%%%% …

%%%%%%%%%%%%%%%%%%%% textI.ily %%%%%%%%%%%%%%%%%%%%%%%%

sla = \lyricmode {
  first pars
}
slb = \lyricmode {
  se -- cond __
}
slc = \lyricmode {
  the end
}

%%%%% …

%%%%%%%%%%%%%%%%%%%%% continue scoreI.ly %%%%%%%%%%%%%%%

\bookpartBox #'I

%%%%%%%%%%%%%%%%%%% end input %%%%%%%%%%%%%%%%%%%%%%%%%%
_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to