From dd7a75b0862bf05adec8033a1c4a15f225255101 Mon Sep 17 00:00:00 2001 From: David Kastrup Date: Mon, 20 Feb 2012 18:39:23 +0100 Subject: [PATCH] Add layout changing command \layout-from for getting context defs from music --- input/regression/layout-from.ly | 19 ++++++++ ly/context-mods-init.ly | 77 ++++++++++++++++++++++++++++++++- 2 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 input/regression/layout-from.ly diff --git a/input/regression/layout-from.ly b/input/regression/layout-from.ly new file mode 100644 index 0000000000..2c0669a2fe --- /dev/null +++ b/input/regression/layout-from.ly @@ -0,0 +1,19 @@ +\version "2.15.31" + +\header { + texidoc = " +@code{\\layout-from} can interpret property-setting music for changing +context definitions inside of layout definitions like @code{\\layout} +or @code{\\midi}. +" +} + +\score { + \relative c' { cis cis cis cis } + \layout { + \layout-from { \accidentalStyle "dodecaphonic" } + } + \midi { + \layout-from { \tempo 4 = 240 } + } +} diff --git a/ly/context-mods-init.ly b/ly/context-mods-init.ly index 087d4bb155..b8361a58ec 100644 --- a/ly/context-mods-init.ly +++ b/ly/context-mods-init.ly @@ -16,7 +16,7 @@ %%%% You should have received a copy of the GNU General Public License %%%% along with LilyPond. If not, see . -\version "2.15.6" +\version "2.15.31" RemoveEmptyStaves = \with { \remove "Axis_group_engraver" @@ -31,3 +31,78 @@ RemoveEmptyStaves = \with { \description "Remove staves which are considered to be empty according to the list of interfaces set by @code{keepAliveInterfaces}." } + +"layout-from" = +#(define-void-function (parser location bottom music) + ((symbol? 'Voice) ly:music?) + (_i "To be used in output definitions. Take the layout instruction +events from @var{music} and do the equivalent of context modifications +duplicating their effect. + +This is handy for making layout definitions by using property +definitions like @code{\\accidentalStyle} or definitions like +@code{\\tabFullNotation} that may work in multiple or unknown +contexts. + +Layout instructions specified without explicit context get mapped to +the context symbol @var{bottom}, with a default of @code{'Voice}. + +For example, you can tell @code{\\layout-from} to apply a contained +@example +\\override #'font-size = #2 +@end example +to @samp{TabVoice} or @samp{Lyrics} context instead of the default +@samp{Voice} context, if the context where you would normally use +@var{music} is not one that would have @samp{Voice} as its +@samp{Bottom}.") + (let loop ((m music) (mods #f)) + ;; The parser turns all sets, overrides etc into something + ;; wrapped in ContextSpeccedMusic. If we ever get a set, + ;; override etc that is not wrapped in ContextSpeccedMusic, the + ;; user has created it in Scheme himself without providing the + ;; required wrapping. In that case, using #f in the place of a + ;; context modification results in a reasonably recognizable + ;; error. + (if (music-is-of-type? m 'layout-instruction-event) + (ly:add-context-mod + mods + (case (ly:music-property m 'name) + ((PropertySet) + (list 'assign + (ly:music-property m 'symbol) + (ly:music-property m 'value))) + ((PropertyUnset) + (list 'unset + (ly:music-property m 'symbol))) + ((OverrideProperty) + (list 'push + (ly:music-property m 'symbol) + (ly:music-property m 'grob-property-path) + (ly:music-property m 'grob-value))) + ((RevertProperty) + (list 'pop + (ly:music-property m 'symbol) + (ly:music-property m 'grob-property-path))))) + (case (ly:music-property m 'name) + ((SequentialMusic SimultaneousMusic) + (fold loop mods (ly:music-property m 'elements))) + ((ContextSpeccedMusic) + ;; It is actually rather embarrassing that we have no + ;; reliable way to check for the type of a context-def. + ;; Nor have a Scheme way to add to a context-def. + (let ((sym (ly:music-property m 'context-type))) + (if (eq? sym 'Bottom) + (set! sym bottom)) + (if (module-bound? (current-module) sym) + (module-set! + (current-module) + sym + #{ \context { + $(module-ref (current-module) sym) + $(loop (ly:music-property m 'element) + (ly:make-context-mod)) + } + #}) + (ly:warning music (_f "Cannot find context-def \\~a" + sym))))))) + mods)) -- 2.39.2