[PATCH] Add `origin-variable` property to music objects assigned to variables

Aura Kelloniemi <[email protected]> Sat, 27 Jun 2026 18:47:55 +0300
Newsgroups gmane.comp.gnu.lilypond.devel
Message-ID <[email protected]>
--=-=-=
Content-Type: text/plain

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


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment; filename=lilypond-origin-variable.patch

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

--=-=-=--