lilypond-user
[Top][All Lists]
Advanced

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

Re: Modifying \layout programmatically


From: Thomas Morley
Subject: Re: Modifying \layout programmatically
Date: Mon, 7 Aug 2017 23:33:59 +0200

2017-08-07 14:41 GMT+02:00 Thomas Morley <address@hidden>:
> 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?


Uh, oh...
The function never updated the original layout but always put out a
modified copy.
A second call again took the original ...
This way creating a stack is impossible.

Attached a first working file.


Cheers,
  Harm

Attachment: modify-context-def-01.ly
Description: Text Data


reply via email to

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