[Top][All Lists]

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

Re: \class grob property

From: Urs Liska
Subject: Re: \class grob property
Date: Mon, 14 May 2018 11:55:14 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.7.0

Hi Harm,

Am 14.05.2018 um 10:36 schrieb Thomas Morley:
2018-05-14 8:50 GMT+02:00 Urs Liska <address@hidden>:

Am 14.05.2018 um 00:02 schrieb David Kastrup:
Urs Liska <address@hidden> writes:

Hi all,

I'm thinking about having a new grob property \class, but before
digging deeper I'd like to put the idea up for discussion.

This would have two different goals:

1) for SVG output the objects would get the class assigned (along with
an id). I don't have any idea yet how that is implemented,
though. This will make it possible to work with CSS in a display

2) (Formatting) functions can check for a grob's class to perform
e.g. highlighting operations (=> color all NoteHeads with class
"temporary" red)

In addition I would like to use that to export class information to

Any comments or objections?
The various semantics seem to be tied more to the word "class" than a
common concept underlying the proposed uses of this property.  Maybe
explain some more what the generic concept of class should be and why
the proposed backend semantics are in every case the proper match to the

The idea is to give various grobs a secondary name, making same-named grobs
belong to a group of objects where the grouping is independent from
groupings like grob type or voice/staff/measure/etc. context. To express
what I mean other words would be appropriate as well, such as e.g. "type",
but I would suggest to use the same word (and concept) as is used in CSS.

In scholarly editions you may have score items you want to mark up as
"addition", "emendation", "deletion". It's already possible to define music
functions that produce the highlighting you want to apply to these types of
grobs, for example dash slurs added by the editor. With that you also have a
way to centrally control the appearance, for example to also use colors
while working on the edition and suppress that for the final publication.
However, the resulting grob will not "know" it is an addition but only that
it is dashed and green, for example.

My suggestion is to have the possibility (which of course doesn't discourage
the use of music functions as would be done currently) to instead set a
grob's 'class' property to semantically mark up that grob instead of
(directly) changing its appearance, deferring the styling to a later stage.
In LilyPond this can for example be an engraver that tests grobs for their
class property and acts upon that.
If the class property is exported to SVG then the appearance of objects can
be controlled interactively with CSS. The same should be possible when
exporting to MusicXML.

Probably an engraver should be made available as well (but not consisted to
any context by default), along with a means of defining "styles" (maybe an
alist of property/value pairs) that will be applied to grobs with the given
class. A style should be somewhat hierarchical, at least to allow generic
property/value pairs and additional ones for specific grob types (for
example note heads should probably not be dashed ...). I haven't thought
about the idea of actually make styles cascading like in CSS, and I'm not
sure there's an appropriate concept of nestedness that would make that a
natural thing to pursue.

I think it would be nice to provide a command [\once] \class <grob-type>
<class-name> which should also be usable as a \tweak on individual grobs.
Very practical would also be to have a context property as well, so
     \set Voice.class = "unclear"
would attach the class to every grob within its scope.

Like with CSS multiple classes should be possible with
     \class Beam "unclear addition"

My examples so far all come from scholarly editing but I think this could
open up a wide array of use cases. Think about classes like the following:
     \class LyricText "excited"
     \set Voice.class = "muted"
     \class Hairpin "grey1 dashed with-text"
     \class RehearsalMark "rehearsal-mark"
     \class RehearsalMark "section-mark"


Hi Urs,

it's still not very clear to me what you want.
This may be due to my limited knowledge of the english language: I
tend to skip detailed explanations.
Not always the right thing, I have to admit...

I'd prefer code.
You certainly know how to define custom context/grob-properties. But
even without doing so, below row implementation is possible. At least
for grobs.

TstEngraver =
#(lambda (context)
       ((grob-interface engraver grob source-engraver)
         (let* ((details (ly:grob-property grob 'details '()))
                (class (assoc-get 'class details)))
           (cond ((symbol-list? class)
                    (if (member 'deleted class)
                        (ly:grob-set-property! grob 'color grey)))
                 ((symbol? class)
                    (case class
                        (ly:grob-set-property! grob 'color red))
                      (else '())))))))))

\layout {
   \context {
     \consists \TstEngraver

   \once \override Slur.details.class = #'addition
   a4( b c' d')
   e' d'
   \once \override Tie.details.class = #'(deleted grey)
   c'~ c'

Is this something you have in mind?

It's only part of what I described, but this is exactly what I was thinking about.

I wasn't aware of the fact that you can simply add unknown properties to the 'details'. With that I might consider implementing the stuff without asking for inclusion in LilyPond itself.

A \class command to apply a class to a grob might then look like

class =
#(define-music-function (grob-type name)(string? symbol-list-or-symbol?)
     \once \override #grob-type #'(details class) = #name

  \class Slur addition
  a4( b c' d')
  e' d'
  \class Tie deleted.grey
  c'~ c'

(of course the \tweak version has to be added)

And instead of defining the class behaviour directly in the engraver I would look them up in some Scheme tree and provide a wrapper command to define classes.

Thank you for now


reply via email to

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