Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add <style> to spec and make various elements styleable #282

Merged
merged 5 commits into from
May 10, 2022

Conversation

adrianholovaty
Copy link
Contributor

Here's a pull request that brings the ideas from #263 into the spec.

The updated docs (as of this pull request) are visible here: https://cdn.githubraw.com/w3c/mnx/issue-263/docs/

See the two new example documents for a very quick overview to get intuition of the general idea:

The specific changes in this pull request are:

  • Added a <style> element, which must have either a "class" or "element" attribute.
  • Documented that <style> can be a child element of <global>, <page>, <score>, <system-layout>, and <system-layout-change>.
  • Added the concept of "styleable" elements, though this currently only exists in the docs' backend system. The styleable elements are: clef, cresc, dim, dynamics, ending, event, expression, fine, grace, instruction, jump, key, measure, note, octave, part, rest, segno, sequence, slur, tuplet, wedge. These are elements that may have a "style" attribute (or "color").
  • Added a single style property, "color", which can be assigned directly to any styleable element. We are deliberately putting off the specification of additional style properties, because this work is intended to be about the general style infrastructure.

I have a few remaining TODOs before this can be merged, but I wanted to start getting feedback on this sooner rather than later. The remaining TODOs are:

  • Create a docs page describing the style system in general (borrowing liberally from Joe's overview in issue Support style properties with a uniform mechanism #263). This will include a list of all styleable elements and will define terms such as "style property" and "style class." It will also specify the cascade of which elements are affected by a given style.
  • Add a few more examples, showing styles attached to layouts (the current two examples simply put styles in <global>).

I made a few changes from the discussion in #263:

  • Instead of <style-class>, the element is simply called <style>.
  • In <style>, the style class name attribute is called "name" instead of "class".
  • Instead of a "class" element scattered throughout markup, I opted to use "style". I believe this more clearly communicates the intent of this data, though the downside is that it might be confusing for people coming from an HTML/CSS background (who would perhaps expect "class"). I'd like to get some feedback on this decision especially.

The only style property we support at the moment is 'color'.
The goal here is simply to establish the infrastructure for
styles.
@janrosseel
Copy link

Would it be possible to apply a style element from/to a measure location in a certain part rather than for the whole part? This would easily allow to indicate ranges of cue/a default notes.

@jefftrevino
Copy link

jefftrevino commented Mar 29, 2022

I share your ambivalence about the choice of "style" and prefer "class" instead, to align with HTML/CSS convention.

Would it be possible to apply a style element from/to a measure location in a certain part rather than for the whole part? This would easily allow to indicate ranges of cue/a default notes.

It looks like detailed conversation about issues like this has happened here previously? See the difference between "properties inherited from a global measure" and "properties inherited from an ancestor" in Joe's examples.

@janrosseel
Copy link

I share your ambivalence about the choice of "style" and prefer "class" instead, to align with HTML/CSS convention.

Would it be possible to apply a style element from/to a measure location in a certain part rather than for the whole part? This would easily allow to indicate ranges of cue/a default notes.

It looks like detailed conversation about issues like this has happened here previously? See the difference between "properties inherited from a global measure" and "properties inherited from an ancestor" in Joe's examples.

Not as I read it. In everything I read, styles are applied to elements. A range of cue notes has a starting/end point. It would be weird (for me) to have to individually markup all notes or measures to achieve the effect.

The element is probably what I'm looking for though. Looks like this might be used to indicate start/stop of cue notes.

@JDLH
Copy link

JDLH commented Mar 29, 2022

The contribution I think I can make is with a use case. I write notation via editors, and don't directly edit enough notation syntax to have useful opinions on the proposal's specifics.

Use case: voice-specific vocal scores. Imagine a vocal score for a SATB choir with piano accompaniment. There is one staff for each of the four choir sections, and each of these staffs has lyrics. Someones the sections are singing different words at the same time, so their lyrics do not always line up. There is a full two-staff piano part. Singers and accompanist and conductor are rehearsing from this score, using tablet computers. Composer and accompanist set styles so that the score has the typical vocal score layout of 4+2 staffs. Each choir singer can choose styles to give this layout, and/or to highlight their part (their staff, their lyrics) with a bright yellow background, and/or to collapse the other three parts into one multi-voice staff, for a layout of 1 vocal staff (the singer's), 1 other-3-voice vocal staff, and 2 piano staffs.

Does this styling proposal enable this use case? Should this use case be achievable by styling alone, or does it require changes to content?

@clnoel
Copy link

clnoel commented Mar 29, 2022

The contribution I think I can make is with a use case. I write notation via editors, and don't directly edit enough notation syntax to have useful opinions on the proposal's specifics.

Use case: voice-specific vocal scores. Imagine a vocal score for a SATB choir with piano accompaniment. There is one staff for each of the four choir sections, and each of these staffs has lyrics. Someones the sections are singing different words at the same time, so their lyrics do not always line up. There is a full two-staff piano part. Singers and accompanist and conductor are rehearsing from this score, using tablet computers. Composer and accompanist set styles so that the score has the typical vocal score layout of 4+2 staffs. Each choir singer can choose styles to give this layout, and/or to highlight their part (their staff, their lyrics) with a bright yellow background, and/or to collapse the other three parts into one multi-voice staff, for a layout of 1 vocal staff (the singer's), 1 other-3-voice vocal staff, and 2 piano staffs.

Does this styling proposal enable this use case? Should this use case be achievable by styling alone, or does it require changes to content?

The layout changes (that is, grouping the other three parts onto one staff) would need to be enabled via extra layout definitions. However, I think that the highlighting could be enabled by giving the lyrics and/or notes for each part a class. Then, the consuming program can apply changes to all elements with that class.

The thing is, I don't think that that is what this is designed to do, and having a consuming program relying on those classes being in place seems risky. If I'm understanding it correctly, this proposal is designed to make it possible to define, for example, the style for a "cue" class, and add it to all the appropriate notes/events/sequences. This would be done by the creating program, which would define the exact size change percentage, (or special notehead type, or a color, whatever). Then a consuming program can read that style once and apply it to all the notes with that class when doing a display. Unless I'm sorely mistaken, it's a way to represent the style of the elements in the originating document, not modify them on the fly.

Which doesn't mean that they can't eventually be used that way. I just don't think it was part of the original proposal.

--Christina

@bhamblok
Copy link

bhamblok commented Mar 31, 2022

Me, coming from an HTML/CSS background, I think it would be less confusing if we would name things as follows:

The <style> element
Parent elements: [<global>](https://cdn.githubraw.com/w3c/mnx/issue-263/docs/mnx-reference/elements/global/), [<page>](https://cdn.githubraw.com/w3c/mnx/issue-263/docs/mnx-reference/elements/page/), [<score>](https://cdn.githubraw.com/w3c/mnx/issue-263/docs/mnx-reference/elements/score/), [<system-layout>](https://cdn.githubraw.com/w3c/mnx/issue-263/docs/mnx-reference/elements/system-layout/), [<system-layout-change>](https://cdn.githubraw.com/w3c/mnx/issue-263/docs/mnx-reference/elements/system-layout-change/)

The <style> element is a way to define visual styling within an MNX document. There are two types of <style> elements:

* <style name="..."> defines a style class-name that can be referenced from another MNX element.
* <style element="..."> targets all elements of a given name.

This example defines a style class "emphasized", which means to use the color red:

<style name="emphasized" color="#ff0000">

A <note> element can then use the "class" attribute to use this style:

<note class="emphasized" ...>

This example says "all <note> elements must be blue":

<style element="note" color="#0000ff">

Note that I used the "name"-attribute on an <style>-element, instead of "class", so we could use the "class"-attribute on elements who want to use that style having that name... This comes closer to HTML/CSS

@samuelbradshaw
Copy link

samuelbradshaw commented Mar 31, 2022

I'm also coming from an HTML/CSS background, and I agree with @bhamblok; however (also because of my HTML/CSS background) I think the name="" attribute is confusing as well – in HTML, name is always the name of the current element.

That brings me to a question – do we need two types of <style> elements? What if we just have a selector attribute that could take either an element name or a class name, and could be expanded to take more complicated queries in the future?

The contents of the selector attribute would follow XPath or CSS conventions – or maybe we allow both.

For example, XPath:

<style selector="//note" color="#0000ff"> <!-- All <note> elements must be blue -->
<style selector="//*[contains(@class, 'emphasized')]" color="#ff0000"> <!-- All elements in the class "emphasized" must be red -->
<style selector="//*[@id='asdf']" color="#00ff00"> <!-- Element with the ID "asdf" must be green -->

Or CSS:

<style selector="note" color="#0000ff"> <!-- All <note> elements must be blue -->
<style selector=".emphasized" color="#ff0000"> <!-- All elements in the class "emphasized" must be red -->
<style selector="#asdf" color="#00ff00"> <!-- Element with the ID "asdf" must be green -->

I expect that we would support only basic XPath or CSS syntax from the beginning (just an element name, class name, or ID), but it would leave us open to much more flexibility down the road.

@adrianholovaty
Copy link
Contributor Author

That brings me to a question – do we need two types of <style> elements? What if we just have a selector attribute that could take either an element name or a class name, and could be expanded to take more complicated queries in the future?

@samuelbradshaw That's a compelling proposal...! I like the fact that it'd be a single, consistent attribute as opposed to the current pull request's two different attributes. Plus the future flexibility for more advanced selectors would be a nice benefit.

As for XPath vs. CSS syntax, my anecdotal experience/feelings are:

  • XPath is more likely to have functionality built into existing XML-parsing libraries. In other words, it will be highly likely that somebody parsing an MNX document would have access to XPath parsing routines, simply due to the fact that they're already using an XML-parsing library. CSS parsers are sort of a different animal.
  • However, CSS is much more elegant for the common case of elements, classes and IDs. selector="//*[contains(@class, 'emphasized')]"> is really verbose and error-prone for such a common case.

So I'd vote for CSS syntax, initially limited to element names, classes and IDs. What do other people think? It's a bit of a big change to the proposal, but it's not too late to make it, in my opinion.

Executive summary of this proposed change

Currently, the pull request defines two different ways to target a style:

  • <style element="note" color="#0000ff"> colors all <note> elements.
  • <style class="emphasized" color="#0000ff"> colors all elements with the class emphasized.

Instead, the proposed change is to unify the element and class attributes into a single selector attribute, such that...

  • <style selector="note" color="#0000ff"> colors all <note> elements.
  • <style selector=".emphasized" color="#0000ff"> colors all elements with the class emphasized. Note the dot before "emphasized" — that means "this is a class" in CSS syntax.

@samuelbradshaw
Copy link

samuelbradshaw commented Apr 12, 2022

I like CSS syntax a lot because of my bias towards web development – but it would be good to get opinions from others, especially anyone who works in a non-web context.

@clnoel
Copy link

clnoel commented Apr 21, 2022

I primarily work in a non-web context, and this makes sense to me. Especially if we can (maybe not as MVP) specify selector="note.emphasized" to combine the two selector types. It feels better than having two mutually exclusive attributes or two different elements that serve essentially the same purpose.

@jsawruk
Copy link

jsawruk commented May 10, 2022

I realize that the following comments might not be within scope for this PR (which I think is an amazing start!), but the confusion in this thread about a class attribute vs. a selector attribute for the <style> element may be due to neither of these attributes appearing in the HTML <style> element. Instead, I suggest aligning to HTML/CSS and defining styles using selector syntax inside of the <style> element rather than as attributes.

This approach has two primary tradeoffs:

  • There is only a need for one kind of <style> element. This could also reduce the number of <style> tags that appear in a document
  • The styles would need to be parsed using a CSS parser. I realize that this might be a high technical cost, but open source CSS parsers already exist that could be used/adapted (this is but one example)

For example, @samuelbradshaw's previous example

<style selector="note" color="#0000ff"> <!-- All <note> elements must be blue -->
<style selector=".emphasized" color="#ff0000"> <!-- All elements in the class "emphasized" must be red -->
<style selector="#asdf" color="#00ff00"> <!-- Element with the ID "asdf" must be green -->

could be written as this instead:

<style>
note { color: #00ffff; }
.emphasized { color: #ff0000; }
#asdf { color: #00ff00; }
</style>

Again, this may be a longer-term solution; don't want to derail the great work and discussion already in this PR.

@adrianholovaty
Copy link
Contributor Author

@jsawruk This approach makes a lot of sense at first glance, but we decided against it a while ago — primarily because introducing full CSS syntax would significantly increase the burden for a developer to parse an MNX document. I wouldn't necessarily rule it out for the long term, but for now I see it as not being worth the added complexity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants