Modifying \layout programmatically

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Modifying \layout programmatically

Thomas Morley-2
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

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Modifying \layout programmatically

Thomas Morley-2
2017-08-07 14:41 GMT+02:00 Thomas Morley <[hidden email]>:

> 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

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user

modify-context-def-01.ly (6K) Download Attachment
Loading...