Re: Output lilypond file with variables/functions applied?

2024-07-01 Thread Valentin Petzel
Hello Dimitri,

> My use case is that I want to manually change the accidentals of some
> specific pitches that were re-pitched using transpose for better
> readability.

It seems to me that you are trying to use enharmonics to avoid some unnatural 
transposed accidentals. Have a look at this snippet, maybe this does what you 
want to do:

https://lilypond.org/doc/v2.25/Documentation/snippets/pitches_003a-transposing-pitches-with-minimum-accidentals-_0028_0022smart_0022-transpose_0029

Cheers,
Valentin

signature.asc
Description: This is a digitally signed message part.


Re: Output lilypond file with variables/functions applied?

2024-06-29 Thread Dmitri Volkov
displayLilyMusic seems to be exactly what I was looking for, thank you 
very much!


On 2024-06-29 5:07 p. m., Timothy Lanfear wrote:

On 29/06/2024 21:16, Dmitri Volkov wrote:
Is there a way to get Lilypond to output a file with variables and 
functions applied?


The displayLilyMusic function covers at least the case of 
transposition, and possibly other things as well.


See 
https://lilypond.org/doc/v2.24/Documentation/notation/displaying-lilypond-notation



--
Timothy Lanfear, Bristol, UK.





Re: Output lilypond file with variables/functions applied?

2024-06-29 Thread Dmitri Volkov
Thank you for the response! New to Lilypond and was not aware of tags, 
I'll have to play around with them.




Re: Output lilypond file with variables/functions applied?

2024-06-29 Thread Timothy Lanfear

On 29/06/2024 21:16, Dmitri Volkov wrote:
Is there a way to get Lilypond to output a file with variables and 
functions applied?


The displayLilyMusic function covers at least the case of transposition, 
and possibly other things as well.


See 
https://lilypond.org/doc/v2.24/Documentation/notation/displaying-lilypond-notation



--
Timothy Lanfear, Bristol, UK.


Re: Output lilypond file with variables/functions applied?

2024-06-29 Thread Simon Albrecht

Hi Dimitri,

On 29.06.24 22:16, Dmitri Volkov wrote:

Hello,

Is there a way to get Lilypond to output a file with variables and 
functions applied?


No, there isn’t. Depending on your setup, the best tool for this purpose 
may be within the editor (Frescobaldi or other?), possibly using the 
python-ly library if you want to work on the command line (though I 
haven’t used that directly myself), or you’ll want to use a different 
approach:


My use case is that I want to manually change the accidentals of some 
specific pitches that were re-pitched using transpose for better 
readability.


That sounds like you might want to use tags for those specific notes. I 
call those tags cisharm and transharm: one alternative is this side of 
an enharmonic transformation, the other is on the other side of the 
transformation.


%%
\version "2.24.3"
\tagGroup cisharm,transharm

music = {
  \tag cisharm { cis'1 }
  \tag transharm { des'1 }
}

\keepWithTag cisharm \music
\transpose c cis \keepWithTag cisharm \music
\transpose c cis \keepWithTag transharm \music
%%

Hope that helps!



Output lilypond file with variables/functions applied?

2024-06-29 Thread Dmitri Volkov

Hello,

Is there a way to get Lilypond to output a file with variables and 
functions applied? For example, if I have a file like:


-
\version "2.24.3"

stuff = { c4 c4 c4 c4 | }

\stuff
\stuff
\transpose c4 d4 { \stuff }
\stuff
-

then is there a way to get Lilypond to output something like the following?

-
\version "2.24.3"

stuff = { c4 c4 c4 c4 | }

c4 c4 c4 c4 |
c4 c4 c4 c4 |
d4 d4 d4 d4 |
c4 c4 c4 c4 |
-

My use case is that I want to manually change the accidentals of some 
specific pitches that were re-pitched using transpose for better 
readability.


Thank you!
~Dmitri



Re: Can't call some functions from translation-functions

2023-12-16 Thread Sebastian Käppler
And that did the trick. Thank you very much, now I can get to actually work
on my markup...

Am Sa., 16. Dez. 2023 um 14:28 Uhr schrieb Aaron Hill <
lilyp...@hillvisions.com>:

> On 2023-12-16 5:27 am, Aaron Hill wrote:
> > On 2023-12-16 5:20 am, Sebastian Käppler wrote:
> >> Hello Aaron,
> >>
> >> thanks for your response. I tried use-modules and got "
> >>
> >> no code for module (scm display-lily)".
> >>
> >> If that is of interest, I use Frescobaldi on Windows with lilypond
> >> 2.24.1.
> >
> > Oh, whoops.  I'm still back on 2.22.0, myself.
> >
> > I think it's (use-modules (lily display-lily)) now.
>
> Sigh, and adding the mailing list back to the thread for visibility.
> Sorry about that.
>
>
> -- Aaron Hill
>


Re: Can't call some functions from translation-functions

2023-12-16 Thread Aaron Hill via LilyPond user discussion

On 2023-12-16 5:27 am, Aaron Hill wrote:

On 2023-12-16 5:20 am, Sebastian Käppler wrote:

Hello Aaron,

thanks for your response. I tried use-modules and got "

no code for module (scm display-lily)".

If that is of interest, I use Frescobaldi on Windows with lilypond 
2.24.1.


Oh, whoops.  I'm still back on 2.22.0, myself.

I think it's (use-modules (lily display-lily)) now.


Sigh, and adding the mailing list back to the thread for visibility.  
Sorry about that.



-- Aaron Hill



Re: Can't call some functions from translation-functions

2023-12-16 Thread Aaron Hill via LilyPond user discussion

On 2023-12-16 4:48 am, Sebastian Käppler wrote:

Hello,

I'm trying to use some of the functions in translation-functions.scm to
create my own note name markup. However, if I use 
note-name->lily-string or
octave->lily-string, I get an "unbound variable" error for that 
function. I
even tried to copy the whole note-name-markup code from the source to 
my
code and rename it to note-name-custom-markup. But if I use this in 
\set

noteNameFunction, I get that same error.
Sorry if this is a dumb question, but I'm still trying to familiarize
myself with most concepts of scheme...


Odd.  A function like note-name->lily-string is exported from 
define-music-display-methods.scm.


Have you tried adding an explicit...

  (use-modules (scm display-lily))

...in your source file?


-- Aaron Hill



Can't call some functions from translation-functions

2023-12-16 Thread Sebastian Käppler
Hello,

I'm trying to use some of the functions in translation-functions.scm to
create my own note name markup. However, if I use note-name->lily-string or
octave->lily-string, I get an "unbound variable" error for that function. I
even tried to copy the whole note-name-markup code from the source to my
code and rename it to note-name-custom-markup. But if I use this in \set
noteNameFunction, I get that same error.
Sorry if this is a dumb question, but I'm still trying to familiarize
myself with most concepts of scheme...

Kind regards!


Re: Using markup-like functions outside of markup (layout/props)

2023-09-23 Thread Jean Abou Samra
> Just quickly though, is that to say that it's hard to inject the layout and
> props outside of a markup command/block? 


This is a bit like asking if it's hard to find a book outside of a library. Not
really, but finding the specific book that you want may or may not be feasible.



signature.asc
Description: This is a digitally signed message part


Re: Using markup-like functions outside of markup (layout/props)

2023-09-23 Thread Kyle Baldwin
Jean - 

Thank you again, I think I can fiddle with this and make this work. 

Just quickly though, is that to say that it's hard to inject the layout and 
props outside of a markup command/block? 

-kwb 

> On Sep 23, 2023, at 12:43 PM, Jean Abou Samra  wrote:
> 
> Take a look at
> 
> https://lists.gnu.org/archive/html/lilypond-user/2023-09/msg00136.html
> 
> which I posted just a few days ago in reply to another question. It's a piece 
> of Scheme code that auto-adds a blank page when needed.



Re: Using markup-like functions outside of markup (layout/props)

2023-09-23 Thread Jean Abou Samra
Take a look at

https://lists.gnu.org/archive/html/lilypond-user/2023-09/msg00136.html

which I posted just a few days ago in reply to another question. It's a piece of
Scheme code that auto-adds a blank page when needed.


signature.asc
Description: This is a digitally signed message part


Re: Using markup-like functions outside of markup (layout/props)

2023-09-23 Thread Kyle Baldwin
Jean - 

The part I care about is whether it starts on a left or right hand page. 

What I am doing is the following: 

- Compile lilypond score  
- Output meta data to a CSV file (I'm using scheme to write out variables like 
the title and such. This is where I would like to add the metadata about 
even/odd or right/left first page) 
- Import the CSV into Affinity publisher to generate the cover from a template 
- using PDFTK to merge the PDF's 

And this works great. However, what I need to know is if the first couple of 
pages should go 

Cover -> First page of score 

OR 

Cover -> Blank page -> first page of score  

depending on if the first page of the score is a "left" or "right" page. I know 
that I can tell lilypond to force a first page number, but would rather allow 
the layout engine to be more free. And obviously, opening the file and looking 
at the page number is trivial, but I hope to just automate this. 

Let me know if that answers your questions! Thanks! 

-kwb 


> On Sep 23, 2023, at 11:55 AM, Jean Abou Samra  wrote:
> 
>> 
>> I'm trying to use the `book-first-page` scheme function to write the first 
>> page to a file in order to do some automated score processing. 
>> `book-first-page` takes the layout and props arguments, however, I'm having 
>> a hard time wrapping my head around accessing the layout and props 
>> properties without using a \markup command. 
>> 
>> Does anyone have any guidance on this and/or a better way to get the first 
>> page programmatically. Thank you! 
> 
> 
> By "write the first page", do you mean "write the first page as a PDF" or 
> similar, or "write the page number of the first page"? Because 
> book-first-page merely returns the *number* of the first page of the book.
> 
> Could you explain what you're trying to do? The answer largely depends on 
> what you actual goal is.



Re: Using markup-like functions outside of markup (layout/props)

2023-09-23 Thread Jean Abou Samra

> I'm trying to use the `book-first-page` scheme function to write the first
> page to a file in order to do some automated score processing. `book-first-
> page` takes the layout and props arguments, however, I'm having a hard time
> wrapping my head around accessing the layout and props properties without
> using a \markup command. 
> 
> Does anyone have any guidance on this and/or a better way to get the first
> page programmatically. Thank you! 


By "write the first page", do you mean "write the first page as a PDF" or
similar, or "write the page number of the first page"? Because book-first-page
merely returns the *number* of the first page of the book.

Could you explain what you're trying to do? The answer largely depends on what
you actual goal is.


signature.asc
Description: This is a digitally signed message part


Using markup-like functions outside of markup (layout/props)

2023-09-23 Thread Kyle Baldwin
Hello - 

I'm trying to use the `book-first-page` scheme function to write the first page 
to a file in order to do some automated score processing. `book-first-page` 
takes the layout and props arguments, however, I'm having a hard time wrapping 
my head around accessing the layout and props properties without using a 
\markup command. 

Does anyone have any guidance on this and/or a better way to get the first page 
programmatically. Thank you! 

-Kyle 


Re: Using functions "parenthesize" in lilypond 2.24.1

2023-07-11 Thread Jean Abou Samra
Le mardi 11 juillet 2023 à 12:19 +0300, Виноградов Юрий a écrit :

> Hello. I'm typing an accordion part. And in my left hand I need to put a note 
> in the \parenthesize function. But since this note takes up space in the 
> measure. Example: beat 2/4 and note 1/8 - it turns out to be 5/8 in a beat. 
> To make everything look good in the other hand, I either put the size of 5/8 
> in this tact and add an invisible pause (s8). Or I type in these bars with 
> the \cadenzaOn function. Can you tell me how to leave the measure in the 
> normal 2/4 size and have this note with the \parenthesize function not be 
> counted in the measure.




I don't know accordion notation, but: isn't this a grace note? If so, you 
should just use the \grace command like so:

```
\version "2.24.1"

<<
  \new Staff {
\time 2/4
\grace s8
d'2
  }
  \new Staff {
\time 2/4
\grace \parenthesize c'8
d'2
  }
>>
```

Note that you might get trouble if you do not have parallel graces (a problem 
famous as “issue #34”), so you should use a grace skip in the upper staff.

Best,

Jean


signature.asc
Description: This is a digitally signed message part


Re: Using functions "parenthesize" in lilypond 2.24.1

2023-07-11 Thread Виноградов Юрий
Ok. Thanks. Юрий Виноградов12:57, 11 июля 2023 г., Jean Abou Samra :Le mardi 11 juillet 2023 à 12:54 +0300, Виноградов Юрий a écrit :How will be correct. Tell.To create a new topic on this list, you should send a new email to lilypond-user@gnu.org . You should use the same method as to create a new email to anybody. You should not take a digest you received and reply to it.Best,Jean




Re: Using functions "parenthesize" in lilypond 2.24.1

2023-07-11 Thread Виноградов Юрий
ok. С уважением,Виноградов Юрий.11.07.2023, 12:59, "David Kastrup" :Виноградов Юрий  writes: 12:51, 11 июля 2023 г., David Kastrup :  Please never, never, never, ever quote an entire week's digest to the  list with any new post to the list. The entirety of your mail,  including the last week's digest, will clog up the next week's digest.  And so the digests will keep piling up. How will be correct. Tell.You don't quote what isn't relevant.  It just clogs up the listunnecessarily.  Since you did not refer to anything at all from thedigest, you don't quote the digest _at_ _all_.Instead you write a _new_ message and send it to the list address.  Youdon't "reply" to some old message, let alone a whole digest.-- David Kastrup

Re: Using functions "parenthesize" in lilypond 2.24.1

2023-07-11 Thread David Kastrup
Виноградов Юрий  writes:

> 12:51, 11 июля 2023 г., David Kastrup :
>>
>>  Please never, never, never, ever quote an entire week's digest to the
>>  list with any new post to the list. The entirety of your mail,
>>  including the last week's digest, will clog up the next week's digest.
>>  And so the digests will keep piling up.
>
> How will be correct. Tell.

You don't quote what isn't relevant.  It just clogs up the list
unnecessarily.  Since you did not refer to anything at all from the
digest, you don't quote the digest _at_ _all_.

Instead you write a _new_ message and send it to the list address.  You
don't "reply" to some old message, let alone a whole digest.

-- 
David Kastrup



Re: Using functions "parenthesize" in lilypond 2.24.1

2023-07-11 Thread Jean Abou Samra
Le mardi 11 juillet 2023 à 12:54 +0300, Виноградов Юрий a écrit :
> How will be correct. Tell.


To create a new topic on this list, you should send a new email to
lilypond-user@gnu.org . You should use the same method as to create a new email
to anybody. You should not take a digest you received and reply to it.

Best,

Jean



signature.asc
Description: This is a digitally signed message part


Re: Using functions "parenthesize" in lilypond 2.24.1

2023-07-11 Thread Виноградов Юрий
How will be correct. Tell.Юрий Виноградов12:51, 11 июля 2023 г., David Kastrup :Виноградов Юрий  writes: Hello. I'm typing an accordion part. And in my left hand I need to put a note in the \parenthesize function. But since this note takes up space in the measure. Example: beat 2/4 and note 1/8 - it turns out to be 5/8 in a beat. To make everything look good in the other hand, I either put the size of 5/8 in this tact and add an invisible pause (s8). Or I type in these bars with the \cadenzaOn function. Can you tell me how to leave the measure in the normal 2/4 size and have this note with the \parenthesize function not be counted in the measure.   Thank you all in advance.Please never, never, never, ever quote an entire week's digest to thelist with any new post to the list.  The entirety of your mail,including the last week's digest, will clog up the next week's digest.And so the digests will keep piling up.-- David Kastrup

Re: Using functions "parenthesize" in lilypond 2.24.1

2023-07-11 Thread David Kastrup
Виноградов Юрий  writes:

> Hello. I'm typing an accordion part. And in my left hand I need to put
> a note in the \parenthesize function. But since this note takes up
> space in the measure. Example: beat 2/4 and note 1/8 - it turns out to
> be 5/8 in a beat. To make everything look good in the other hand, I
> either put the size of 5/8 in this tact and add an invisible pause
> (s8). Or I type in these bars with the \cadenzaOn function. Can you
> tell me how to leave the measure in the normal 2/4 size and have this
> note with the \parenthesize function not be counted in the measure.
>  
> Thank you all in advance.

Please never, never, never, ever quote an entire week's digest to the
list with any new post to the list.  The entirety of your mail,
including the last week's digest, will clog up the next week's digest.
And so the digests will keep piling up.

-- 
David Kastrup



Using functions "parenthesize" in lilypond 2.24.1

2023-07-11 Thread Виноградов Юрий
Hello. I'm typing an accordion part. And in my left hand I need to put a note in the \parenthesize function. But since this note takes up space in the measure. Example: beat 2/4 and note 1/8 - it turns out to be 5/8 in a beat. To make everything look good in the other hand, I either put the size of 5/8 in this tact and add an invisible pause (s8). Or I type in these bars with the \cadenzaOn function. Can you tell me how to leave the measure in the normal 2/4 size and have this note with the \parenthesize function not be counted in the measure. Thank you all in advance. Translated with www.DeepL.com/Translator (free version) С уважением,Виноградов Юрий.   04.04.2023, 03:53, "lilypond-user-requ...@gnu.org" :Send lilypond-user mailing list submissions tolilypond-user@gnu.orgTo subscribe or unsubscribe via the World Wide Web, visithttps://lists.gnu.org/mailman/listinfo/lilypond-useror, via email, send a message with subject or body 'help' tolilypond-user-requ...@gnu.orgYou can reach the person managing the list atlilypond-user-ow...@gnu.orgWhen replying, please edit your Subject line so it is more specificthan "Re: Contents of lilypond-user digest..."Today's Topics:   1. Creating Text with Hyperlinks (Ken Ledeen)   2. Re: Creating Text with Hyperlinks (Jean Abou Samra)   3. Re: Creating Text with Hyperlinks (Jean Abou Samra)   4. Custom engraver to draw frame around notes (Nate Whetsell)   5. Re: Custom engraver to draw frame around notes (Jean Abou Samra)--Message: 1Date: Mon, 3 Apr 2023 19:15:19 -0400From: Ken Ledeen To: lilypond-user@gnu.orgSubject: Creating Text with HyperlinksMessage-ID:Content-Type: text/plain; charset="utf-8"Hello All,I would like to be able to add conventional text to a score, but provideassociated hyperlinks in the PDF.  FOr example, the title might have ahyperlink to a youtube video of the score being performed.So far, I've not found anything in the documentation that would supportthis functionalityKen LedeenMobile:   617-817-3183www.nevo.comwww.bitsbook.comtiny.cc/KenLedeen -- next part --An HTML attachment was scrubbed...URL: --Message: 2Date: Tue, 04 Apr 2023 01:25:22 +0200From: Jean Abou Samra To: Ken Ledeen , lilypond-user@gnu.orgSubject: Re: Creating Text with HyperlinksMessage-ID:<43ebef711865338fcc5472c2b3806358cccfd93b.ca...@abou-samra.fr>Content-Type: text/plain; charset="utf-8"Le lundi 03 avril 2023 à 19:15 -0400, Ken Ledeen a écrit : Hello All,   I would like to be able to add conventional text to a score, but provide associated hyperlinks in the PDF.  FOr example, the title might have a hyperlink to a youtube video of the score being performed.  So far, I've not found anything in the documentation that would support this functionality  Look for “URL” in the notation manual's indexhttps://lilypond.org/doc/v2.24/Documentation/notation/lilypond-index.htmlBest,Jean-- next part --An HTML attachment was scrubbed...URL: -- next part --A non-text attachment was scrubbed...Name: signature.ascType: application/pgp-signatureSize: 228 bytesDesc: This is a digitally signed message partURL: --Message: 3Date: Tue, 04 Apr 2023 01:27:31 +0200From: Jean Abou Samra To: Ken Ledeen , lilypond-user@gnu.orgSubject: Re: Creating Text with HyperlinksMessage-ID:Content-Type: text/plain; charset="utf-8"Le mardi 04 avril 2023 à 01:25 +0200, Jean Abou Samra a écrit : Le lundi 03 avril 2023 à 19:15 -0400, Ken Ledeen a écrit :  > Hello All,   >  I would like to be able to add conventional text to a score, but provide associated hyperlinks in the PDF.  FOr example, the title might have a hyperlink to a youtube video of the score being performed. > So far, I've not found anything in the documentation that would support this functionality  Look for “URL” in the notation manual's index   https://lilypond.org/doc/v2.24/Documentation/notation/lilypond-index.html  PS: In version 2.25.3 (released last Saturday), there is also a `\qr-code` command, which may be better if you want to print the scores.-- next part --An HTML attachment was scrubbed...URL: -- next part --A non-text 

Re: Tutorial on writing lilypond functions?

2023-04-05 Thread Eef Weenink
Found: https://extending-lilypond.gitlab.io/en/scheme/functions.html
I go from there.

Op 6 apr. 2023, om 08:38 heeft Eef Weenink 
mailto:h.e.ween...@de-erve.nl>> het volgende geschreven:

Using arranger.ly<http://arranger.ly/> (thanks to Gilbert :-)) I am now at the 
point I want to automate more. And next step is probably working with scheme 
functions. Using https://lsr.di.unimi.it/LSR/Item?id= as a starter.

As soon I try to change something I run into the fact that I don't know enough 
about writing the function. So searching for a tutorial, examples, manual to 
get a better start?

Where should I go?

Regards, Eef



Tutorial on writing lilypond functions?

2023-04-05 Thread Eef Weenink
Using arranger.ly<http://arranger.ly> (thanks to Gilbert :-)) I am now at the 
point I want to automate more. And next step is probably working with scheme 
functions. Using https://lsr.di.unimi.it/LSR/Item?id= as a starter.

As soon I try to change something I run into the fact that I don't know enough 
about writing the function. So searching for a tutorial, examples, manual to 
get a better start?

Where should I go?

Regards, Eef


Re: Making two functions into one

2023-01-16 Thread David Kastrup
Jean Abou Samra  writes:

> There is also
>
> https://extending-lilypond.readthedocs.io/en/latest/lily-and-scheme.html#hash-vs-dollar
>
> (This is an instance where the official extending manual seems
> much too technical and example-less to me ...)

Well, as developer I tend to write up basic descriptions of
functionality, in the expectation that somebody™ will take it up and
translate it into something more digestible.  It's more "documentation"
of what I did than hands-on instructions.  Writing examples is way more
arbitrary than writing functionality, so it's a comparatively painful
mental effort I tend not to end up vigourously embracing.

Sorry for that.

-- 
David Kastrup



Re: Making two functions into one

2023-01-16 Thread Jean Abou Samra

Le 16/01/2023 à 22:58, David Kastrup a écrit :

 From the Lilypond-Extending manual:

1.2.1 LilyPond Scheme syntax


The Guile interpreter is part of LilyPond, which means that Scheme can
be included in LilyPond input files.  There are several methods for
including Scheme in LilyPond.

The simplest way is to use a hash mark ‘#’ before a Scheme
expression.

Now LilyPond’s input is structured into tokens and expressions, much
like human language is structured into words and sentences.  LilyPond
has a lexer that recognizes tokens (literal numbers, strings, Scheme
elements, pitches and so on), and a parser that understands the syntax,
*note (lilypond-contributor)LilyPond grammar::.  Once it knows that a
particular syntax rule applies, it executes actions associated with it.

The hash mark ‘#’ method of embedding Scheme is a natural fit for
this system.  Once the lexer sees a hash mark, it calls the Scheme
reader to read one full Scheme expression (this can be an identifier, an
expression enclosed in parentheses, or several other things).  After the
Scheme expression is read, it is stored away as the value for an
‘SCM_TOKEN’ in the grammar.  Once the parser knows how to make use of
this token, it calls Guile for evaluating the Scheme expression.  Since
the parser usually requires a bit of lookahead from the lexer to make
its parsing decisions, this separation of reading and evaluation between
lexer and parser is exactly what is needed to keep the execution of
LilyPond and Scheme expressions in sync.  For this reason, you should
use the hash mark ‘#’ for calling Scheme whenever this is feasible.

Another way to call the Scheme interpreter from LilyPond is the use
of dollar ‘$’ instead of a hash mark for introducing Scheme expressions.
In this case, LilyPond evaluates the code right after the lexer has read
it.  It checks the resulting type of the Scheme expression and then
picks a token type (one of several ‘xxx_IDENTIFIER’ in the syntax) for
it.  It creates a _copy_ of the value and uses that for the value of the
token.  If the value of the expression is void (Guile’s value of
‘*unspecified*’), nothing at all is passed to the parser.

This is, in fact, exactly the same mechanism that LilyPond employs
when you call any variable or music function by name, as ‘\name’, with
the only difference that the name is determined by the LilyPond lexer
without consulting the Scheme reader, and thus only variable names
consistent with the current LilyPond mode are accepted.

The immediate action of ‘$’ can lead to surprises, see *note
Importing Scheme in LilyPond::.  Using ‘#’ where the parser supports it
is usually preferable.  Inside of music expressions, expressions created
using ‘#’ _are_ interpreted as music.  However, they are _not_ copied
before use.  If they are part of some structure that might still get
used, you may need to use ‘ly:music-deep-copy’ explicitly.

There are also ‘list splicing’ operators ‘$@’ and ‘#@’ that insert
all elements of a list in the surrounding context.




There is also

https://extending-lilypond.readthedocs.io/en/latest/lily-and-scheme.html#hash-vs-dollar

(This is an instance where the official extending manual seems
much too technical and example-less to me ...)




OpenPGP_signature
Description: OpenPGP digital signature


Re: Making two functions into one

2023-01-16 Thread David Kastrup
| || | |  writes:

> Thank you Valentin,
>
> That was simpler than I thought. Of curse I tried first with lily code
> blocks, but have been struggling with
>
>  \time #number/8 (which doesn't work because it needs pair but gets
> int).

It gets an undefined symbol called number/8 .

What you could write here is

   \time #(cons number 8)

It turns out that fractions cannot be assembled piecemeal in LilyPond
syntax.

> There is some kind of coding convention? Both # and $ seems to work
> the same.

>From the Lilypond-Extending manual:

1.2.1 LilyPond Scheme syntax


The Guile interpreter is part of LilyPond, which means that Scheme can
be included in LilyPond input files.  There are several methods for
including Scheme in LilyPond.

   The simplest way is to use a hash mark ‘#’ before a Scheme
expression.

   Now LilyPond’s input is structured into tokens and expressions, much
like human language is structured into words and sentences.  LilyPond
has a lexer that recognizes tokens (literal numbers, strings, Scheme
elements, pitches and so on), and a parser that understands the syntax,
*note (lilypond-contributor)LilyPond grammar::.  Once it knows that a
particular syntax rule applies, it executes actions associated with it.

   The hash mark ‘#’ method of embedding Scheme is a natural fit for
this system.  Once the lexer sees a hash mark, it calls the Scheme
reader to read one full Scheme expression (this can be an identifier, an
expression enclosed in parentheses, or several other things).  After the
Scheme expression is read, it is stored away as the value for an
‘SCM_TOKEN’ in the grammar.  Once the parser knows how to make use of
this token, it calls Guile for evaluating the Scheme expression.  Since
the parser usually requires a bit of lookahead from the lexer to make
its parsing decisions, this separation of reading and evaluation between
lexer and parser is exactly what is needed to keep the execution of
LilyPond and Scheme expressions in sync.  For this reason, you should
use the hash mark ‘#’ for calling Scheme whenever this is feasible.

   Another way to call the Scheme interpreter from LilyPond is the use
of dollar ‘$’ instead of a hash mark for introducing Scheme expressions.
In this case, LilyPond evaluates the code right after the lexer has read
it.  It checks the resulting type of the Scheme expression and then
picks a token type (one of several ‘xxx_IDENTIFIER’ in the syntax) for
it.  It creates a _copy_ of the value and uses that for the value of the
token.  If the value of the expression is void (Guile’s value of
‘*unspecified*’), nothing at all is passed to the parser.

   This is, in fact, exactly the same mechanism that LilyPond employs
when you call any variable or music function by name, as ‘\name’, with
the only difference that the name is determined by the LilyPond lexer
without consulting the Scheme reader, and thus only variable names
consistent with the current LilyPond mode are accepted.

   The immediate action of ‘$’ can lead to surprises, see *note
Importing Scheme in LilyPond::.  Using ‘#’ where the parser supports it
is usually preferable.  Inside of music expressions, expressions created
using ‘#’ _are_ interpreted as music.  However, they are _not_ copied
before use.  If they are part of some structure that might still get
used, you may need to use ‘ly:music-deep-copy’ explicitly.

   There are also ‘list splicing’ operators ‘$@’ and ‘#@’ that insert
all elements of a list in the surrounding context.


-- 
David Kastrup



Re: Making two functions into one

2023-01-16 Thread | || | |

Thank you Valentin,

That was simpler than I thought. Of curse I tried first with lily code 
blocks, but have been struggling with


 \time #number/8 (which doesn't work because it needs pair but gets int).

Would you like to short explain difference between usage of $ and # or 
point me to place when I can understand it?


There is some kind of coding convention? Both # and $ seems to work the 
same.


Cheers!

W dniu 16.01.2023 o 15:32, Valentin Petzel pisze:

Hello,

not sure about that one, but this seems to work:

\version "2.24.0"

nd =  #(define-music-function (number) (integer?)
  #{
#(time (cons number 8))
s8 * $number
  #})

\score {
\new Staff {

  \nd 8
  \nd 7
  
}

}

Cheers,
Valentin




Re: Making two functions into one

2023-01-16 Thread Jean Abou Samra

Le 16/01/2023 à 15:12, | || | | a écrit :

So I thought about delete one nested (list) and try it:

nd =  #(define-music-function (number) (integer?)
  (make-music
  'TimeSignatureMusic
  'numerator
  8
  'denominator
  8
  'beat-structure
  '())
    (make-music
  'UnfoldedRepeatedMusic
  'elements
  '()
  'repeat-count
  8
  'element
  (make-music
    'SequentialMusic
    'elements
    (list (make-music
    'SkipEvent
    'duration
    (ly:make-duration 3))


But the problem is, when I don't use (list) for two adjacent 
(make-music) functions, one of them doesn't run, so depending on the 
kind of second (make-music) code, one od them goes, another don't.





David already explained the missing 'origin. I just want to explain
why this drops the first expression: it has nothing to do with LilyPond,
it's just the way Scheme works. When you have a sequence of expressions
like this in the body of a function, they are evaluated in turn, and
the value of the last one is returned. The others are discarded. They
can only be useful if they have "side effects", like (display ...)
for example.

Best,
Jean



OpenPGP_signature
Description: OpenPGP digital signature


Re: Making two functions into one

2023-01-16 Thread David Kastrup
Valentin Petzel  writes:

> Hello,
>
> not sure about that one, but this seems to work:
>
> \version "2.24.0"
>
> nd =  #(define-music-function (number) (integer?)
>  #{
>#(time (cons number 8))
>s8 * $number
>  #})

LilyPond syntax expressions, like in #{ ... #}, attach origin
information automatically.  If you want things to happen automatically,
Scheme is not the way to go...

-- 
David Kastrup



Re: Making two functions into one

2023-01-16 Thread David Kastrup
| || | |  writes:

> I would like to make a function which will be responsible for two things:
>
> 1. Change time signature
>
> 2. Fill empty bar with 's8'
>
> I made this one, but there is a problem with point'n'click function,
> so I can't click on time signature to go to correspondent place in
> code:
>
> \version "2.24.0"
>
> nd =  #(define-music-function (number) (integer?)
>   (list (make-music
>   'SequentialMusic
>   'elements
>   (list (make-music
>   'TimeSignatureMusic
>   'numerator
>   number
>   'denominator
>   8
>   'beat-structure
>   '(

[...]

> So I thought about delete one nested (list) and try it:

> Honestly, I don't understand why it's like that, because when I run
> displayScheme{}, it display it properly without (list) and
> SquentialMusic for this two events. I suspect it could be something
> wrong with my definition.

You need to look closer at the difference of your displayScheme results.
Your above definition is missing the element

'origin (*location*)

in the make-music function arguments.  A music function automatically
tacks them onto the top music expression but not on everything below.
Without origin information, point-and-click has no way to know where to
go.  I am not sure what magic you imagine to be doing that job for
you...

-- 
David Kastrup



Re: Making two functions into one

2023-01-16 Thread Valentin Petzel
Hello,

not sure about that one, but this seems to work:

\version "2.24.0"

nd =  #(define-music-function (number) (integer?)
 #{
   #(time (cons number 8))
   s8 * $number
 #})

\score {
   \new Staff {

 \nd 8
 \nd 7
 
   }
}

Cheers,
Valentin

Am Montag, 16. Jänner 2023, 15:12:15 CET schrieb | || | |:
> Hi,
> 
> I would like to make a function which will be responsible for two things:
> 
> 1. Change time signature
> 
> 2. Fill empty bar with 's8'
> 
> I made this one, but there is a problem with point'n'click function, so
> I can't click on time signature to go to correspondent place in code:
> 
> \version "2.24.0"
> 
> nd =  #(define-music-function (number) (integer?)
> (make-music
>'SequentialMusic
>'elements
>(list (make-music
>'SequentialMusic
>'elements
>(list (make-music
>'TimeSignatureMusic
>'numerator
>number
>'denominator
>8
>'beat-structure
>'(
>  (make-music
>'UnfoldedRepeatedMusic
>'elements
>'()
>'repeat-count
>number
>'element
>(make-music
>  'SequentialMusic
>  'elements
>  (list (make-music
>  'SkipEvent
>  'duration
>  (ly:make-duration 3)))
>)
> 
> \score {
>\new Staff {
> 
>  \nd 8
>  \nd 7
>}
> }
> 
> 
> So I thought about delete one nested (list) and try it:
> 
> nd =  #(define-music-function (number) (integer?)
>(make-music
>'TimeSignatureMusic
>'numerator
>8
>'denominator
>8
>'beat-structure
>'())
>  (make-music
>'UnfoldedRepeatedMusic
>'elements
>'()
>'repeat-count
>8
>'element
>(make-music
>  'SequentialMusic
>  'elements
>  (list (make-music
>  'SkipEvent
>  'duration
>  (ly:make-duration 3))
> 
> 
> But the problem is, when I don't use (list) for two adjacent
> (make-music) functions, one of them doesn't run, so depending on the
> kind of second (make-music) code, one od them goes, another don't.
> 
> Honestly, I don't understand why it's like that, because when I run
> displayScheme{}, it display it properly without (list) and
> SquentialMusic for this two events. I suspect it could be something
> wrong with my definition.
> 
> 
> Thank you :)



signature.asc
Description: This is a digitally signed message part.


Making two functions into one

2023-01-16 Thread | || | |

Hi,

I would like to make a function which will be responsible for two things:

1. Change time signature

2. Fill empty bar with 's8'

I made this one, but there is a problem with point'n'click function, so 
I can't click on time signature to go to correspondent place in code:


\version "2.24.0"

nd =  #(define-music-function (number) (integer?)
   (make-music
  'SequentialMusic
  'elements
  (list (make-music
  'SequentialMusic
  'elements
  (list (make-music
  'TimeSignatureMusic
  'numerator
  number
  'denominator
  8
  'beat-structure
  '(
    (make-music
  'UnfoldedRepeatedMusic
  'elements
  '()
  'repeat-count
  number
  'element
  (make-music
    'SequentialMusic
    'elements
    (list (make-music
    'SkipEvent
    'duration
    (ly:make-duration 3)))
  )

\score {
  \new Staff {

    \nd 8
    \nd 7
  }
}


So I thought about delete one nested (list) and try it:

nd =  #(define-music-function (number) (integer?)
  (make-music
  'TimeSignatureMusic
  'numerator
  8
  'denominator
  8
  'beat-structure
  '())
    (make-music
  'UnfoldedRepeatedMusic
  'elements
  '()
  'repeat-count
  8
  'element
  (make-music
    'SequentialMusic
    'elements
    (list (make-music
    'SkipEvent
    'duration
    (ly:make-duration 3))


But the problem is, when I don't use (list) for two adjacent 
(make-music) functions, one of them doesn't run, so depending on the 
kind of second (make-music) code, one od them goes, another don't.


Honestly, I don't understand why it's like that, because when I run 
displayScheme{}, it display it properly without (list) and 
SquentialMusic for this two events. I suspect it could be something 
wrong with my definition.



Thank you :)




Re: \include in scheme functions

2022-02-27 Thread Jean Abou Samra




Le 27/02/2022 à 09:50, Pierre-Yves Saumont a écrit :

Hi,

The Lilypond documentation says that any lilypond code can be use in a 
Scheme function by enclosing it in a #{ ...  #} block, but it seems 
\include doesn't work in this case.


I am building a program to handle multiple Big Band scores. I need to 
extract parts for each instrument (16 to 22) and for all titles in a 
given program (10 - 15).


At this time, here is what I do:

\include "../Doxy/Doxy_music.ly"
\include "partAltoI.ly"
\include "../Alfie/Alfie_music.ly"
\include "partAltoI.ly"
\include "../CestSiBon/CestSiBon_music.ly"
\include "partAltoI.ly"
\include "../BeyondTheSea/BeyondTheSea_music.ly"
\include "partAltoI.ly"
\include "../CloseToYou/CloseToYou_music.ly"
\include "partAltoI.ly"
.
.
.
include "../Doxy/Doxy_music.ly"
\include "partAltoII.ly"
\include "../Alfie/Alfie_music.ly"
\include "partAltoII.ly"
\include "../CestSiBon/CestSiBon_music.ly"
\include "partAltoII.ly"
\include "../BeyondTheSea/BeyondTheSea_music.ly"
\include "partAltoII.ly"
\include "../CloseToYou/CloseToYou_music.ly"
\include "partAltoII.ly"
.
.
.
include "../Doxy/Doxy_music.ly"
\include "partTenorI.ly"
\include "../Alfie/Alfie_music.ly"
\include "partTenorI.ly"
\include "../CestSiBon/CestSiBon_music.ly"
\include "partTenorI.ly"
\include "../BeyondTheSea/BeyondTheSea_music.ly"
\include "partTenorI.ly"
\include "../CloseToYou/CloseToYou_music.ly"
\include "partTenorI.ly"
.
.
.

This is tedious, and I would like to be able to simply have to enter 
the list of titles:


Doxy
Alfie
CestSiBon
BeyondTheSea
CloseToYou
.
.
.

and the list of instruments:

AltoI
AltoII
TenorI
TenorII
Baritone
.
.
.

The result should be a series of PDF files, one for each 
instrument, containing the specific parts for all selected tunes.


I tried to write a function such as:

part = #(define-void-function (score instrument) (string? string?)
   #{
     \include "../Doxy/Doxy_music.ly"
     \include "partAltoI.ly"
   #})

(Here, I am not constructing the file names from the arguments, only 
testing the use of \include in the function.


This doesn't work, producing the following error:

.../include/LilyJAZZwithBarNums.ily:62:1 <0>: error: syntax error, 
unexpected SCM_TOKEN, expecting end of input


#(define jazz-map '(

/tmp/frescobaldi-1mgd5_wr/tmpys2kq_gz/March2022_parts_alto1.ly:13:1 
<1>: error: error in #{ ... #}


\part "Doxy" "AltoI"

The message says the error is in LilyJAZZwithBarNums.ily, but since 
the same instructions work when not in a function, I presume it's not 
related to this file.


Is there a way to make this work, or is there another way to achieve 
the intended result? For example, is there a way to read a lilypond 
variable from a file without including the whole file?


Thanks for any advice!





As with 
https://lists.gnu.org/archive/html/lilypond-user/2022-02/msg00537.html,

this is being answered on lilypond-user-fr.

Jean




\include in scheme functions

2022-02-27 Thread Pierre-Yves Saumont
Hi,

The Lilypond documentation says that any lilypond code can be use in a
Scheme function by enclosing it in a #{ ...  #} block, but it seems
\include doesn't work in this case.

I am building a program to handle multiple Big Band scores. I need to
extract parts for each instrument (16 to 22) and for all titles in a given
program (10 - 15).

At this time, here is what I do:

\include "../Doxy/Doxy_music.ly"
\include "partAltoI.ly"
\include "../Alfie/Alfie_music.ly"
\include "partAltoI.ly"
\include "../CestSiBon/CestSiBon_music.ly"
\include "partAltoI.ly"
\include "../BeyondTheSea/BeyondTheSea_music.ly"
\include "partAltoI.ly"
\include "../CloseToYou/CloseToYou_music.ly"
\include "partAltoI.ly"
.
.
.
include "../Doxy/Doxy_music.ly"
\include "partAltoII.ly"
\include "../Alfie/Alfie_music.ly"
\include "partAltoII.ly"
\include "../CestSiBon/CestSiBon_music.ly"
\include "partAltoII.ly"
\include "../BeyondTheSea/BeyondTheSea_music.ly"
\include "partAltoII.ly"
\include "../CloseToYou/CloseToYou_music.ly"
\include "partAltoII.ly"
.
.
.
include "../Doxy/Doxy_music.ly"
\include "partTenorI.ly"
\include "../Alfie/Alfie_music.ly"
\include "partTenorI.ly"
\include "../CestSiBon/CestSiBon_music.ly"
\include "partTenorI.ly"
\include "../BeyondTheSea/BeyondTheSea_music.ly"
\include "partTenorI.ly"
\include "../CloseToYou/CloseToYou_music.ly"
\include "partTenorI.ly"
.
.
.

This is tedious, and I would like to be able to simply have to enter the
list of titles:

Doxy
Alfie
CestSiBon
BeyondTheSea
CloseToYou
.
.
.

and the list of instruments:

AltoI
AltoII
TenorI
TenorII
Baritone
.
.
.

The result should be a series of PDF files, one for each
instrument, containing the specific parts for all selected tunes.

I tried to write a function such as:

part = #(define-void-function (score instrument) (string? string?)
   #{
 \include "../Doxy/Doxy_music.ly"
 \include "partAltoI.ly"
   #})

(Here, I am not constructing the file names from the arguments, only
testing the use of \include in the function.

This doesn't work, producing the following error:

.../include/LilyJAZZwithBarNums.ily:62:1 <0>: error: syntax error,
unexpected SCM_TOKEN, expecting end of input


#(define jazz-map '(

/tmp/frescobaldi-1mgd5_wr/tmpys2kq_gz/March2022_parts_alto1.ly:13:1 <1>:
error: error in #{ ... #}


\part "Doxy" "AltoI"


The message says the error is in LilyJAZZwithBarNums.ily, but since the
same instructions work when not in a function, I presume it's not related
to this file.


Is there a way to make this work, or is there another way to achieve the
intended result? For example, is there a way to read a lilypond variable
from a file without including the whole file?


Thanks for any advice!


Re: Ly Scheme functions reference

2022-02-05 Thread Rip _Mus
WOW!
This seems wonderful! Thank you very much!



Il sab 5 feb 2022, 20:30 Jean Abou Samra  ha scritto:

>
> > Le 5 févr. 2022 à 20:10, Rip _Mus  a
> écrit :
> >
> > Good evening everyone,
> > do you know if there is a complete reference (perhaps with tutorials) of
> the use of the Scheme functions?
> > In the Lilypond reference, from time to time, some functions are
> explained, but it seems to me that a precise reference of each Scheme
> function is missing. I know that they are explained in Internals reference,
> but I wanted like to see their behaviour in action, rather then only
> arguments and parameters.
>
>
> Given the number of such functions, crafting examples for each one is just
> not feasible. However, there is an Extending manual:
>
> https://lilypond.org/doc/v2.23/Documentation/web/extending
>
> and also this unofficial but much more thorough resource (disclaimer: I am
> the author):
>
> https://extending-lilypond.readthedocs.io
>
> Hope that helps (and feel free to send me feedback on the latter one).
> Also, it would help understanding your needs if you gave examples of things
> you'd like to understand better.
>
> Best,
> Jean
>
>
> PS:
>
> > Rip_mus
>
> RIP Music? I hope not :-)


Re: Ly Scheme functions reference

2022-02-05 Thread Jean Abou Samra


> Le 5 févr. 2022 à 20:10, Rip _Mus  a écrit :
> 
> Good evening everyone,
> do you know if there is a complete reference (perhaps with tutorials) of the 
> use of the Scheme functions?
> In the Lilypond reference, from time to time, some functions are explained, 
> but it seems to me that a precise reference of each Scheme function is 
> missing. I know that they are explained in Internals reference, but I wanted 
> like to see their behaviour in action, rather then only arguments and 
> parameters.


Given the number of such functions, crafting examples for each one is just not 
feasible. However, there is an Extending manual:

https://lilypond.org/doc/v2.23/Documentation/web/extending

and also this unofficial but much more thorough resource (disclaimer: I am the 
author):

https://extending-lilypond.readthedocs.io

Hope that helps (and feel free to send me feedback on the latter one). Also, it 
would help understanding your needs if you gave examples of things you'd like 
to understand better.

Best,
Jean


PS:

> Rip_mus

RIP Music? I hope not :-)


Ly Scheme functions reference

2022-02-05 Thread Rip _Mus
Good evening everyone,
do you know if there is a complete reference (perhaps with tutorials) of
the use of the Scheme functions?
In the Lilypond reference, from time to time, some functions are explained,
but it seems to me that a precise reference of each Scheme function is
missing. I know that they are explained in Internals reference, but I
wanted like to see their behaviour in action, rather then only arguments
and parameters.

Thank you

Rip_mus


Re: Markup functions and punctuation in lyrics

2021-11-06 Thread Fr. Samuel Springuel
I’ve done some work to clean up my code and also modified the interface to be 
fairly intuitive and non-intrusive.  Hopefully I’ll have some time this week to 
integrate this into my project, but if anyone sees anything that could be 
improved, I’d love to hear about it.

✝✝
Fr. Samuel, OSB
(R. Padraic Springuel)
St. Anselm’s Abbey
4501 South Dakota Ave, NE
Washington, DC, 20017
202-269-2300
(c) 202-853-7036

PAX ☧ ΧΡΙΣΤΟΣ



gender-test.ly
Description: Binary data


Re: Markup functions and punctuation in lyrics

2021-11-04 Thread Fr. Samuel Springuel
On Nov 2, 2021, at 11:26 PM, Aaron Hill  wrote:
> 
> Okay, would text replacement be viable as opposed to writing a bunch of 
> individual functions?

That does sound nice.  There would need to be some helper functions to handle 
the formatting issue that Jean pointed out, but I can get that mostly to work.

Attached is a basic mock-up of this strategy.  The one hangup that I ran into 
is that \replace doesn’t work directly on lyrics, so I had to use the \paper 
version.  Beyond that, it seems to be working, but I’ll happily take any 
critiques on the coding style before I start working this into a final version.


✝✝
Fr. Samuel, OSB
(R. Padraic Springuel)
St. Anselm’s Abbey
4501 South Dakota Ave, NE
Washington, DC, 20017
202-269-2300
(c) 202-853-7036

PAX ☧ ΧΡΙΣΤΟΣ


gender-test.ly
Description: Binary data


Re: Markup functions and punctuation in lyrics

2021-11-03 Thread Jean Abou Samra




Le 03/11/2021 à 04:26, Aaron Hill a écrit :
Okay, would text replacement be viable as opposed to writing a bunch 
of individual functions?



feminine =
#'(("man/woman" . "woman")
   ("his/her" . "her")
   ("he/she" . "she"))

\markup \replace \feminine {
  The man/woman, tightly clutching his/her jacket, braved the
  bitter cold as he/she searched for his/her missing dog.
}


Note that you can install such text replacements at the global level 
to affect all markup without needing the explicit call to \replace:



neutral =
#'(("man/woman" . "person")
   ("his/her" . "their")
   ("he/she" . "they"))

\paper { #(add-text-replacements! neutral) }

\markup {
  The man/woman, tightly clutching his/her jacket, braved the
  bitter cold as he/she searched for his/her missing dog.
}




The original spec was putting "man/men" in italic — but typographically, 
the comma should stay upright. If one can give up on that, text 
replacements are certainly the simplest solution. (I guess you could 
also write a function to do the replacements yourself.)


Perhaps we should take this thread as a feature request for replacing 
strings with arbitrary markups rather than just strings?


Best,
Jean



Re: Markup functions and punctuation in lyrics

2021-11-02 Thread Aaron Hill

On 2021-11-02 2:56 pm, R. Padraic Springuel wrote:
On Nov 2, 2021, at 1:00 PM, Aaron Hill  
wrote:


Not sure if this was already suggested, but could you use something 
like this to concatenate arbitrary markup?


I think that what you’re suggesting is in the spirit of what David was
suggesting, but I’m trying to reduce the input overhead at this point
and feel like what you propose increases it slightly.


Okay, would text replacement be viable as opposed to writing a bunch of 
individual functions?



feminine =
#'(("man/woman" . "woman")
   ("his/her" . "her")
   ("he/she" . "she"))

\markup \replace \feminine {
  The man/woman, tightly clutching his/her jacket, braved the
  bitter cold as he/she searched for his/her missing dog.
}


Note that you can install such text replacements at the global level to 
affect all markup without needing the explicit call to \replace:



neutral =
#'(("man/woman" . "person")
   ("his/her" . "their")
   ("he/she" . "they"))

\paper { #(add-text-replacements! neutral) }

\markup {
  The man/woman, tightly clutching his/her jacket, braved the
  bitter cold as he/she searched for his/her missing dog.
}



-- Aaron Hill



Re: Markup functions and punctuation in lyrics

2021-11-02 Thread R. Padraic Springuel
On Nov 2, 2021, at 1:00 PM, Aaron Hill  wrote:
> 
> Not sure if this was already suggested, but could you use something like this 
> to concatenate arbitrary markup?

I think that what you’re suggesting is in the spirit of what David was 
suggesting, but I’m trying to reduce the input overhead at this point and feel 
like what you propose increases it slightly.

> On Nov 2, 2021, at 1:11 PM, Jean Abou Samra  wrote:
> 
> The difference between a music function and an
> even function is that the return type of an event
> function is narrower -- it must return something
> suitable as a post-event, such as \p, -., \marcato,
> etc. This brings syntax flexibility in the case
> where a note is immediately followed by the application
> of an event function. The handling of arguments remains
> the same. It does not help here.

Thanks for that information.  So I guess that leads me back towards something 
like your first post.  I’m going to need to pick that code apart and see what I 
can understand there.

> Since you ask about this again, here is some code that
> I wrote when you asked the first time. It post-processes
> the lyrics to squash punctuation with the previous lyric
> event. I had abandoned it because it was getting complex.
> Try it and see how it fares -- it has not been extensively
> tested.

Oooo.  This is decidedly more complicated looking than your first post, but 
I’ll definitely take a look as the interface looks really promising.  Given my 
one track mind, I’ll probably wait until after I’ve had a chance to pick apart 
and understand your first suggestion.


✝✝
Fr. Samuel, OSB
(R. Padraic Springuel)
St. Anselm’s Abbey
4501 South Dakota Ave, NE
Washington, DC, 20017
202-269-2300
(c) 202-853-7036

PAX ☧ ΧΡΙΣΤΟΣ




Re: Markup functions and punctuation in lyrics

2021-11-02 Thread Jean Abou Samra

Le 02/11/2021 à 16:23, R. Padraic Springuel a écrit :

On Oct 31, 2021, at 6:02 PM, David Kastrup  wrote:

If the ugliness of juxtaposition is ok, you may use things like

\,\man

for concatenating stuff, too.

What about event functions?  Can a command which does the concatenation be 
written as an event function so that the juxtaposition isn’t needed?  (I’ve 
never written an event function and the extending manual doesn’t provide much 
info about their capabilities/limitations.)



The difference between a music function and an
even function is that the return type of an event
function is narrower -- it must return something
suitable as a post-event, such as \p, -., \marcato,
etc. This brings syntax flexibility in the case
where a note is immediately followed by the application
of an event function. The handling of arguments remains
the same. It does not help here.

Since you ask about this again, here is some code that
I wrote when you asked the first time. It post-processes
the lyrics to squash punctuation with the previous lyric
event. I had abandoned it because it was getting complex.
Try it and see how it fares -- it has not been extensively
tested.


\version "2.22.1"

#(use-modules (ice-9 regex))

#(define punctuation (make-regexp "^[.,;:?!]+$"))

magneticPunctuation =
#(define-music-function (music) (ly:music?)
   (for-some-music
 (lambda (m)
   (let ((elts (ly:music-property m 'elements)))
 (if (pair? elts)
 (let loop ((e elts)
    (last-lyric #f)
    (acc '()))
   (if (null? e)
   (ly:music-set-property! m 'elements (reverse! acc))
   (let ((next (car e)))
 (cond
   ((and (music-is-of-type? m 'sequential-music)
 (music-is-of-type? next 'sequential-music))
    ; #{ \lyricmode { ... } #} yields sequential music,
    ; so flatten it.
    (loop (append (ly:music-property next 'elements)
  (cdr e))
  last-lyric
  acc))
   ((and last-lyric
 (music-is-of-type? next 'lyric-event))
    (let ((previous-text (ly:music-property 
last-lyric 'text))

  (next-text (ly:music-property next 'text)))
  (if (and (string? previous-text)
   (string? next-text)
   (regexp-match? (regexp-exec 
punctuation next-text)))

  (let ((new
  (make-music 'LyricEvent
  last-lyric
  'text
  (string-append 
previous-text

next-text
    (loop (cdr e)
  new
  (cons new (delq1! last-lyric acc
  (loop (cdr e)
    next
    (cons next acc)
   ((music-is-of-type? next 'lyric-event)
    (loop (cdr e)
  next
  (cons next acc)))
   ((equal? ZERO-MOMENT (ly:music-length next))
    (loop (cdr e)
  last-lyric
  (cons next acc)))
   (else
    (loop (cdr e)
  #f
  (cons next acc)
   #f)
 music)
   music)

gender = "other"

man =
#(cond
   ((equal? gender "male") #{ \lyricmode { man } #})
    ;((equal? gender "female")  #{ \lyricmode{ error } #})
   ((equal? gender "plural") #{ \lyricmode { men } #})
   (else
 #{
   \lyricmode {
 \override Lyrics.LyricText.font-shape = #'italic
 man/men
 \revert Lyrics.LyricText.font-shape
   }
 #}))


music = { c' c' c' c' c' c' c' c' c' c' c' }

verseI = \lyricmode {
  In glad re -- mem -- brance of this ho -- ly \man, \skip 4
  Who sought to fol -- low you in faith and love.
}

\magneticPunctuation \new Staff
<<
    \new Voice = "mel" { \music \music }
    \new Lyrics \lyricsto "mel" { \verseI }
>>


Regards,
Jean



Re: Markup functions and punctuation in lyrics

2021-11-02 Thread Aaron Hill

On 2021-11-02 8:23 am, R. Padraic Springuel wrote:

On Oct 31, 2021, at 6:02 PM, David Kastrup  wrote:

If the ugliness of juxtaposition is ok, you may use things like

\,\man

for concatenating stuff, too.


Not sure if this was already suggested, but could you use something like 
this to concatenate arbitrary markup?



"\+" =
#(define-scheme-function
  (first second) (markup? markup?)
  #{ \markup \concat { #first #second } #})

foo =
#(let ((idx 0))
  (define (inc) (set! idx (1+ idx)) idx)
  (define-scheme-function () ()
   #{ \markup $(format #f "~r" (inc)) #}))

{ b'4 4 4 4 }
\addlyrics { \+ \foo , \+ \foo , and \+ \foo ! }



-- Aaron Hill



Re: Markup functions and punctuation in lyrics

2021-11-02 Thread R. Padraic Springuel


> On Oct 31, 2021, at 6:02 PM, David Kastrup  wrote:
> 
> If the ugliness of juxtaposition is ok, you may use things like
> 
> \,\man
> 
> for concatenating stuff, too.

What about event functions?  Can a command which does the concatenation be 
written as an event function so that the juxtaposition isn’t needed?  (I’ve 
never written an event function and the extending manual doesn’t provide much 
info about their capabilities/limitations.)


✝✝
Fr. Samuel, OSB
(R. Padraic Springuel)
St. Anselm’s Abbey
4501 South Dakota Ave, NE
Washington, DC, 20017
202-269-2300
(c) 202-853-7036

PAX ☧ ΧΡΙΣΤΟΣ




Re: Markup functions and punctuation in lyrics

2021-10-31 Thread David Kastrup
"R. Padraic Springuel"  writes:

>> On Oct 18, 2021, at 5:57 PM, David Kastrup  wrote:
>> 
>> I'd lean towards defining \man like in the question and a function \maN
>> that takes the following markup and concatenates it.  That's viciously
>> unclever but sometimes not having to worry whether the computer gets
>> everything right is its own reward.
>
> David, can you elaborate on this suggestion a bit?  \man is only a
> single example of the kind of function I have to write (there are
> similar ones for various pronouns, possessive adjectives, etc.) and so
> I’d like to separate the punctuation handling from the word selection
> (to avoid duplicate code in each function.  I’m working on applying
> that idea to Jean’s code, but perhaps your idea is better suited to
> said separation.  Is it anything more elaborate than establishing a
> function which effectively does `\markup \concat { \man, }`?  And if
> not, is there a more succinct way of writing that?

No, that's really all there is to it.  As I said: there may be lots of
cleverer ways.

If the ugliness of juxtaposition is ok, you may use things like

\,\man

for concatenating stuff, too.

-- 
David Kastrup



Re: Markup functions and punctuation in lyrics

2021-10-31 Thread R. Padraic Springuel
> On Oct 18, 2021, at 5:57 PM, David Kastrup  wrote:
> 
> I'd lean towards defining \man like in the question and a function \maN
> that takes the following markup and concatenates it.  That's viciously
> unclever but sometimes not having to worry whether the computer gets
> everything right is its own reward.

David, can you elaborate on this suggestion a bit?  \man is only a single 
example of the kind of function I have to write (there are similar ones for 
various pronouns, possessive adjectives, etc.) and so I’d like to separate the 
punctuation handling from the word selection (to avoid duplicate code in each 
function.  I’m working on applying that idea to Jean’s code, but perhaps your 
idea is better suited to said separation.  Is it anything more elaborate than 
establishing a function which effectively does `\markup \concat { \man, }`?  
And if not, is there a more succinct way of writing that?

✝✝
Fr. Samuel, OSB
(R. Padraic Springuel)
St. Anselm’s Abbey
4501 South Dakota Ave, NE
Washington, DC, 20017
202-269-2300
(c) 202-853-7036

PAX ☧ ΧΡΙΣΤΟΣ






Re: Markup functions and punctuation in lyrics

2021-10-18 Thread David Kastrup
Jean Abou Samra  writes:

> Le 18/10/2021 à 21:22, R. Padraic Springuel a écrit :
>> I’m using some functions to allow me to select words in the lyrics
>> of some hymns in a systematic way so that the same hymn can be used
>> referring to one or more persons (and in some cases, either a man or
>> a woman).  These functions work just fine when they appear in the
>> lyrics by themselves, but when there is punctuation immediately
>> after one of these functions, the punctuation gets shifted to its
>> own syllable.  Is there a way to have the function interact with
>> punctuation more intelligently?  I’m thinking I need to use \concat
>> somehow, but how do I write the function so that it only does the
>> concatenation when the next character is punctuation?
>>
>> Attached is an example showing one of my simple word selection
>> functions followed by a comma.
>
>
> It's slightly tricky. What you may want is a
> function recognizing the comma as its argument,
> but not taking any argument if the next input
> element is not punctuation.

I'd lean towards defining \man like in the question and a function \maN
that takes the following markup and concatenates it.  That's viciously
unclever but sometimes not having to worry whether the computer gets
everything right is its own reward.

-- 
David Kastrup



Re: Markup functions and punctuation in lyrics

2021-10-18 Thread Jean Abou Samra

Le 18/10/2021 à 21:22, R. Padraic Springuel a écrit :

I’m using some functions to allow me to select words in the lyrics of some 
hymns in a systematic way so that the same hymn can be used referring to one or 
more persons (and in some cases, either a man or a woman).  These functions 
work just fine when they appear in the lyrics by themselves, but when there is 
punctuation immediately after one of these functions, the punctuation gets 
shifted to its own syllable.  Is there a way to have the function interact with 
punctuation more intelligently?  I’m thinking I need to use \concat somehow, 
but how do I write the function so that it only does the concatenation when the 
next character is punctuation?

Attached is an example showing one of my simple word selection functions 
followed by a comma.



It's slightly tricky. What you may want is a
function recognizing the comma as its argument,
but not taking any argument if the next input
element is not punctuation. This is not possible
because optional function arguments in last position
can only omitted with \default, not implicitly.
However, you can make a function that takes the
next element in all cases, and inserts it back
in the input, either together with your lyric
event as a single event, or separately in a second
event as you got it. The only disadvantage is that
putting \man at the end of an expression
(\lyricmode { ... \man }) will not work since \man
will be expecting an argument. As long as you're
not doing that (I assume you would want a period
at the end anyway), all should be fine.


\version "2.22.1"

#(use-modules (srfi srfi-11)
  (ice-9 regex))

#(define punctuation (make-regexp "^[.,;:?!]+$"))

gender = #'other

man =
#(define-music-function (next) (ly:music?)
   (let-values
 (((text)
   (case gender
 ((male) "man")
 ((plural) "men")
 (else "man/men")))
  ((next-is-punctuation punctuation-text)
   (if (music-is-of-type? next 'lyric-event)
   (let ((other-text (ly:music-property next 'text)))
 (if (and (string? other-text)
  (regexp-match? (regexp-exec punctuation other-text)))
 (values #t other-text)
 (values #f #f)))
   (values #f #f
 (case gender
   ((male plural)
    (if next-is-punctuation
    #{ \lyricmode { #(string-append text punctuation-text) } #}
    #{ \lyricmode { #text #next } #}))
   (else
    (if next-is-punctuation
    #{ \lyricmode { \markup \concat { \italic #text 
#punctuation-text } } #}

    #{ \lyricmode { \markup \italic #text #next } #})


music = { c' c' c' c' c' c' c' c' c' c' c' }

verseI = \lyricmode {
  In glad re -- mem -- brance of this ho -- ly \man, \skip 4
  Who sought to fol -- low you in faith and love.
}

\new Staff <<
    \new Voice = "mel" { \music \music }
    \new Lyrics \lyricsto "mel" { \verseI }
>>



Note the use of symbols, which are better suited
for discrete values than strings (comparison is
cheaper at least in theory, and you get nice
specific idioms like case).

Best,
Jean



Markup functions and punctuation in lyrics

2021-10-18 Thread R. Padraic Springuel
I’m using some functions to allow me to select words in the lyrics of some 
hymns in a systematic way so that the same hymn can be used referring to one or 
more persons (and in some cases, either a man or a woman).  These functions 
work just fine when they appear in the lyrics by themselves, but when there is 
punctuation immediately after one of these functions, the punctuation gets 
shifted to its own syllable.  Is there a way to have the function interact with 
punctuation more intelligently?  I’m thinking I need to use \concat somehow, 
but how do I write the function so that it only does the concatenation when the 
next character is punctuation?

Attached is an example showing one of my simple word selection functions 
followed by a comma.

✝✝
Fr. Samuel, OSB
(R. Padraic Springuel)
St. Anselm’s Abbey
4501 South Dakota Ave, NE
Washington, DC, 20017
202-269-2300
(c) 202-853-7036

PAX ☧ ΧΡΙΣΤΟΣ


gender-test.ly
Description: Binary data


Re: Basic functions

2021-05-15 Thread Jean Abou Samra


Le 15/05/2021 à 19:49, Jenifer Tribe a écrit :
I want to include a change of midi tempo at various points in a score, 
using something like

\setSpeed #2 #120

where
setSpeed =
  #(define-music-function
      (parser location scale speed)
      (number? number? )
    #{
       \set Score.tempoHideNote = ##t
       \tempo scale = speed
    #}
  )

I'm still using 2.18 I'm afraid, which still used the parser and 
location parameters..
I'm assuming this should be a music function rather than markup, but 
perhaps my arguments aren't numbers.
In this case the function is hardly worth it, but I want to base more 
complicated routines on it, and have failed at the first hurdle!



There are two mistakes here:

- In the function, scale and speed are interpreted as strings.
  You want $scale and $speed (the reason for using $ instead
  of # is explained in [1]).

- The scale argument is a duration, not a number (you can do
  \tempo 4. = 120 for instance).

Corrected version:

\version "2.23.3"

setSpeed =
#(define-music-function
    (parser location scale speed)
    (ly:duration? number?)
  #{
 \set Score.tempoHideNote = ##t
 \tempo $scale = $speed
  #})


\score {
  {
    \setSpeed 4. 4
    c
  }
  \layout { }
  \midi { }
}

There is also the possibility of doing

\layout {
  \context {
    \Score
    tempoHideNote = ##t
  }
}

to set tempoHideNote globally (read [2]), and then you
can just use the normal \tempo command in the music.


Best,
Jean

[1] 
https://extending-lilypond.readthedocs.io/en/latest/lily-and-scheme.html#hash-vs-dollar
[2] 
http://lilypond.org/doc/v2.22/Documentation/notation/changing-context-default-settings




Basic functions

2021-05-15 Thread Jenifer Tribe
I want to include a change of midi tempo at various points in a score, using 
something like
  \setSpeed #2 #120

where
setSpeed =
  #(define-music-function
  (parser location scale speed)
  (number? number? )
#{
   \set Score.tempoHideNote = ##t
   \tempo scale = speed
#}
  )

I'm still using 2.18 I'm afraid, which still used the parser and location 
parameters..
I'm assuming this should be a music function rather than markup, but perhaps my 
arguments aren't numbers.
In this case the function is hardly worth it, but I want to base more 
complicated routines on it, and have failed at the first hurdle!

Jonathan


Lilypond functions

2021-03-03 Thread Silvain Dupertuis

Hello everyone,

Functions in Lilypond can also be written in pure Sheme syntax like this
#(define abcd
    (lambda (x y ... )
        PROCEDURE USING x y ...))

and then called within Lilypond with the syntax
\abcd x y ...
or within a Sheme fucntion with the syntax
(abcd x y ...)

If anyone is interested, I made an exercise for myself to explore *the use of 
functions*
and create a score of the *first Prelude of Book I of J.S. Bach's Well-Tempered 
Clavier*

As this piece has 32 bars using the same pattern based on 5 notes, plus an 
ending in 3 bars,
I used a simple list of notes (without any rythmic indications) as my main data
and designed functions to extract the groups of 5 notes, apply the patterns to create 
voices and scores, including a chord version on the piece in addition to the standard score.


notes = {
  c e g c e
  c d a' d f
  b d g d' f ... etc.
)

Files (Lilypond, PDF and midi) are in this online folder
(midi files need to be downloaded to listen to them)
<https://nextcloud.silvain-dupertuis.net/index.php/s/oQJfcgZP9PKY9ca>

Silvain Dupertuis

Merci

This is a perfect solution, and, a clear explanation about why my solution 
failed.

Thank you very much


Ken Ledeen

Mobile:                617-817-3183
www.nevo.com <http://www.nevo.com>
www.bitsbook.com <http://www.bitsbook.com>
tiny.cc/KenLedeen <http://tiny.cc/KenLedeen>
tiny.cc/KenLedeenAmazon <http://iny.cc/KenLedeenAmazon>

ᐧ

On Sat, Feb 27, 2021 at 10:43 AM Jean Abou Samra <mailto:j...@abou-samra.fr>> wrote:


   Le 27/02/2021 à 02:16, Ken Ledeen a écrit :

> I am struggling to understand the restrictions on substitution functions.
>
> For example:
>
> 1) can a function include "\score { ...}"  or can it only be invoked
> INSIDE a \score?
>
> 2) is it possible to include \header { ...}  inside a substitution
> function?  It fails when I try, but I don't understand why.
>
> I assume I am missing some basic concepts regarding their use.
>
> Thanks!


   Hello,

   Music functions must return music objects; \score blocks are not music
   but general containers that enclose music as well as other objects such
   as \header and \layout blocks.

   However, replacing define-music-function with define-scheme-function,
   you can define more versatile functions that are allowed to return any
   kind of object for interpretation. For example:

   \version "2.23.1"

   failingFunction =
   #(define-music-function () ()
    #{
  \score {
    \header {
  piece = "Piece A"
    }
    { c' }
  }
    #})

   % \failingFunction

   succeedingFunction =
   #(define-scheme-function () ()
    #{
  \score {
    \header {
  piece = "Piece B"
    }
    { c' }
  }
    #})

   \succeedingFunction


   Hope that helps,
   Jean



Re: functions with multiple arguments

2021-01-03 Thread Tom Sgouros
Aha!

Thank you, I could have looked at that for a week without realizing it's
supposed to be a list of functions not a list of function calls.

 -Tom

On Sun, Jan 3, 2021 at 7:46 PM Knute Snortum  wrote:

> I think this is the correct syntax:
>
> rpt =
> #(define-music-function
>  (parser location note1 note2)
>  (ly:pitch? ly:pitch?)
>#{
>  $note1 1 $note2 1
>#})
> \rpt a bes
>
> --
> Knute Snortum
>
> On Sun, Jan 3, 2021 at 4:04 PM Tom Sgouros  wrote:
> >
> > Hello all:
> >
> > This works:
> >
> > rpt =
> > #(define-music-function
> >  (parser location note1)
> >  (ly:pitch?)
> >#{
> >  $note1 1
> >#})
> > \rpt a
> >
> > Why doesn't this? ("Wrong number of arguments to # location note1 note2)>") What am I missing?
> >
> > rpt =
> > #(define-music-function
> >  (parser location note1 note2)
> >  (ly:pitch?) (ly:pitch?)
> >#{
> >  $note1 1 note2 1
> >#})
> > \rpt a bes
> >
> > I was imagining I could use a function like this to generate groups of
> sextets efficiently, with four notes input to make the groups of six and
> making the arpeggio automatically. Perhaps barking up the wrong tree?
> >
> > Thank you,
> >
> >  -Tom
>


Re: functions with multiple arguments

2021-01-03 Thread Knute Snortum
I think this is the correct syntax:

rpt =
#(define-music-function
 (parser location note1 note2)
 (ly:pitch? ly:pitch?)
   #{
 $note1 1 $note2 1
   #})
\rpt a bes

--
Knute Snortum

On Sun, Jan 3, 2021 at 4:04 PM Tom Sgouros  wrote:
>
> Hello all:
>
> This works:
>
> rpt =
> #(define-music-function
>  (parser location note1)
>  (ly:pitch?)
>#{
>  $note1 1
>#})
> \rpt a
>
> Why doesn't this? ("Wrong number of arguments to # location note1 note2)>") What am I missing?
>
> rpt =
> #(define-music-function
>  (parser location note1 note2)
>  (ly:pitch?) (ly:pitch?)
>#{
>  $note1 1 note2 1
>#})
> \rpt a bes
>
> I was imagining I could use a function like this to generate groups of 
> sextets efficiently, with four notes input to make the groups of six and 
> making the arpeggio automatically. Perhaps barking up the wrong tree?
>
> Thank you,
>
>  -Tom



functions with multiple arguments

2021-01-03 Thread Tom Sgouros
Hello all:

This works:

rpt =
#(define-music-function
 (parser location note1)
 (ly:pitch?)
   #{
 $note1 1
   #})
\rpt a

Why doesn't this? ("Wrong number of arguments to #") What am I missing?

rpt =
#(define-music-function
 (parser location note1 note2)
 (ly:pitch?) (ly:pitch?)
   #{
 $note1 1 note2 1
   #})
\rpt a bes

I was imagining I could use a function like this to generate groups of
sextets efficiently, with four notes input to make the groups of six and
making the arpeggio automatically. Perhaps barking up the wrong tree?

Thank you,

 -Tom


Re: newbie: help with Scheme functions

2020-10-18 Thread Dave Seidel
Thanks, Aaron.

On Sun, Oct 18, 2020 at 4:46 PM Aaron Hill  wrote:

> On 2020-10-18 1:38 pm, Dave Seidel wrote:
> > Very cool, thanks! I'm curious -- could aBook and aBookPart have been
> > written as a lambda, or is it cleaner to use a void function?
>
> (Re-adding the mailing list on the thread for visibility.)
>
> To get the benefits of LilyPond's Scheme functions, you would need to
> use one of the define-*-function family.  Since it is our intention here
> not to return any value, we use the void function.
>
> If you do not need any parameters, you can certainly invoke procedures
> like print-book-with-defaults or ly:book-add-bookpart! without wrapping
> them in a function.  Though, without parameterization, I would wonder
> why you could not just use \book or \bookpart directly.
>
>
> -- Aaron Hill
>


Re: newbie: help with Scheme functions

2020-10-18 Thread Aaron Hill

On 2020-10-18 1:38 pm, Dave Seidel wrote:

Very cool, thanks! I'm curious -- could aBook and aBookPart have been
written as a lambda, or is it cleaner to use a void function?


(Re-adding the mailing list on the thread for visibility.)

To get the benefits of LilyPond's Scheme functions, you would need to 
use one of the define-*-function family.  Since it is our intention here 
not to return any value, we use the void function.


If you do not need any parameters, you can certainly invoke procedures 
like print-book-with-defaults or ly:book-add-bookpart! without wrapping 
them in a function.  Though, without parameterization, I would wonder 
why you could not just use \book or \bookpart directly.



-- Aaron Hill



Re: newbie: help with Scheme functions

2020-10-18 Thread Aaron Hill

On 2020-10-18 7:52 am, Dave Seidel wrote:
Having articulated the question, I figured out that apparently one 
can't
return a \bookpart from a Scheme function, but it's ok to return a 
\score,

so I am restructuring my code.


You cannot return a \book or \bookpart but you can do this:


\version "2.20.0"

aBook =
#(define-void-function
  (name music)
  (symbol? ly:music?)
  (print-book-with-defaults #{
\book {
  \bookOutputSuffix $(symbol->string name)
  \score { $music }
} #}))

\aBook one { c'8 d' ees' f' g' a' bes' c'' }
\aBook two { c'8 des' ees' f' g' aes' bes' c'' }

aBookPart =
#(define-void-function
  (name music)
  (symbol? ly:music?)
  (ly:book-add-bookpart!
   (ly:parser-lookup '$current-book)
   #{ \bookpart {
\markup \italic $(symbol->string name)
\score { $music }
  } #}))

\book {
  \bookOutputSuffix "bookparts"
  \aBookPart three { c'8 d' e' fis' g' a' b' c'' }
  \aBookPart four { c'8 d' e' f' g' a' bes' c'' }
}



-- Aaron Hill



Re: newbie: help with Scheme functions

2020-10-18 Thread Dave Seidel
Having articulated the question, I figured out that apparently one can't
return a \bookpart from a Scheme function, but it's ok to return a \score,
so I am restructuring my code.

On Sun, Oct 18, 2020 at 10:28 AM Dave Seidel  wrote:

> Hi,
>
> I have a multi-section piece, with a master .ly file that uses \include
> for each of the sections of the piece. Each included file more or less
> follows the pattern of the string quartet template that ships with
> Lilypond: a series of macros, one per voice, followed by a \bookpart
> section that builds a StaffGroup, with one Staff per voice. This bookpart
> block is nearly identical in all the included files, with the exception of
> a title string used for "piece" property in in a \header section and also
> also as a \tocItem.
>
> This all works quite well, and I have a nice score with everything. Now
> I'd like to be able to produce parts, and my thought is that rather than
> have a literal bookpart block in each file, I should be able to convert the
> block into a function that takes the title string parameter. If I can get
> this to work, then hopefully I can make the function smart enough to either
> render all voices (for the full score) or just a single voice (for parts).
>
> My problem is that I have defined the function, but I can't invoke it.
> Here's the function:
>
> scoreSection =
> #(define-scheme-function
> (parser location title)
> (string?)
>   #{
> \bookpart {
> \header {
>   piece = #title
> }
> \tocItem \markup #title
> \markup {
>   \italic "Notes other than C have different pitches than notated,
> as indicated by a number"
> }
> \markup {
>   \italic "in parentheses giving an offset in cents relative to
> the notated pitch, shown at"
> }
> \markup {
>   \italic "the first appearance of each note that requires
> alteration."
> }
> \score {
> \new StaffGroup \with { midiInstrument = "cello" } <<
> \new Staff \with { instrumentName = "String 1" }
> << \global \stringOne >>
> \new Staff \with { instrumentName = "String 2" }
> << \global \stringTwo >>
> \new Staff \with { instrumentName = "String 3" }
> << \global \stringThree >>
> \new Staff \with { instrumentName = "String 4" }
> << \global \stringFour >>
> \new Staff \with { instrumentName = "String 5" }
> << \global \stringFive >>
> \new Staff \with { instrumentName = "String 6" }
> << \global \stringSix >>
> \new Staff \with { instrumentName = "String 7" }
> << \global \stringSeven >>
> >>
> \layout { }
> \midi { }
> }
> }
>   #})
>
> And I am trying to invoke it using
>
> \scoreSection #"Part 1"
>
>
> but I keep getting the error messages like this:
>
> Parsing...
> hexany_permutations.ly:127:1: error: bad expression type
>
> \scoreSection #"Part 1"
>
>
> What am I doing wrong? I'm a Lilypond and Scheme newbie (but a programmer
> by trade).
>
> - Dave
>


newbie: help with Scheme functions

2020-10-18 Thread Dave Seidel
Hi,

I have a multi-section piece, with a master .ly file that uses \include for
each of the sections of the piece. Each included file more or less follows
the pattern of the string quartet template that ships with Lilypond: a
series of macros, one per voice, followed by a \bookpart section that
builds a StaffGroup, with one Staff per voice. This bookpart block is
nearly identical in all the included files, with the exception of a title
string used for "piece" property in in a \header section and also also as a
\tocItem.

This all works quite well, and I have a nice score with everything. Now I'd
like to be able to produce parts, and my thought is that rather than have a
literal bookpart block in each file, I should be able to convert the block
into a function that takes the title string parameter. If I can get this to
work, then hopefully I can make the function smart enough to either render
all voices (for the full score) or just a single voice (for parts).

My problem is that I have defined the function, but I can't invoke it.
Here's the function:

scoreSection =
#(define-scheme-function
(parser location title)
(string?)
  #{
\bookpart {
\header {
  piece = #title
}
\tocItem \markup #title
\markup {
  \italic "Notes other than C have different pitches than notated,
as indicated by a number"
}
\markup {
  \italic "in parentheses giving an offset in cents relative to the
notated pitch, shown at"
}
\markup {
  \italic "the first appearance of each note that requires
alteration."
}
\score {
\new StaffGroup \with { midiInstrument = "cello" } <<
\new Staff \with { instrumentName = "String 1" }
<< \global \stringOne >>
\new Staff \with { instrumentName = "String 2" }
<< \global \stringTwo >>
\new Staff \with { instrumentName = "String 3" }
<< \global \stringThree >>
\new Staff \with { instrumentName = "String 4" }
<< \global \stringFour >>
\new Staff \with { instrumentName = "String 5" }
<< \global \stringFive >>
\new Staff \with { instrumentName = "String 6" }
<< \global \stringSix >>
\new Staff \with { instrumentName = "String 7" }
<< \global \stringSeven >>
>>
\layout { }
\midi { }
}
}
  #})

And I am trying to invoke it using

\scoreSection #"Part 1"


but I keep getting the error messages like this:

Parsing...
hexany_permutations.ly:127:1: error: bad expression type

\scoreSection #"Part 1"


What am I doing wrong? I'm a Lilypond and Scheme newbie (but a programmer
by trade).

- Dave


Re: Understanding scope of functions in Scheme modules

2020-07-25 Thread Urs Liska
I thought I had a good idea, but it got me into hot water, with no
border in sight yet...

I thought I could do the following:

 * Define-public my "internal" procedures in a module _my-module
 * Use that module in my-module

All the stuff defined in _my-module will be visible in my-module, and
all the stuff defined publicly in my-module will be seen in later
LilyPond files. If some later Scheme module needs access to it it can
use my-module.

While I have the impression this actually works I run into situations I
wouldn't have expected. Unfortunately I can't really provide an MWE for
it.

But could someone give me a hint how I can bring myself in a situation
to get
  Unbound variable: define-void-function
?
This is defined in music-functions.scm, and it should in any case have
been loaded before I ever issue an \include "oll-core/package.ily",
isn't it?

Probably the real issue is totally somewhere else, but I just have to
shoot in the dark here, hoping for some reflections ...

BestUrs

Am Samstag, den 25.07.2020, 10:28 +0200 schrieb Urs Liska:
> Hi,
> 
> I'm trying to clean up some code in openLilyLib, most of which had
> been
> added when I was just starting to understand the topics I had to deal
> with at any point ...
> 
> One thing I'm right now struggling with and that I'd like to get
> right
> this time is the scoping of code within Scheme modules.
> 
> My observation at this point seems to be:
> 
>  * I can define procedures or variables in a Scheme module
> equivalently
>with (define-public my-proc) or (define my-proc) (export my-proc)
>  * I can include such a module in a .ly file with (use-modules (my-
>module)) (if it's in the Guile path).
>  * my-proc will then be available for any later LilyPond code (i.e.
>also in other files that are later in that compilation's parsing)
>  * my-proc will *not* be available in other .scm files, in these I
>would have to explicitly include my-module with use-modules.
> 
> Is this correct so far?
> If so is there a way to make names from modules only available within
> the LilyPond file that uses the module?
> 
> I would like to have more encapsulation, so that the helper functions
> needed for the implementation are only visible where needed to have
> less clutter in the global namespace, like in many other languages
> where you have to explicitly import modules you want to use within
> each
> file.
> 
> I think it will already be progress just to have the code *organized*
> like that, the camelCase-d user-facing LilyPond functions in the .ily
> file and the Scheme-define-d helper code in a separate .scm file. But
> if there were a way for real scoping it would be better.
> 
> Any suggestions available?
> 
> Thanks
> Urs
> 
> 




Understanding scope of functions in Scheme modules

2020-07-25 Thread Urs Liska
Hi,

I'm trying to clean up some code in openLilyLib, most of which had been
added when I was just starting to understand the topics I had to deal
with at any point ...

One thing I'm right now struggling with and that I'd like to get right
this time is the scoping of code within Scheme modules.

My observation at this point seems to be:

 * I can define procedures or variables in a Scheme module equivalently
   with (define-public my-proc) or (define my-proc) (export my-proc)
 * I can include such a module in a .ly file with (use-modules (my-
   module)) (if it's in the Guile path).
 * my-proc will then be available for any later LilyPond code (i.e.
   also in other files that are later in that compilation's parsing)
 * my-proc will *not* be available in other .scm files, in these I
   would have to explicitly include my-module with use-modules.

Is this correct so far?
If so is there a way to make names from modules only available within
the LilyPond file that uses the module?

I would like to have more encapsulation, so that the helper functions
needed for the implementation are only visible where needed to have
less clutter in the global namespace, like in many other languages
where you have to explicitly import modules you want to use within each
file.

I think it will already be progress just to have the code *organized*
like that, the camelCase-d user-facing LilyPond functions in the .ily
file and the Scheme-define-d helper code in a separate .scm file. But
if there were a way for real scoping it would be better.

Any suggestions available?

Thanks
Urs




Re: Arguments before functions

2020-07-20 Thread Fr. Samuel Springuel
> On 19 Jul, 2020, at 4:32 PM, David Kastrup  wrote:
> 
> I don't see that you can fix this with a music function,

That’s what I thought, I just wanted to make sure.

> but of course
> you can process the complete music expression and then modify any note
> before a \bar "|".

I hadn’t thought of that, but since it would still involve modifications to the 
source (to add the function which modifies the whole source) I figure I’m 
probably better off with functions that only affect the notes I’m interested in 
changing in the long run.

> On 19 Jul, 2020, at 4:43 PM, Aaron Hill  wrote:
> 
> Rather than try to work around the plumbing of LilyPond, might I suggest the 
> following:
> 
> 
> ...
> 
> 
> This approach allows you to create a template of sorts for individual notes.  
> Above is an example usage to aid with pointing, supporting the middle of a 
> phrase and the final tone.

Interesting approach.  My idea was to define functions which apply the 
transformations directly and then have place holder functions in the music 
which are defined using \etc:



\version "2.20.0"

episema = #(define-music-function (note-event) (ly:music?)
   "Add an tenuto ArticulationEvent to the articulations of 
`note-event',
which is supposed to be a NoteEvent expression.  This simulates 
the 
episema."
   (set! (ly:music-property note-event 'articulations)
 (cons (make-music 'ArticulationEvent
   'articulation-type "tenuto")
 (ly:music-property note-event 'articulations)))
   note-event)

dotted = #(define-music-function (note) (ly:music?)
  "Add a dot to the duration of note."
  (withMusicProperty 'duration (ly:make-duration 2 1) note)
  )

final = \dotted \etc
middle = \episema \etc

\fixed c' { \cadenzaOn a4 g \middle b g8[ f] g4_( \final c') \bar "|” }




In this case switching what appears in the music is a matter of changing the 
definitions of the aliases.

I think both approaches accomplish the job, so it’s probably a matter of taste 
as to which to choose.  Yours does have the distinct advantage of making more 
use of LilyPond syntax and is more compact as a result.

✝✝
Fr. Samuel, OSB
(R. Padraic Springuel)
St. Anselm’s Abbey
4501 South Dakota Ave, NE
Washington, DC, 20017
202-269-2300
(c) 202-853-7036

PAX ☧ ΧΡΙΣΤΟΣ




Re: Arguments before functions

2020-07-19 Thread Aaron Hill

On 2020-07-19 11:16 am, Fr. Samuel Springuel wrote:
Is there a way for a music function to operate on the note that 
precedes it?


Rather than try to work around the plumbing of LilyPond, might I suggest 
the following:



\version "2.20.0"

noteTemplate =
#(define-scheme-function
  (reference-note) (ly:music?)
  (define-music-function
(pitch) (ly:pitch?)
(let ((note (ly:music-deep-copy reference-note)))
  (ly:music-set-property! note 'pitch pitch)
  note)))

middle = \noteTemplate 2^"*"
final = \noteTemplate 2.--

\fixed c' { \cadenzaOn a4 g \middle b g8[ f] g4_( \final c') \bar "|" }
\fixed c' { \cadenzaOn g4 f8[ d] e4 \middle e g4 a \final g \bar "|" }


This approach allows you to create a template of sorts for individual 
notes.  Above is an example usage to aid with pointing, supporting the 
middle of a phrase and the final tone.



-- Aaron Hill

Re: Arguments before functions

2020-07-19 Thread David Kastrup
"Fr. Samuel Springuel"  writes:

> Is there a way for a music function to operate on the note that precedes it?
>
> I’m transcribing chant and have lots of music where I transcribed the
> note just before the bar as a quarter note (the same as other
> non-reciting notes in the measure):
>
> { \cadenzaOn g'1 c'4 f'  \bar "|" }
>
>
> I’ve been asked now to lengthen the note just before the bar by making
> it into a dotted quarter:
>
> { \cadenzaOn g'1 c'4 f'4.  \bar "|" }
>
> What I’d like to know is if there’s a way that I can modify the \bar
> function so that it automatically changes the duration of the note
> just before it, or if I have to break out the text replacement tools
> to modify all my source files.

I don't see that you can fix this with a music function, but of course
you can process the complete music expression and then modify any note
before a \bar "|".

> As a further complication, the dotted quarter notation hasn’t been
> settled yet, as there are some arguing for making it a quarter with a
> tenuto and others for a half note, so I’d really like a function that
> allows me to switch between those three options (dotted quarter,
> quarter with tenuto, or half note) relatively easily.

That would then be reasonably simple.

-- 
David Kastrup



Arguments before functions

2020-07-19 Thread Fr. Samuel Springuel
Is there a way for a music function to operate on the note that precedes it?

I’m transcribing chant and have lots of music where I transcribed the note just 
before the bar as a quarter note (the same as other non-reciting notes in the 
measure):

{ \cadenzaOn g'1 c'4 f'  \bar "|" }


I’ve been asked now to lengthen the note just before the bar by making it into 
a dotted quarter:

{ \cadenzaOn g'1 c'4 f'4.  \bar "|" }

What I’d like to know is if there’s a way that I can modify the \bar function 
so that it automatically changes the duration of the note just before it, or if 
I have to break out the text replacement tools to modify all my source files.

As a further complication, the dotted quarter notation hasn’t been settled yet, 
as there are some arguing for making it a quarter with a tenuto and others for 
a half note, so I’d really like a function that allows me to switch between 
those three options (dotted quarter, quarter with tenuto, or half note) 
relatively easily.

✝✝
Fr. Samuel, OSB
(R. Padraic Springuel)
St. Anselm’s Abbey
4501 South Dakota Ave, NE
Washington, DC, 20017
202-269-2300
(c) 202-853-7036

PAX ☧ ΧΡΙΣΤΟΣ




Re: Making markup functions parametric

2020-07-04 Thread David Kastrup
Lukas-Fabian Moser  writes:

>>> Of course I can do
>>>
>>> circlefunc = \markup\circle\etc
>>> \markup \test \circlefunc "whatever"
>> You can?  Have you tried?  \circlefunc here is quite equivalent to
>> \circle .
>
> Hm, I think I do not understand. With
>
> test =
> #(define-scheme-function (enclosure content)
>(markup-function? markup?)
>(list enclosure #{ \markup \box #content #}))
>
> I can do and compile
>
> \test \markup \circle \etc "whatever"
>
> as well as
>
> circlefunc = \markup\circle\etc
> \markup \test \circlefunc "whatever"
>
> but
>
> \markup \test \circle "whatever"
>
> fails with
>
> /tmp/frescobaldi-7l5ntq0c/tmp1iduvtxw/document.ly:8:15: Fehler: syntax
> error, unexpected MARKUP_FUNCTION, expecting \header
>
> \markup \test
>
> \circle "whatever"
>
> /tmp/frescobaldi-7l5ntq0c/tmp1iduvtxw/document.ly:8:33: Fehler:
> Haupt-Eingabe nicht beendet
>
> \markup \test \circle "whatever"
>
> schwerer Fehler: gescheiterte Dateien:
> "/tmp/frescobaldi-7l5ntq0c/tmp1iduvtxw/document.ly"
>
> So, I can't believe that \circlefunc and \circle should be actually
> equivalent.

Ah right, there is a difference.  They would be equivalent when writing

\markup circlefunc = \markup \circle \etc

The actually embedded markup function is the same, but it is packaged
differently.  You can get at the markup function part of the package by
using

test =
#(define-scheme-function (enclosure content)
  (markup-function? markup?)
  (list enclosure #{ \markup \box #content #}))

\markup \test \circle-markup "whatever"


Markups and their commands are an abomination.

-- 
David Kastrup


Re: Making markup functions parametric

2020-07-04 Thread Lukas-Fabian Moser

Of course I can do

circlefunc = \markup\circle\etc
\markup \test \circlefunc "whatever"

You can?  Have you tried?  \circlefunc here is quite equivalent to
\circle .


Hm, I think I do not understand. With

test =
#(define-scheme-function (enclosure content)
   (markup-function? markup?)
   (list enclosure #{ \markup \box #content #}))

I can do and compile

\test \markup \circle \etc "whatever"

as well as

circlefunc = \markup\circle\etc
\markup \test \circlefunc "whatever"

but

\markup \test \circle "whatever"

fails with

/tmp/frescobaldi-7l5ntq0c/tmp1iduvtxw/document.ly:8:15: Fehler: syntax 
error, unexpected MARKUP_FUNCTION, expecting \header


\markup \test

\circle "whatever"

/tmp/frescobaldi-7l5ntq0c/tmp1iduvtxw/document.ly:8:33: Fehler: 
Haupt-Eingabe nicht beendet


\markup \test \circle "whatever"

schwerer Fehler: gescheiterte Dateien: 
"/tmp/frescobaldi-7l5ntq0c/tmp1iduvtxw/document.ly"


So, I can't believe that \circlefunc and \circle should be actually 
equivalent.


Lukas



Re: Making markup functions parametric

2020-07-04 Thread David Kastrup
Lukas-Fabian Moser  writes:

> Hi David,
>
>> test =
>> #(define-scheme-function (enclosure content)
>>(markup-function? markup?)
>>(list enclosure #{ \markup \box #content #}))
>>
>> \markup \test \markup \circle \with-color #red \etc "whatever"
>
> Amazing, wonderfully elegant.
>
> Is there a way to avoid the second "\markup" and "\etc" in \markup
> \test \markup \box \etc "whatever" ?

No.

> Of course I can do
>
> circlefunc = \markup\circle\etc
> \markup \test \circlefunc "whatever"

You can?  Have you tried?  \circlefunc here is quite equivalent to
\circle .

-- 
David Kastrup



Re: Making markup functions parametric

2020-07-04 Thread Lukas-Fabian Moser

Hi David,


test =
#(define-scheme-function (enclosure content)
   (markup-function? markup?)
   (list enclosure #{ \markup \box #content #}))

\markup \test \markup \circle \with-color #red \etc "whatever"


Amazing, wonderfully elegant.

Is there a way to avoid the second "\markup" and "\etc" in \markup \test 
\markup \box \etc "whatever" ? Of course I can do


circlefunc = \markup\circle\etc
\markup \test \circlefunc "whatever"

but this requires an extra function definition, so it makes it harder to 
exchange \circle for something different. (In my own super-clumsy idea I 
could write \markup \test #'circle "whatever".)


Lukas




Re: Making markup functions parametric

2020-07-04 Thread David Kastrup
Urs Liska  writes:

> In the following markup command definition
>
> #(define-markup-command (test layout props enclosure content)
>   (scheme? markup?)
>(interpret-markup layout props (markup #:circle content)))
>
> I would like to make the #:circle parametric, i.e. I want to pass
> something into the function (e.g. as the 'enclosure' argument) and
> apply the corresponding markup function within the markup expression.
> The argument could be a function directly or a symbol from which it is
> referenced.
>
> Howeve, I would like to dynamically apply the markup function here
> rather than create a structure that chooses a complete markup
> expression based on the desirec markup type.
>
> Unfortunately I don't really have an idea what "#:circle" actually
> *is*, so I have no clue about getting where I need to.
>
> BestUrs

test =
#(define-scheme-function (enclosure content)
  (markup-function? markup?)
  (list enclosure #{ \markup \box #content #}))

\markup \test \markup \circle \with-color #red \etc "whatever"



-- 
David Kastrup


Re: Making markup functions parametric

2020-07-04 Thread Urs Liska
Hi Lukas,

Am Samstag, den 04.07.2020, 10:22 +0200 schrieb Lukas-Fabian Moser:
> Hi Urs,
> 
> > I have tried various things, but I don't seem to understand how
> > that
> > primitive-eval actually works here. Your solution does only work
> > when
> > the input is a simple markup (string), not when it is wrapped in
> > other
> > markup commands.
> 
> It seems to work quite robustly if you draw the given content markup 
> into a stencil and insert this stencil in the markup expression that 
> will be fly-evaluated:
> 
> \version "2.20"
> 
> #(define (get-scheme-markup-function func)
> (symbol-append 'make- func '-markup))
> 
> #(define-markup-command (enclose layout props func content)(symbol?
> markup?)
> (interpret-markup layout props
>   (primitive-eval
>(list 'markup
>  (list
>   (get-scheme-markup-function func)
>   `(make-stencil-markup ,(interpret-
> markup 
> layout props content)))
> 
> \markup \enclose #'box "C"
> \markup \enclose #'circle \italic \concat { "Camel" "Case" }
> \markup \enclose #'circle \enclose #'box \italic "E"
> 
> Does this help?
> 

Yes, indeed, thank you very much! With it I could for now complete my
function for a highly configurable object to denote the reference key
in harmonic analysis.

The following code produces the (non-sensical) attached result. It is
also a first demonstration of the new "properties/property
sets/presets" feature I'm right now finalizing for openLilyLib.
If you want to check it our yourself, the code is in oll-core (branch
'properties') and anaLYsis (branch 'harmony-initial'). The full
implementation of the function (also with property sets in action) can
be seen in 
https://github.com/openlilylib/analysis/blob/harmony-initial/harmony/ref-key.ily
When a function is created with the with-property-set macro arguments
are type-checked against the property set, defaults are given,
properties can be changed globally, in presets or locally in a call.
Within a function there's a function 'property' available to retrieve
the current property value. There's also a function 'use-preset' (not
used in this example, which works together with a set of preset filters
to determine whether a function should be "used" based on the given
presets. This can be used to selectively activate functions, for
example to hide them until needed or to highlight them on demand. The
Frames, Arrows, and Highlighters modules of anaLYsis are the first
real-world examples for this new functionality, which I'm pretty
excited about.

Best
Urs

\version "2.20.0"

\include "oll-core/package.ily"
\loadModule analysis.harmony

\definePreset \with {
  color = #red
  box-padding = 1
} analysis.harmony.ref-key default

\definePreset \with {
  parent = default
  box-type = ellipse
  box-padding = 0.3
  space-before-separator = 0.7
} analysis.harmony.ref-key one

\definePreset \with {
  parent = default
  accidental-size = 4
  space-before-accidental = -0.5
} analysis.harmony.ref-key two


{
  <<
\new Staff { c' d' e' f' g' a' b' c' }
\new Lyrics \lyricmode {
  \refKey  \with  { preset = one } C> T1
  \refKey  \with  { preset = two } F< S
}
  >>
}

(The complete list of (so far) configurable properties for \refKey can
be seen here: 
https://github.com/openlilylib/analysis/blob/harmony-initial/harmony/ref-key.ily#L20-L38
)

> Best
> Lukas
> 
> 


Re: Making markup functions parametric

2020-07-04 Thread Lukas-Fabian Moser

Hi Urs,


I have tried various things, but I don't seem to understand how that
primitive-eval actually works here. Your solution does only work when
the input is a simple markup (string), not when it is wrapped in other
markup commands.


It seems to work quite robustly if you draw the given content markup 
into a stencil and insert this stencil in the markup expression that 
will be fly-evaluated:


\version "2.20"

#(define (get-scheme-markup-function func)
   (symbol-append 'make- func '-markup))

#(define-markup-command (enclose layout props func content)(symbol? markup?)
   (interpret-markup layout props
 (primitive-eval
  (list 'markup
    (list
 (get-scheme-markup-function func)
 `(make-stencil-markup ,(interpret-markup 
layout props content)))


\markup \enclose #'box "C"
\markup \enclose #'circle \italic \concat { "Camel" "Case" }
\markup \enclose #'circle \enclose #'box \italic "E"

Does this help?

Best
Lukas





Re: Making markup functions parametric

2020-07-04 Thread Urs Liska
Am Samstag, den 04.07.2020, 05:28 +0200 schrieb Urs Liska:
> 
> Am 3. Juli 2020 23:33:42 MESZ schrieb Lukas-Fabian Moser 
> :
> > > #(define (get-scheme-markup-function func)
> > >(string->symbol
> > > (string-append "make-"
> > >(symbol->string func)
> > >"-markup")))
> > 
> > ... which should be replaced by
> > 
> > #(define (get-scheme-markup-function func)
> >(symbol-append 'make- func '-markup))
> > 
> 
> That's fantastic, thank you very much.
> (You'll soon see that code again, I assume ;-) ).

Oops, unfortunately it's not enough ...

I have tried various things, but I don't seem to understand how that
primitive-eval actually works here. Your solution does only work when
the input is a simple markup (string), not when it is wrapped in other
markup commands. 
Consider this:

\version "2.20"

#(define (get-scheme-markup-function func)
   (symbol-append 'make- func '-markup))

#(define-markup-command (enclose layout props func content)(symbol?
markup?)
   (ly:message "content: ~a" content)
   (interpret-markup layout props
 (primitive-eval
  (list 'markup
(list
 (get-scheme-markup-function func)
 content)

\markup \enclose #'box "C"
\markup \enclose #'circle \concat { "D" } 
\markup \enclose #'circle \italic "E"


While it works for the first case, both the \concat and the \italic
produce an error like
  Wrong type to apply: "D"

The content entering the markup command is printed as
  (# (D))
or
  (# E)

What will go there in the \enclose is a concatted and potentially
formatted markup expression.

I got one step further accepting a second symbol, which made the
\italic work:

\version "2.20"

#(define (get-scheme-markup-function func)
   (symbol-append 'make- func '-markup))

#(define-markup-command (enclose layout props func func2
content)(symbol? symbol? markup?)
   (ly:message "content: ~a" content)
   (interpret-markup layout props
 (primitive-eval
  (list 'markup
(list
 (get-scheme-markup-function func)
 (list (get-scheme-markup-function func2)
 content))

%\markup \enclose #'box "C"
%\markup \enclose #'circle #'concat \concat { "D" "e" }
\markup \enclose #'circle #'italic "E"


But with the \concat it still doesn't work.
Content prints
  (# Best
> Urs
> 
> > Sorry, I had not realized that symbol-append is available in Guile
> > 1.8.
> > 
> > Lukas




Re: Making markup functions parametric

2020-07-03 Thread Urs Liska



Am 3. Juli 2020 23:33:42 MESZ schrieb Lukas-Fabian Moser :
>
>> #(define (get-scheme-markup-function func)
>>    (string->symbol
>>     (string-append "make-"
>>    (symbol->string func)
>>    "-markup")))
>
>... which should be replaced by
>
>#(define (get-scheme-markup-function func)
>    (symbol-append 'make- func '-markup))
>

That's fantastic, thank you very much.
(You'll soon see that code again, I assume ;-) ).

Best
Urs

>Sorry, I had not realized that symbol-append is available in Guile 1.8.
>
>Lukas

-- 
Diese Nachricht wurde von meinem Android-Gerät mit K-9 Mail gesendet.



Re: Making markup functions parametric

2020-07-03 Thread Lukas-Fabian Moser




#(define (get-scheme-markup-function func)
   (string->symbol
    (string-append "make-"
   (symbol->string func)
   "-markup")))


... which should be replaced by

#(define (get-scheme-markup-function func)
   (symbol-append 'make- func '-markup))

Sorry, I had not realized that symbol-append is available in Guile 1.8.

Lukas




Re: Making markup functions parametric

2020-07-03 Thread Lukas-Fabian Moser

Hi Urs,


Thanks a lot. That's exactly the kind of procedure I can store and
apply:

\version "2.20.0"

#(define-markup-command (dyna layout props func content)(symbol?
markup?)
(let*
 ((funcs
   `((box . ,make-box-markup)
 (circle . ,make-circle-markup
 (interpret-markup layout props
   (markup
((assq-ref funcs func) content)

\markup \dyna #'circle "C:"

\markup \dyna #'box "C:"


You don't even need to hardcode the make-xxx-markup functions:

\version "2.20"

#(define (get-scheme-markup-function func)
   (string->symbol
    (string-append "make-"
   (symbol->string func)
   "-markup")))

#(define-markup-command (dynb layout props func content)(symbol? markup?)
 (interpret-markup layout props
   (primitive-eval
    (list 'markup
  (list
(get-scheme-markup-function func)
   content)


\markup \dynb #'circle "C"
\markup \dynb #'box "C"

Best
Lukas




Re: Making markup functions parametric

2020-07-03 Thread Aaron Hill

On 2020-07-03 1:07 pm, Urs Liska wrote:

But I'd rather do something like

  (markup (assq-ref enclosures enclosure) "CC")


markup is a macro, and macros appear to have unique rules of evaluation.

The following approach defers the macro expansion:


\version "2.20.0"

#(define-markup-command
  (test layout props enclosure content)
  (boolean? markup?)
  (interpret-markup layout props
(primitive-eval
  (list 'markup
(if enclosure #:box #:circle)
content

\markup {
  \test ##t box
  \test ##f circle
}



-- Aaron Hill



Re: Making markup functions parametric

2020-07-03 Thread Ralf Mattes

Am Freitag, 03. Juli 2020 22:07 CEST, Urs Liska  schrieb:


> > Syntacilally? That would be a scheme keyword.
>
> So that would be difficult to inject from a variable/argument, isn't
> it?

No, why? You can of course store a keyword in a variable and/or pass it as an 
argument.

> I can of course do
>
>   (cond
>((eq? enclosure 'circle)
> (markup #:circle "CC"))
>((eq? enclosure 'box)
> (markup #:box "CC)))

Looks a bit too complicated - iff you insist on using symbols as parameters you
could use guile's symbol->keyword function.

> But I'd rather do something like
>
>   (markup (assq-ref enclosures enclosure) "CC")
>
> i.e. looking up the appropriate function instead of creating a
> conditional chain.

But #:circle isn't a function ...

 Cheers RalfD

> Any ideas?
>
> ThanksUrs
>
> >
> >  Cheers, RalfD
> >
> > > BestUrs
> > >
> > >
> >
> >
> >
>
>



--
Ralf Mattes

Hochschule für Musik Freiburg
Projektleitung HISinOne
Schwarzwaldstr. 141, D-79102 Freiburg
http://www.mh-freiburg.de






Re: Making markup functions parametric

2020-07-03 Thread Urs Liska
Hi Robin,

Am Freitag, den 03.07.2020, 22:11 +0200 schrieb Robin Bannister:
> Urs Liska wrote:
> 
> > Unfortunately I don't really have an idea what "#:circle" actually
> > *is*, so I have no clue about getting where I need to.
> 
> I think it's a sort of macro thingy, trying to be easy to be used.
> 
> Look at 'Known issues and warnings' at the bottom of
> https://lilypond.org/doc/v2.20/Documentation/extending/markup-construction-in-scheme
> 
> So make-circle-markup would be equivalent.

Thanks a lot. That's exactly the kind of procedure I can store and
apply:

\version "2.20.0"

#(define-markup-command (dyna layout props func content)(symbol?
markup?)
   (let*
((funcs
  `((box . ,make-box-markup)
(circle . ,make-circle-markup
(interpret-markup layout props
  (markup 
   ((assq-ref funcs func) content)

\markup \dyna #'circle "C:"

\markup \dyna #'box "C:"

Best
Urs

> 
> 
> Cheers,
> Robin




Re: Making markup functions parametric

2020-07-03 Thread Robin Bannister

Urs Liska wrote:



Unfortunately I don't really have an idea what "#:circle" actually
*is*, so I have no clue about getting where I need to.



I think it's a sort of macro thingy, trying to be easy to be used.

Look at 'Known issues and warnings' at the bottom of
https://lilypond.org/doc/v2.20/Documentation/extending/markup-construction-in-scheme

So make-circle-markup would be equivalent.


Cheers,
Robin



Re: Making markup functions parametric

2020-07-03 Thread Urs Liska
Am Freitag, den 03.07.2020, 21:58 +0200 schrieb Ralf Mattes:
>  
> Am Freitag, 03. Juli 2020 21:52 CEST, Urs Liska <
> li...@openlilylib.org> schrieb: 
>  
> > Unfortunately I don't really have an idea what "#:circle" actually
> > *is*, so I have no clue about getting where I need to.
> 
> Syntacilally? That would be a scheme keyword. 

So that would be difficult to inject from a variable/argument, isn't
it?

I can of course do

  (cond
   ((eq? enclosure 'circle)
(markup #:circle "CC"))
   ((eq? enclosure 'box)
(markup #:box "CC)))

But I'd rather do something like

  (markup (assq-ref enclosures enclosure) "CC")

i.e. looking up the appropriate function instead of creating a
conditional chain.

Any ideas?

ThanksUrs

> 
>  Cheers, RalfD
>  
> > BestUrs
> > 
> > 
>  
>  
>  




Re: Making markup functions parametric

2020-07-03 Thread Ralf Mattes

Am Freitag, 03. Juli 2020 21:52 CEST, Urs Liska  schrieb:

> Unfortunately I don't really have an idea what "#:circle" actually
> *is*, so I have no clue about getting where I need to.

Syntacilally? That would be a scheme keyword.

 Cheers, RalfD

> BestUrs
>
>



--
Ralf Mattes

Hochschule für Musik Freiburg
Projektleitung HISinOne
Schwarzwaldstr. 141, D-79102 Freiburg
http://www.mh-freiburg.de






Making markup functions parametric

2020-07-03 Thread Urs Liska
In the following markup command definition

#(define-markup-command (test layout props enclosure content)
  (scheme? markup?)
   (interpret-markup layout props (markup #:circle content)))

I would like to make the #:circle parametric, i.e. I want to pass
something into the function (e.g. as the 'enclosure' argument) and
apply the corresponding markup function within the markup expression.
The argument could be a function directly or a symbol from which it is
referenced.

Howeve, I would like to dynamically apply the markup function here
rather than create a structure that chooses a complete markup
expression based on the desirec markup type.

Unfortunately I don't really have an idea what "#:circle" actually
*is*, so I have no clue about getting where I need to.

BestUrs




Re: Access "current duration" from music functions

2020-06-26 Thread Lukas-Fabian Moser

Hi David,

(More concretely, in our use case, \myFunction expected "a chord or a
duration". This leads to a behaviour where

a2 \myFunction 4

does not change the "current duration", but

a2 \myFunction 4

does.)

So let it expect a music expression only.  4 is a pitchless note event.


Thanks for the tip! This actually works in "normal" note entry mode, but 
it doesn't in our case, since our function is (at the current point of 
time) to be used in \figuremode, and here, the parser seems not to be 
willing to interpret 4 as ly:music?.


The problem is that in reality (sorry that I didn't mention this) our 
function is supposed to be given


- either a bass figure (e.g. <6 4> or <6 5>8)
- or just a duration.

This works with a predicate of the form (or (ly:music? x) (ly:duration? 
x)), but then the duration is not taken as the next default_duration. 
I'm not aware of any way let a music function accept a bass figure 
without explicit \figuremode - and I'd very much prefer to write this 
_once_ (at the outside), and not in every function call (at the inside).



Interestingly,

zing =
#(define-void-function (x) (ly:music?)
   #f)

\fixed c' { c1 \zing c4 c \zing 2 c c }

does not actually work.  But that arguably is a bug that should get
fixed.  If a duration is accepted as a note, it should affect the
default note duration.


Yes, probably. If I'm informed correctly I should not try to open an 
issue myself, but send a mail the bug list?


Lukas




Re: Access "current duration" from music functions

2020-06-26 Thread David Kastrup
Lukas-Fabian Moser  writes:

> Hi David,
>>> But it does not seem to be possible to _set_ this "current duration"
>>> from scheme, does it?
>> Why would that be a good idea?
>
> Consider a situation where \myFunction with signature (ly:duration?)
> generates some complex music expression in which the given duration is
> used.
>
> Currently, in
>
> (*) { a2 \myFunction 4 c }
>
> is equivalent to
>
> { a2 \myFunction 4 c2 }
>
> but in some situations it might be more natural for the user to expect
> (*) to yield
>
> { a2 \myFunction 4 c4 }.
>
>
> (More concretely, in our use case, \myFunction expected "a chord or a
> duration". This leads to a behaviour where
>
> a2 \myFunction 4
>
> does not change the "current duration", but
>
> a2 \myFunction 4
>
> does.)

So let it expect a music expression only.  4 is a pitchless note event.

Interestingly,

zing =
#(define-void-function (x) (ly:music?)
  #f)

\fixed c' { c1 \zing c4 c \zing 2 c c }

does not actually work.  But that arguably is a bug that should get
fixed.  If a duration is accepted as a note, it should affect the
default note duration.

-- 
David Kastrup



Re: Access "current duration" from music functions

2020-06-26 Thread Lukas-Fabian Moser

Hi David,

But it does not seem to be possible to _set_ this "current duration"
from scheme, does it?

Why would that be a good idea?


Consider a situation where \myFunction with signature (ly:duration?) 
generates some complex music expression in which the given duration is used.


Currently, in

(*) { a2 \myFunction 4 c }

is equivalent to

{ a2 \myFunction 4 c2 }

but in some situations it might be more natural for the user to expect 
(*) to yield


{ a2 \myFunction 4 c4 }.


(More concretely, in our use case, \myFunction expected "a chord or a 
duration". This leads to a behaviour where


a2 \myFunction 4

does not change the "current duration", but

a2 \myFunction 4

does.)

Lukas




Re: Access "current duration" from music functions

2020-06-26 Thread David Kastrup
Lukas-Fabian Moser  writes:

> Hi Aaron & David,
>> Well, it's more a bug like anything else I guess, but
>>
>> (ly:music-property #{ q #} 'duration)
>>
>> at the current point of time would appear to do the trick.
>>
> Which seems solve the "reading" part of the problem, yes. Thanks much
> (and also to Aaron for pointing out the corresponding bit of C++).
>
> And basically, your solution seems to be a variant (of course much
> more elegant!) of my clumsy
>
> get-current-duration =
> #(define-scheme-function () ()
>    (let* ((tempmusic #{ {a} #})
>   (els (ly:music-property tempmusic 'elements)))
>  (ly:music-property (car els) 'duration)))
>
> But it does not seem to be possible to _set_ this "current duration"
> from scheme, does it?

Why would that be a good idea?

-- 
David Kastrup



Re: Access "current duration" from music functions

2020-06-26 Thread Lukas-Fabian Moser

Hi Aaron & David,

Well, it's more a bug like anything else I guess, but

(ly:music-property #{ q #} 'duration)

at the current point of time would appear to do the trick.

Which seems solve the "reading" part of the problem, yes. Thanks much 
(and also to Aaron for pointing out the corresponding bit of C++).


And basically, your solution seems to be a variant (of course much more 
elegant!) of my clumsy


get-current-duration =
#(define-scheme-function () ()
   (let* ((tempmusic #{ {a} #})
  (els (ly:music-property tempmusic 'elements)))
 (ly:music-property (car els) 'duration)))

But it does not seem to be possible to _set_ this "current duration" 
from scheme, does it?


Lukas




Re: Access "current duration" from music functions

2020-06-26 Thread David Kastrup
Aaron Hill  writes:

> On 2020-06-26 6:13 am, Lukas-Fabian Moser wrote:
>> Is it possible to access this "current duration" from a music or
>> scheme function?
>
> Looks to be stored in Lily_parser::default_duration_ which, while
> public in the C++ interface, does not appear to be exposed to Scheme
> as far as I can tell.

Well, it's more a bug like anything else I guess, but

(ly:music-property #{ q #} 'duration)

at the current point of time would appear to do the trick.

-- 
David Kastrup



Re: Access "current duration" from music functions

2020-06-26 Thread Aaron Hill

On 2020-06-26 6:13 am, Lukas-Fabian Moser wrote:

Is it possible to access this "current duration" from a music or
scheme function?


Looks to be stored in Lily_parser::default_duration_ which, while public 
in the C++ interface, does not appear to be exposed to Scheme as far as 
I can tell.



-- Aaron Hill



Access "current duration" from music functions

2020-06-26 Thread Lukas-Fabian Moser

Folks,

the following question came up (well, by me) in the recent thread start 
by Urs Liska "Combine Text/Lyrics with bass figures":


The LilyPond parser (?) has some notion of "current duration": A note 
with explicit duration sets the next duration that is assumed if none is 
given. Hence { a4 b a b8 a b } will create three crotchets followed by 
three quavers.


Is it possible to access this "current duration" from a music or scheme 
function?


a) for reading: in order to create events with the same duration that 
any note would get if directly entered?
(This is possible by using #{ $pitch #} and the like, but that does not 
make the duration in itself scheme-readable.)


Something like { a8. \myFunction c16 } where \myFunction, for instance, 
displays "I would create a 8."


b) for writing: in order to tell the parser which duration to assume for 
the next explicitly entered note (if it does not have an explicit 
duration) ?


Something like { a4 \myGunction b a } where \myGunction performs some 
magic such that the following b a are interpreted as b8 a8?


Best
Lukas





Re: Regexp Functions

2020-06-20 Thread Freeman Gilmore
On Tue, Jun 16, 2020 at 4:41 AM Aaron Hill  wrote:
>
> On 2020-06-15 11:16 pm, Freeman Gilmore wrote:
> > "y" could represent  one of my accidentals, "-y" inverted.   "-ax3" ,
> > one of my accidentals ,
> > "-a" used 3 times; like a flag, but needs to be inverted to "-x3".
> > "+rx2" needs a space like "+r x2".   "t" standard accidental. All "+"
> > removed.
> > "-y -ax3 +rx2 -stx2 t" becomes "-y -a -x3 r x2 -st -x2 t" , then
> > convert to list
> >  ("-y" "-a" "-x3" "r" "x2" "-st" "-x2" "t").
>
> This is sounding much more like you have invented a language/grammar
> that needs to be parsed rather than simply wanting to apply some
> arbitrary text transformation.  The interest in string manipulation
> stems from wanting to support a form of shorthand within the microtonal
> ligature notation.
>
> To that end, allow me to present an alternate way to attack the problem.
>   Consider:
>
> 
> (apply append
>(map (lambda (m)
>   (let ((inv (or (match:substring m 2) "")))
> (map (lambda (s) (string-append inv s))
>  (filter
>(lambda (s) (not (string-null? s)))
>(map (lambda (n) (or (match:substring m n) ""))
> '(3 4))
> (list-matches
>   "((-)|\\+?)([a-z]*)(x[0-9]+)?"
>   "-y -ax3 +rx2 -stx2 t")))
> 
> 
> ("-y" "-a" "-x3" "r" "x2" "-st" "-x2" "t")
> 
>
> Several assumptions are being made within the core regular expression
> above; but what is important to note is that we are not doing any text
> substitution of the original input.  Rather, we are using a regular
> expression to identify the valid "words" and extract the key parts of
> those words.  While you can certainly act upon the information right
> away, I am showing a way to build a list of strings that should meet
> your specification.
>
>
> -- Aaron Hill

Aaron:

I wish I had more time to stay on this, with the good help I am
getting. Looks like mapping is the better way to go.There is
some more information to be included if mapping is used that cannot be
pleased in as I am learning.Simple string manipulation I can do;
but reading about regular expressions does not give me the intuitive
ability to manipulate them without a lot more study, with my wrote
memory a lot more time.So help with this would be appreciated.

Input string:

1.  input example  \j "-y-ax3rex2 -31x2 es accidentalFlat+6 "

2.  “-“ is part of the name of the accidental and can represent the
name of an inverted accidental.

3.  size of white space is not important

4.  the accidentals are separated by “ “, “+”, “ +”; “-“, “  -“   (“-“
is part of the name of the accidental)

5.  accidentals are of the form “…” or “-…”  with rang [0 - 9]*|[a –
z]*|[A – Z]* (abbreviated or full name)

 6.  accidentals that are applied more than one time can be ligatures
“…xn”; “-…xn” , rang of n 2 – 5, (no “-x” or “-n”)


Output list of strings:

1.  order of accidentals to be maintained

2.  “+” are eliminated

3.  “-“ are retained   (part of name of accidental)

4.  accidentals are of the form “…” or “-…”  with rang [0 - 9]*|[a –
z]*|[A – Z]*

5.  “…xn” => “…” “xn”  (will form a true ligature)

6.  “-…xn” => “-…” “-xn”  (will form a true ligature)

7.  So far, each accidental has no space between them, add an “SP”
between each split

 except “…” “xn”  and “-…” “-xn”  (the true ligatures),  “Sp” is a
narrow blank glyph.

8.  Output example: ("-y” “Sp” “-a” “-x3 “Sp” “re” “x2” “Sp” “-st”
“-x2” “Sp” “es” “Sp” “accidentalFlat” “Sp” “6”)


Simple string manipulation does not get me what I also need to handle
the ligatures in the following.

"-y-ax3rx2 -31x2 es accidentalFlat+6"  => (-y (* -a 3) (* re
2) (* -v31 2) es accidentalFlat +v6) , here the “-“ is not part of the
name of the variable, but just give a negative value to it.  Note v’s
are added to string names that are numbers to create a variable, “+6”
=> +v6, or => v6,   Also +’s can be retained or not.

I will then ‘apply +’ to this list.   So would this work instead, =>
(+ -y (* -a 3) (* re 2) (* -v31 2) es accidentalFlat +v6)


I have developed a system of accidental that I want to try, and I want
the program to be usable for other systems as well.

I would be using short names for my accidentals (some numbers if I do
not have a problem with them, they work so far).   Inverted
accidentals have “-“ added to the name of the glyph.   An accidental
used more than one time is a ligature.The input accidentals are
separated by “ “ or “+” and “-“ for inverted accidentals, being part
of the name.

Thank you, ƒg



Re: Regexp Functions

2020-06-16 Thread Freeman Gilmore
On Tue, Jun 16, 2020 at 4:41 AM Aaron Hill  wrote:
>
> On 2020-06-15 11:16 pm, Freeman Gilmore wrote:
> > "y" could represent  one of my accidentals, "-y" inverted.   "-ax3" ,
> > one of my accidentals ,
> > "-a" used 3 times; like a flag, but needs to be inverted to "-x3".
> > "+rx2" needs a space like "+r x2".   "t" standard accidental. All "+"
> > removed.
> > "-y -ax3 +rx2 -stx2 t" becomes "-y -a -x3 r x2 -st -x2 t" , then
> > convert to list
> >  ("-y" "-a" "-x3" "r" "x2" "-st" "-x2" "t").
>
> This is sounding much more like you have invented a language/grammar
> that needs to be parsed rather than simply wanting to apply some
> arbitrary text transformation.  The interest in string manipulation
> stems from wanting to support a form of shorthand within the microtonal
> ligature notation.
>
> To that end, allow me to present an alternate way to attack the problem.
>   Consider:
>
> 
> (apply append
>(map (lambda (m)
>   (let ((inv (or (match:substring m 2) "")))
> (map (lambda (s) (string-append inv s))
>  (filter
>(lambda (s) (not (string-null? s)))
>(map (lambda (n) (or (match:substring m n) ""))
> '(3 4))
> (list-matches
>   "((-)|\\+?)([a-z]*)(x[0-9]+)?"
>   "-y -ax3 +rx2 -stx2 t")))
> 
> 
> ("-y" "-a" "-x3" "r" "x2" "-st" "-x2" "t")
> 

\version "2.20.0"
 #(use-modules (ice-9 regex))

#(define V "-6 -ax3 +rx2 -31x2 t" )%  note change, numbers as
well used for  names of accidentals

#(define W (apply append
   (map (lambda (m)
  (let ((inv (or (match:substring m 2) "")))
(map (lambda (s) (string-append inv s))
 (filter
   (lambda (s) (not (string-null? s)))
   (map (lambda (n) (or (match:substring m n) ""))
'(3 4))
 (list-matches
  "((-)|\\+?)([0-9]*|[a-z]*)(x[0-9]+)?"   %  do not
that this fool you, this chang is about
  V
%the only thing I think i understand here

 #(write W)
==
("-6" "-a" "-x3" "r" "x2" "-31" "-x2" "t")
==
I am running out of time, but the mapping may be extended to include a
ruffer input that i have already
converted to the  form like V above using 4 steps.   May take awhile
to get back.

Thank you, ƒg

>
> Several assumptions are being made within the core regular expression
> above; but what is important to note is that we are not doing any text
> substitution of the original input.  Rather, we are using a regular
> expression to identify the valid "words" and extract the key parts of
> those words.  While you can certainly act upon the information right
> away, I am showing a way to build a list of strings that should meet
> your specification.
>
>
> -- Aaron Hill



Re: Regexp Functions

2020-06-16 Thread Aaron Hill

On 2020-06-15 11:16 pm, Freeman Gilmore wrote:

"y" could represent  one of my accidentals, "-y" inverted.   "-ax3" ,
one of my accidentals ,
"-a" used 3 times; like a flag, but needs to be inverted to "-x3".
"+rx2" needs a space like "+r x2".   "t" standard accidental. All "+" 
removed.
"-y -ax3 +rx2 -stx2 t" becomes "-y -a -x3 r x2 -st -x2 t" , then 
convert to list

 ("-y" "-a" "-x3" "r" "x2" "-st" "-x2" "t").


This is sounding much more like you have invented a language/grammar 
that needs to be parsed rather than simply wanting to apply some 
arbitrary text transformation.  The interest in string manipulation 
stems from wanting to support a form of shorthand within the microtonal 
ligature notation.


To that end, allow me to present an alternate way to attack the problem. 
 Consider:



(apply append
  (map (lambda (m)
 (let ((inv (or (match:substring m 2) "")))
   (map (lambda (s) (string-append inv s))
(filter
  (lambda (s) (not (string-null? s)))
  (map (lambda (n) (or (match:substring m n) ""))
   '(3 4))
   (list-matches
 "((-)|\\+?)([a-z]*)(x[0-9]+)?"
 "-y -ax3 +rx2 -stx2 t")))


("-y" "-a" "-x3" "r" "x2" "-st" "-x2" "t")


Several assumptions are being made within the core regular expression 
above; but what is important to note is that we are not doing any text 
substitution of the original input.  Rather, we are using a regular 
expression to identify the valid "words" and extract the key parts of 
those words.  While you can certainly act upon the information right 
away, I am showing a way to build a list of strings that should meet 
your specification.



-- Aaron Hill



Re: Regexp Functions

2020-06-16 Thread Freeman Gilmore
On Mon, Jun 15, 2020 at 10:32 PM Aaron Hill  wrote:
>
> On 2020-06-15 5:57 pm, Freeman Gilmore wrote:
> > Thank you Aaron.  :
> >
> > In order to ask my question, not knowing how to ask, I simplified it
> > too much.   The one or both of the first two below  may work but i do
> > not know how to apply them.
>
> This is a meta problem I have often struggled with.  While trying to
> solve problem A on my own, I encounter problem B of which I need help.
> So I seek guidance on problem B while omitting the context of problem A.
>   The answers found might address problem B but do not work well in the
> greater context.  The philosophical question is whether I should have
> originally framed my question about problem B with the scope of problem
> A or if I should have simply asked about problem A and allow the natural
> discussion to bring up problem B on its own.
>
> Seeing more of what you have in mind below, I am confused about its
> connection with LilyPond.  On the one hand, I think I can help you
> wrangle your text in the way you want; but I am worried that we are
> fighting a bit of the meta problem above.  What is this text intended to
> represent with regards to music?

Microtonal accidentals, some of my own.

> What are the semantics of the transformation you want to apply?

The string example is an exaggerated but posable string of
accidentals, used for a note.
Applied as a ligather using a list of strings
.
>  Could there be another way to express
> things that might be easier to work with or that might better fit the
> patterns of LilyPond?

Not for what I want to try.

> Mind you, the answers to those questions would be taking us from the
> narrow problem into the broader scope.  And perhaps only you truly
> benefit from answering them.
Probably.
>
>
> > Say I have "-y -ax3 +rx2 -stx2 t"

"y" could represent  one of my accidentals, "-y" inverted.   "-ax3" ,
one of my accidentals ,
"-a" used 3 times; like a flag, but needs to be inverted to "-x3".
"+rx2" needs a space like "+r x2".   "t" standard accidental. All "+" removed.
"-y -ax3 +rx2 -stx2 t" becomes "-y -a -x3 r x2 -st -x2 t" , then convert to list
 ("-y" "-a" "-x3" "r" "x2" "-st" "-x2" "t").


> >   I wanted, if  "-" followed "x"  before a space, then replace the "x" with 
> > " -x" for each.If I use
> > "(^-.*)x" "-y -ax3 +rx2 -stx2 t"  'pre 1 " -x" 'post) , from what I
> > have read, this would happen at the first "x" from the right.   So
> > that will not work.
>
> Ah, there are at least two critical pieces of information I overlooked.
> The prefix in question does not necessarily occur at the beginning of
> the string.  Also, the string we are looking for might occur multiple
> times so we want the nearest match.
>
> We can address this as follows by being more precise in our regular
> expression.
>
> /^/ becomes /(^|\s)/
>
> Here we are using alteration to assert that we are either at the
> beginning of the string or that we have just seen a whitespace
> character.
>
> /.*/ becomes /[^x]*/
>
> All quantifiers in POSIX ERE (and thusly GNU ERE) are greedy, so care
> must be taken to limit what can be matched so we do not grab too much.
> We do not want an "x" to be matched, so we use a negated character
> class.
>
> Let us see this working:
>
> 
> (regexp-substitute/global #f
>"((^|\\s)-[^x]*)(x)"
>"-y -ax3 +rx2 -stx2 t"
>'pre 1 " -" 3 'post)
> 
> 
> "-y -a -x3 +rx2 -st -x2 t"
> 
>
> Seems good.  But therein lies the problem with test-driven development
> (TDD).  Our code will only be as good as our test cases, which is why we
> are instructed to "test everything that can possibly break".  There is a
> hidden problem above due to using /[^x]*/.  This matches more than what
> we want.  In particular, it matches whitespace.
>
> The first substitution in the above example was not effectively
> operating on "-ax3" but rather on "-y -ax3".  The end result looks
> correct, but what if we had said "-y +ax3"?  This would have been
> matched because we included whitespace, resulting in "-y +a -x3", which
> is presumably incorrect.
>
> The fix is simple: add [:space:] to the negated character class.  Below
> I have amended the test string to include "-z +bx4" which should remain
> unchanged.
>
> 
> (regexp-substitute/global #f
>"((^|\\s)-[^x[:space:]]*)(x)"
>"-y -ax3 +rx2 -stx2 t -z +bx4"
>'pre 1 " -" 3 'post)
> 
> 
> "-y -a -x3 +rx2 -st -x2 t -z +bx4"
> 
>
> What about "-x"?  Our expression will match that because we are using
> the zero-or-more quantifier (*).  The resulting substitution, "- -x", is
> probably not what we want.  We should ensure that there is at least one
> non-"x" character:
>
> 
> (regexp-substitute/global #f
>"((^|\\s)-[^x[:space:]]+)(x)"
>"-y -ax3 +rx2 -stx2 t -z +bx4 -x"
>'pre 1 " -" 3 'post)
> 
> 
> "-y -a -x3 +rx2 -st -x2 t -z +bx4 -x"
> 
>
>
> > My next step was to convert the string to a list of strings.  So if i
> > convert first, 

  1   2   3   4   >