[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
- Modifying \layout programmatically,
Thomas Morley <=