Re: Making markup functions parametric
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
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
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
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
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
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
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
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
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
#(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
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
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
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
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
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
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
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