Hi,
I'm writing a program that uses LilyPond's music tree to export music to other
formats, initially braille music. I discussed this once on the lilypond-user
mailing list. Right now I have a Scheme exporter that turns LilyPond's music
tree into an S-expression, including all property values.
However, I'm running into a big problem. Many LilyPond commands are defined as
variables. These commands are often semantically quite meaningful, such as the
\voiceXXX commands defined in property-init.ly. When I traverse the music tree
in Scheme, these commands have already been expanded, and it becomes very hard
to relate them back to the original commands.
In my program, I'd like to preserve as much semantic information as possible.
For example, a voice setup written with \voiceXXX commands is much easier to
interpret than the property overrides those commands expand to.
It occurred to me that if LilyPond stored the original command name in the
expanded music expression, there would not be need for trying to analyze the
generated overrides to guess what the original command was.
Attached is a patch that adds two lines to LilyPond's parser.yy file. It
changes the assignment rule so that it sets an `origin-variable` property on
each music expression assigned to a variable. The patch is trivial and, from my
limited testing, seems to work.
So I have a few questions:
1. Would this be a reasonable addition to LilyPond? Do you see any objections
to storing optional metadata like `origin-variable` on music objects?
2. If this approach isn't acceptable, is there some other mechanism LilyPond
could provide for preserving the identity of named commands through the parser?
3. Would `origin-variable` be a sensible property name?
Caveat: I'm not a LilyPond internals expert in any way, so I apologize, if I'm
overlooking some very basic things.
The alternative I considered was to use the `origin` property to locate the
sources of all processed files and analyze them to detect variable expansions.
But that seems pretty hacky, and it would require a lot of extra work, such as
loading all included files, which LilyPond already does anyway.
Thanks very much in advance!
--
Aura
diff --git a/lily/parser.yy b/lily/parser.yy
index f5d34d71d9..74b7e5154e 100644
--- a/lily/parser.yy
+++ b/lily/parser.yy
@@ -748,8 +748,10 @@ assignment_id:
assignment:
assignment_id '=' identifier_init {
- parser->lexer_->set_identifier ($1, $3);
- $$ = SCM_UNSPECIFIED;
+ if (Music *m = unsmob<Music> ($3))
+ set_property (m, "origin-variable", $1);
+ parser->lexer_->set_identifier ($1, $3);
+ $$ = SCM_UNSPECIFIED;
}
| assignment_id '.' property_path '=' identifier_init {
SCM path = scm_cons ($1, $3);