Han-Wen,
actually, I would strongly welcome to see some kind of formal definition
of the structure of lily music, maybe something analogous to an XML Schema
definition, but for guile/scheme instead of XML:
When implementing the "\ligature { <music expression> }" command (see
ly/gregorian-init.ly), I finally figured out that the structure of music
expressions was somewhat different from what I naively expected. I did
not realize this until I used Nicolas' \displayMusic function (which he
sent to this list a couple of months ago), which helped me a lot in
discovering the internal structure of music expressions in scheme (looking
at the lily source code scattered over the whole source tree would
probably have taken a tremendously bigger amount of time). If I would
have had a formal definition of the structure, I would have been able to
implement it directly from the specification rather than exploring with
Nicolas' function how e.g. "\[ a \pes b \]" finally maps to scheme data
structure.
Having a formal definition probably also would allow for automatically
creating the \displayLilyMusic function (if not, I probably wouldn't
call it a (sufficiently complete) formal definition). This should solve
the maintenance problem of the \displayLilyMusic function that you are
mentioning (or at least reduce it to maintaining the formal definition).
Moreover, on the long term with some additional glue code, the
\displayLilyMusic function could lead to a smarter convert-ly that catches
more conversions correctly (though, as Nicolas shows, with the current
implementation, transpose information and probably more things like
comments get lost).
In general, having a central place, where the structure of the scheme
representation of music expressions is well specified, probably would help
very much in developing any scheme function that processes music. And it
could also be used to generate programming documentation.
Just a view thoughts...
Juergen
On Sun, 22 May 2005, Nicolas Sceaux wrote:
Han-Wen Nienhuys <[EMAIL PROTECTED]> writes:
Nicolas Sceaux wrote:
I have an nearly complete implementation of a \displayLilyMusic
command.
\displayLilyMusic \new Voice { \clef alto \time 3/4 \key g
\minor c'2. |
\once \override TextScript #'padding = #2
d'2 e'4^\markup { \bold { hello \italic world ! } }
}
==>
\new Voice {
\clef "alto"
\time 3/4
\key g \minor
c'2. |
\once \override TextScript #'padding = #2
d'2 e'4^\markup \line { \bold "hello" \bold \italic "world" \bold
"!"} }
\displayLilyMusic \transpose c' a { <c e> <d f> }
==>
{ < a, cis > < b, d > }
Should there be such a command inside the LilyPond distribution?
it would be wonderful to have it. My only reservation is
maintainability. How sensitive is this to breakage when we change the
music implementation (property names, etc?)
This is indeed a major concern. Of course, the print method for a
music type will stop working if the relevant property names are changed.
Here is an example of such a method:
(define-primary-print-method TimeScaledMusic (times)
(parameterize ((*force-line-break* #f)
(*time-factor-numerator* (ly:music-property times 'numerator))
(*time-factor-denominator* (ly:music-property times
'denominator)))
(format #f "\\times ~a/~a ~a"
(*time-factor-numerator*)
(*time-factor-denominator*)
(print-lily-music (ly:music-property times 'element)))))
in this case, if numerator and denominator names change, it will print
something like:
\times ()/() { ... }
Or if it is the element property that changes, it will print:
\times 3/4 %{ expecting a music expression: () %}
If a print method is not implemented for some music type:
%{ Print method not implemented for music type StrangeEvent %}
When I have finished implementing methods for the remaining music
types, I'll send here the code. (I've just seen some improvements to
do also).
;;BusyPlayingEvent
;;ClusterNoteEvent
;;FoldedRepeatedMusic
;;LyricCombineMusic
;;MelismaPlayingEvent
;;MultiMeasureTextEvent
;;NewLyricCombineMusic
;;NoteGroupingEvent
;;OutputPropertySetMusic
;;PartCombineMusic
;;PesOrFlexaEvent
;;QuoteMusic
;;ScriptEvent
;;SoloOneEvent
;;SoloTwoEvent
;;StartPlayingEvent
;;UnaCordaEvent
;;UnisonoEvent
;;UnrelativableMusic
;;UntransposableMusic
A music pattern matcher was defined for recognizing some more complex
expressions, eg:
(add-print-method ContextSpeccedMusic (expr)
"If `expr' is a bar, return \"\\bar ...\".
Otherwise, return #f."
(with-music-match (expr (music
'ContextSpeccedMusic
element (music
'ContextSpeccedMusic
context-type 'Timing
element (music
'PropertySet
value ?bar-type
symbol 'whichBar))))
(format #f "\\bar \"~a\"~a" ?bar-type (print-lily-new-line))))
Here, if the implementation of bars changes somewhat, the default
methods for contexts and property sets will be called.
\context Score \set Timing . whichBar = #"||"
nicolas
_______________________________________________
lilypond-devel mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/lilypond-devel
_______________________________________________
lilypond-devel mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/lilypond-devel