[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
modify-context-def-01.ly
Description: Text Data