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: Jean Abou Samra
Subject: Re: SVG export - how might you add classes for all graphical objects?
Date: Tue, 29 Jun 2021 18:43:35 +0200 (CEST)

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]