lilypond-devel
[Top][All Lists]
Advanced

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

Re: Add layout changing command \layout-from for getting context defs fr


From: dak
Subject: Re: Add layout changing command \layout-from for getting context defs from music (issue 5686046)
Date: Thu, 23 Feb 2012 00:53:58 +0000

Reviewers: janek,


http://codereview.appspot.com/5686046/diff/1/ly/context-mods-init.ly
File ly/context-mods-init.ly (right):

http://codereview.appspot.com/5686046/diff/1/ly/context-mods-init.ly#newcode49
ly/context-mods-init.ly:49: to @code{'Voice}.
On 2012/02/23 00:13:34, janek wrote:
I don't get what these Bottoms are.

\set whatever = value is the same as \set Bottom.whatever = value.
Bottom is an alias for Voice most of the time, but in some contexts
(like TabStaff and below) also for TabVoice, or for Lyrics or some other
things.

How should I write this instead?

http://codereview.appspot.com/5686046/diff/1/ly/context-mods-init.ly#newcode55
ly/context-mods-init.ly:55: ;; Scheme.
On 2012/02/23 00:13:34, janek wrote:
I don't understand this.  What happens?
The parser turns all sets, overrides etc into something wrapped in
ContextSpeccedMusic.  If you ever get a set, override etc that is not
wrapped in ContextSpeccedMusic, the user has created it in Scheme
himself.  In that case, the code will try to use #f as a context
modification resulting in an error.  It's a situation that can only be
triggered when you are messing in experienced areas, so I don't bother
providing a different behavior.

One could let "mods" be an empty context modification instead: in that
case, the bad commands outside of ContextSpeccedMusic would just
silently get eaten.  I prefer an explicit error, even if it is a Scheme
execution error.  It is close enough to the cause to be informative.

Proposal for a comment expressing that better?

Description:
Add layout changing command \layout-from for getting context defs from
music

Please review this at http://codereview.appspot.com/5686046/

Affected files:
  A input/regression/layout-from.ly
  M ly/context-mods-init.ly


Index: input/regression/layout-from.ly
diff --git a/input/regression/layout-from.ly b/input/regression/layout-from.ly
new file mode 100644
index 0000000000000000000000000000000000000000..2c0669a2fe56a0b629d1903c31a4badc32a513fb
--- /dev/null
+++ b/input/regression/layout-from.ly
@@ -0,0 +1,19 @@
+\version "2.15.31"
+
+\header {
+  texidoc = "
address@hidden 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 }
+  }
+}
Index: ly/context-mods-init.ly
diff --git a/ly/context-mods-init.ly b/ly/context-mods-init.ly
index 087d4bb155e1a37464111fd584c8a949031fab38..86edbb0d963b105314141076a471a25867d7c654 100644
--- a/ly/context-mods-init.ly
+++ b/ly/context-mods-init.ly
@@ -31,3 +31,70 @@ 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
address@hidden that may work in multiple or unknown
+contexts.
+
+Layout instructions specified for @samp{Bottom} (the default) are
+mapped to the symbol optionally specified as @var{bottom}, defaulting
+to @code{'Voice}.
+")
+   (let loop ((m music) (mods #f))
+     ;; layout instruction events can't really occur outside of
+     ;; ContextSpeccedMusic, so we can initialize with #f here and
+     ;; bomb out when this happens because of bad music created within
+     ;; Scheme.
+     (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)
+           (for-each (lambda (x)
+                       (loop x 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))





reply via email to

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