lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Modifying \layout programmatically


From: Thomas Morley
Subject: Modifying \layout programmatically
Date: Mon, 7 Aug 2017 14:41:36 +0200

Hi all,

first some background.
I'm currently researching how to create output from basic,
mostly-empty stuff or defaults.
Like after defining some music, bookpart, book, layout, paper, header as:
mus = { r1 }
bkp = \bookpart {}
bk = \book {}
lo = \layout {}
pap = \paper {}
hd = \header {}
the exercise is:
Put \mus in a score, probably with a modified layout derived from \lo
Put this score in \bkp, probably with a modified paper derived from \pap
Put this \bkp in \bk, probably with a modifies \paper derived from \pap
Probably add more bookparts with different settings into \bk
Create a modified toplevel-layout derived from \lo

For some of this tasks we do have conveniant functions/procedures for
others not.


Currently I'm struggling with modifying a layout, which I want to do
with a function taking \lo as an argument returning a modified layout,
not from inside of a \layout.
To explain the problem more detailed, first the spelled out default,
(displaying functions are commented)

\layout { \context { \Voice \override NoteHead.color = #yellow } }
%#(format #t "\n1. look for property-ops:\n~y"
%  (ly:context-def-lookup
%    (module-ref (ly:output-def-scope $defaultlayout) 'Voice)
%    'property-ops))

\layout { \context { \Voice \override NoteHead.color = #green } }
%#(format #t "\n2. look for property-ops:\n~y"
%  (ly:context-def-lookup
%    (module-ref (ly:output-def-scope $defaultlayout) 'Voice)
%    'property-ops))

\score {
  \new Voice {
    cis'1
    \revert NoteHead.color
    d'1
    \revert NoteHead.color
    e'
    \revert NoteHead.color
    f'
  }
  \layout { \context { \Voice \override NoteHead.color = #red } }
}

As one can see the subsequent reverts are following the stack nicely.
If I remember correctly it was David K who put some afford into this
to get it correct.

Here what I have so far. Obviously the stack is not created correctly.

modify-context-def-in-layout =
#(define-scheme-function (lay-out ctx-name context-mod)
  (ly:output-def? symbol? ly:context-mod?)
  "Modifies the context-def of  @var{ctx-name} in @var{lay-out} with
@var{context-mod}.  Returning @var{lay-out} as new $defaultlayout.
Implicit created contexts will be modified as well, aliases are not affected."
  (let* ((actual-module (current-module))
         ;; TODO never go for (current-module) ??
         ;;      needs decision whether this function is always applied
         ;;      outside of \layout
         (curr-module
           (if (module-ref actual-module 'is-layout #f)
               actual-module
               (ly:output-def-scope lay-out)))
         (curr-module-ctx-def (module-ref curr-module ctx-name))
         ;; not needed for final approach
         (curr-module-ctx-var
           (module-variable curr-module ctx-name))
           )

;;;;
;;;; first pretty generic attempt
;;;;
;    (module-map
;      (lambda (_sym var)
;        (if (and (eq? _sym ctx-name)
;                 (variable-bound? var)
;                 (ly:context-def? curr-module-ctx-def))
;            (variable-set!
;              var
;              (ly:context-def-modify curr-module-ctx-def context-mod))))
;      curr-module)
;
;;;;
;;;; second more specific attempt
;;;;
;    ;; TODO safe?
;    ;;      or need to check for variable-bound?
;    (if (variable? curr-module-ctx-var)
;        (variable-set!
;          curr-module-ctx-var
;          (ly:context-def-modify curr-module-ctx-def context-mod)))
;
;;;;
;;;; final
;;;;
    (if (ly:context-def? curr-module-ctx-def)
        (ly:output-def-set-variable!
          lay-out
          ctx-name
          (ly:context-def-modify curr-module-ctx-def context-mod)))
    lay-out))

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% EXAMPLE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

my-layout =
\layout { \context { \Voice \override NoteHead.color = #yellow } }

%#(format #t "\n1. look for property-ops:\n~y"
%  (ly:context-def-lookup
%    (module-ref (ly:output-def-scope my-layout) 'Voice)
%    'property-ops))

\modify-context-def-in-layout
  \my-layout
  Voice
  \settingsFrom \override NoteHead.color = #green

%#(format #t "\n1a. look for property-ops:\n~y"
%  (ly:context-def-lookup
%    (module-ref (ly:output-def-scope my-layout) 'Voice)
%    'property-ops))

\score {
  \new Voice {
    cis'1
    \revert NoteHead.color
    d'1
    \revert NoteHead.color
    e'
    \revert NoteHead.color
    f'
  }
  \modify-context-def-in-layout
    \my-layout
    Voice
    \settingsFrom \override NoteHead.color = #red
}

I'd like have some guidance here. How to do so?


Cheers,
  Harm



reply via email to

[Prev in Thread] Current Thread [Next in Thread]