lilypond-user
[Top][All Lists]
Advanced

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

Re: Understanding ly:parser-include-string


From: David Kastrup
Subject: Re: Understanding ly:parser-include-string
Date: Wed, 27 Jan 2016 18:22:07 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/25.1.50 (gnu/linux)

Urs Liska <address@hidden> writes:

> Hi,
>
> I'm running into an issue with including files using
> ly:parser-include-string.
>
> The underlying task is that I want to conditionally include files, so I
> have the pseudo-code:
>
> #(if (some-condition)
>      (ly:parser-include-string "\\include \"some-file.ily\""))
>
> This works pretty well for single items. It is also possible to insert
> multiple \include-s in the string, and all files are loaded. However,
> when a file defines anything, subsequently included files don't have
> access to it. It seems the whole conditional expression has to be
> evaluated until the new definitions are available.

Of course it has.  You are in the middle of the interpretation of a
Scheme form.  ly:parser-include-string works with the _current_ parser
by default.  Something like

#(ly:parser-include-string "theme = { c1 d }")

\addlyrics { Hi ho }

\displayMusic \theme

creates a single music expression and displays it.  How would that work
if you wanted to reference `theme' in the expression itself?  If you
want an _independent_ parser, clone it.

#(begin
  (ly:parser-parse-string (ly:parser-clone)
   "\\language #default-language
theme = { c1 d }")
  (displayScheme theme))

\displayLilyMusic \theme

will work as expected, using a fresh parser.  Note that the cloned
parser will not have a language set by default.

> And if I only include this single some-file.ily this can again include
> multiple files (with regular LilyPond syntax). And again, files
> included that way don't have access to definitions (variables,
> functions) that are in files included earlier.

I have no idea what you are talking about here.

> The same is true for modules.
> If this some-file.ily uses a module-1 and later a module-2 module-2
> doesn't have access to items defined in module-1.

Again, I have no idea what you are talking about.  If you are using
use-module, then the modules themselves will only see variables imported
into them and provide variables exported by them.  That's pretty much
the whole point of modules.

> In a way I need something like the (let* construct but for
> ly:parser-include-string.
>
> Can someone confirm that my observation is correct (and intentional)?

ly:parser-include-string arranges for the string to be processed when
the parser resumes operation next by pushing it on its stack.  Maybe you
are confused about the effect of multiple uses of
ly:parser-include-string:

#(begin
  (ly:parser-include-string "#(display \"1\\n\")")
  (ly:parser-include-string "#(display \"2\\n\")"))

This will output first 2, then 1.  In general, it is a bad idea to
accumulate uses of ly:parser-include-string.  You are better off
building a single string which you then use, to wit:

#(begin
  (ly:parser-include-string
    (string-concat
       (if ... ... "")
       (if ... ... "")
       (if ... ... ""))))

> And is there a solution for my original problem: conditionally
> including files with multiple secondary includes?

There is no problem with that.

-- 
David Kastrup



reply via email to

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