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);

Reply via email to