lilypond-user
[Top][All Lists]
Advanced

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

Re: SVG export - how might you add classes for all graphical objects?


From: Matt Hood
Subject: Re: SVG export - how might you add classes for all graphical objects?
Date: Wed, 30 Jun 2021 11:26:35 +1000

P.S. (Sorry to be spamming the list!)

> Out of curiosity: what tool is this for?

A browser-based rhythm game I'm putting together, which makes use of
Lilypond's fantastic proportional notation feature. The addition of
classes is used to separate moving objects (NoteHead, Stem, BarLine,
etc) from non-moving objects (StaffLine, Clef, TimeSignature).

Cheers,
Matt.

On Wed, Jun 30, 2021 at 2:43 AM Jean Abou Samra <jean@abou-samra.fr> wrote:
>
> Hello,
>
> > Le 29/06/2021 10:42, Matt Hood <matthood0@gmail.com> a écrit :
> >
> >
> > Hi everyone,
> >
> > I'm working with lilypond output in the browser, using its SVG export
> > function. Lilypond permits attaching attributes to particular kinds of
> > grobs, e.g.:
> >
> > {
> > \override NoteHead.output-attributes =
> > #'((class . "NoteHead"))
> > c
> > }
> >
> > The above will cause all NoteHead objects to have the following SVG:
> >
> > <g class="NoteHead">
> > ...NoteHead grob SVG elements...
> > </g>
> >
> > My question is: how can I make it so that all graphical objects have
> > their name in the class attribute?
> >
> > I've tried using the following scheme function:
> >
> > #(define (add-class grob grob-origin context)
> > (let (name (cdr (assoc 'name
>
> This lacks a pair of parentheses around the
> bindings. You might have posted the wrong
> version of your code.
>
> > (ly:grob-property grob 'meta))))
> > (set! (ly:grob-property grob 'output-attributes) '((class
> > . name)))))
>
> '((class . name)) is literally a list containing a
> list of the symbols 'class and 'name, which is not
> very useful ;-) You rather want quasiquoting:
> `((class . ,name)).
>
> >
> > This successfully (I believe) extracts the correct name, and assigns
> > it to the output-attributes field. As per the instructions in the
> > lilypond documentation, I then attempted to use \applyOutput Score
> > #add-class to apply this function to all graphical objects, but it
> > didn't supply all of the required objects. My attempted code is below:
> >
> > \applyOutput Score #add-class
> > \score {
> > \new RhythmicStaff {
> > c'2 c'16 c' c' c' \tuplet 5/4 { c'16 c' c' c' c' }
> > }
> > }
> >
> > If I add a print call to the add-class function, I can see that it was
> > called for the objects with the following names from which crucial
> > objects such as NoteHead are missing:
> >
> > NonMusicalPaperColumn
> > PaperColumn
> > Clef
> > TimeSignature
> > LedgerLineSpanner
> > StaffSymbol
> > VerticalAxisGroup
> > SystemStartBar
> > SpacingSpanner
> > VerticalAlignment
> > StaffSpacing
> > BreakAlignment
> > LeftEdge
> > BreakAlignGroup
> > BreakAlignGroup
> > BreakAlignGroup
>
> I'm not sure how you got this output. The way
> the code is written, the \applyOutput is separate
> from the main \score, so it is a score of its own
> containing no actual music. If you move it to
> the beginning of the music, you should get at
> least one NoteHead, as illustrated here:
>
> \version "2.22.0"
>
> {
>   \applyOutput Score
>     #(lambda (grob origin context)
>        (ly:message "~s" grob)
>        (set! (ly:grob-property grob 'color)
>              red))
>   <<
>     { c d e f }
>     \\
>     { g a b c' }
>   >>
> }
>
> This also shows the reason why \applyOutput
> isn't working as you are expecting. \applyOutput
> applies to one single time step. Think of it
> as a \once \override. I don't think there
> currently exists an equivalent of \applyOutput
> for the whole score (perhaps because there were
> not many use cases before output-attributes).
>
> However, this problem can be solved by writing
> an engraver (those are the powerful tools that
> \applyOutput uses under the hood).
>
> \version "2.22.0"
>
> \layout {
>   \context {
>     \Score
>     \consists
>       #(lambda (context)
>          (make-engraver
>            (acknowledgers
>              ((grob-interface engraver grob source-engraver)
>                 (set! (ly:grob-property grob 'output-attributes)
>                       `((class . ,(grob::name grob))))))))
>   }
> }
>
> <<
>   { c d e f }
>   \\
>   { g a b c' }
> >>
>
>
> Out of curiosity: what tool is this for?
>
> Best,
> Jean



reply via email to

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