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