Consistent attribute syntax

Isn’t readability by humans one of the Markdown’s best advantages? If you need to specify many attributes readability will suffer anyway IMO, so why not use a HTML?

P.S. Id and class attributes would be nice to have, though. It’s a common case when you need to have some links within a documentation, that point to some blocks within the same page.

Again, if you don’t need it, then readability doesn’t suffer here with this addition. This allows for very easy and flexible edits to already existing documents if you want to add some attributes, as opposed to changing it to html itself.

It’s a logical extension since many already use it in pandoc markdown’s fenced code attributes extension, and having it for other elements such as headers, images and tables makes sense too since it is often the case you may want/need it. For example, aligning a particular image differently to the rest. Whereas without it, you’d have to resort to html syntax to do what should really be simple and put into the spec. Makes the document look quite inconsistent too.

I have no problem with wrapping div block elements for this, but the suggested syntax is much nicer.

1 Like

There’s no need to explicitly add the height and width of an image in Markdown. Use a server side script to get the dimensions from the image file and add these to the HTML after it has been converted from Markdown. This will make the Markdown much simpler to read and easier to write.

As for classes and IDs, how about some specific real world use case examples? I provided a solution for image alignments in 266 that does not extend the Markdown syntax. I would be very hesitant to add IDs to Markdown as you’re moving into presentation territory, the realm of CSS. There’s often a better way implementing advanced features that does not clutter up the content with metadeta.

1 Like

I disagree, adding IDs/classes/attributes is something that’s normally done in the html itself, css only controls the presentation if needed.

Your example in 266 doesn’t need an extended syntax because you’re simply selecting images based on a pattern (odd/even), not an arbitrary selection based on the image itself which is only possible with the addition of an id or class.

There are lots of extras in HTML that make sense from a web developer perspective, but create confusion if you’re not a developer. If these attributes only exist so that the presentation can be changed for specific elements then you’re extending Markdown solely for presentation reasons. Why is it the role of the content writer to specify this?

The image syntax is complex enough for non-developers without adding classes too. We already have a unique identifier for images - the file name. Perhaps this could be used to save the content writer from making up an additional ID? You could do the same for headings too if each heading is unique.

1 Like

The point is that IDs/classes/attributes are part of the content, not presentation. Since they should be describing the content semantically rather than just providing stylistic information.

You shouldn’t do things like add class left or right like you do in your example from 266, but add a class that describes more specifically what type of image it actually is, content-wise, and then in the css refer to that class when doing align: left/right.

The curly braces section should be optional, therefore, if users don’t need it, it doesn’t complicate the syntax for them.

The case for having the content writer specify the id/class would be because the elements themselves are inherently (content-wise, semantically) different than the rest of the elements which of are of the same type. The content writer needs to somehow be able to specify this so that the presentation of it can be changed/controlled if desired.

The filename as an unique identifier for images doesn’t work because you can’t select that with css. Even if you could, your css would have to include image file names, which is inflexible since a filename might change. Classes can be applied to multiple images and don’t have to change with a filename change.

It does work for headings (generating IDs from the heading text itself) since headings (of the same type) are all usually styled the same way. The reason for unique identifiers for headings is usually due to anchoring.


Original post says to change syntax from:

```ruby
def foo(x)
  return 3
end
```

to:

``` {.ruby}
mycode;
```

but that obviously has backward compatiblity issues since many already use the former syntax. I think what mb21 proposes can still be achieved though:

  • For code blocks, keep the ability to have the former syntax.

    • If ID’s or other attributes are needed, you’ll need to surround them in curly braces after the language class/declaration.
    • This may be a needed differentiation for code blocks since, if 136 is accepted, the initial language declaration (ruby in this case) would be changed to language-ruby, instead of just a ruby class if .ruby was in curly braces.
      • And if you don’t want this change from ruby to language-ruby for whatever reason (if you don’t want a language declaration at all), you can just omit it, but you’ll have to use curly braces to add IDs/classes/attributes to differentiate between that.
  • But for headings or other elements, where the attributes would need to be added on the same line as the heading/content itself, curly braces should be required for adding attributes so that it doesn’t conflict with normal heading/content text.


Edit: 136 has been accepted, so the old syntax definitely needs to stay otherwise there would be conflicts.

2 Likes

I think we need to get away from thinking about Markdown directly correlating to HTML and CSS. While Markdown ultimately compiles to HTML, it doesn’t need to do so directly.

With this particular example, you could add IDs to the images after the Markdown is converted to HTML. The IDs could be generated from the filename. This is inflexible as the filename might change, but the ID might change too. I’m sure you could come up with a script to keep them in sync if it was going to be a problem.

I can see this being hard to implement without classes. You could resolve it by having a separate system in your CMS where you drag and drop images into groups that are linked to CSS classes. But I understand the general point you’re making: the current Markdown syntax on it’s own is not sufficient for some advanced scenarios.

This is advanced, layout specific stuff. I don’t think it should be the core spec, but an extension. There are other ways you might implement particular image properties. Properties could be defined for each image in the CMS. Or lots of small Markdown text boxes and images could be rearranged with drag and drop. Etc.

With the Ruby fenced code block example, the former syntax currently used by GitHub and Discourse is clearly more readable. And as a writer, I’m not thinking about whether it translates into a class behind the scenes. I’m thinking about writing a code block in the Ruby programming language. I want the syntax to be as simple and lightweight as possible. The fact that it compiles into a class is an implementation detail that I only care about if I understand HTML. (Edit: I see “keep the ability to have the former syntax” is a consideration - good).

1 Like

That last part about the ruby class staff was more directed at the original poster’s recommendations, not you, sorry! The hr line isn’t very visible. The whole point of that part was due to retaining the former syntax too. :slight_smile:

And yeah, I guess having some way to add IDs/classes/attributes to some types of elements is just really useful. There are probably other ways but it makes the most sense for the content writer to specify the info if they desire. It’s also much easier than separately maintaining the classifications, as with your cms drag drop interface example.

And if the writer doesn’t want/need to, when it’s not semantically relevant, then they need not worry about it or be affected by it! I wouldn’t say it’s layout specific though since that implies it’s only related to presentation, which it shouldn’t really be.

Not sure if it’s even that advanced either, as this is already a widely used feature with the headings (for example in markdown extra/pandoc’s markdown), but I guess that’s just my opinion of it.

Well john said that he’d like to focus on just the markdown as a method to produce html for now at least. I’ll try to edit in a link to where he says it when/if I find it (assuming it’s not a false memory).

But I certainly know that other output formats for markdown exist. I literally have hundreds of pdfs produced from markdown documents (nearing one thousand soon). Nevertheless, I understand that the primary, default format is html, the current spec itself always refers to html output, so I see no reason for that to hinder having this proposal in the spec. If another output format doesn’t need such information, then it can be easily removed/ignored.

I’m coming at this from a usability perspective, so while creating a drag and drop UI might be more difficult for the web developer, from the user’s perspective it could be simpler to operate. I believe that regular Markdown for emphasis, links, and images is actually simpler than using a WYSIWYG editor (once you learn the basic syntax). I’m less sure about some of the proposals I’ve seen here which seem more developer-y. So as a CMS developer, I would be hesitant to allow users to specify classes.

[quote=“rwzy, post:17, topic:272”]And if the writer doesn’t want/need to, when it’s not semantically relevant, then they need not worry about it or be affected by it! I wouldn’t say it’s layout specific though since that implies it’s only related to presentation, which it shouldn’t really be.
[/quote]

Another way of thinking about this is asking how portable any new syntax is. If we were to copy/paste the Markdown to a different website with a different layout, would the IDs/classes still be relevant? What uses do the IDs/classes have besides providing a semantic link to layout/presentation features?

No it wouldn’t. It would be much easier to specify it in the text itself than separately handling such information. Your content would be split up in two different places, when it shouldn’t be.

The syntax proposed here is just a pair of curly braces surrounding your attributes.

IDs are also commonly used for anchoring.

The content would already be split in two places, because the image file itself is not part of the text. I’m thinking of a CMS where the images are displayed on the page next to the content (which contains the ![]() tag to reference that image and all of it’s properties). The image properties could be customised alongside that image file. This would also keep the image properties specific to the particular website; if the rest of the Markdown was copied, the properties wouldn’t automatically be copied too. I see that as feature if they are presentational properties.

Anchors in headings could be auto-generated, so we wouldn’t need an explicit syntax. Any other examples?

I think I covered your other points in 266.

The attributes would be split from the text which refers to the image (![image](src)), and rather reside on the cms’ database or whatever. And by the following I get that that’s exactly what’d you prefer:

But my point was always that the attributes are not always just presentational, but also inherent properties of the content. So that they shouldn’t be separated and still be copied over. So that the other system can also present the differences specified by the attributes if they so desire/think it’s meaningful to do so.

If auto-generation of heading anchors is accepted into the spec, then it’s most imperative that there’s a custom method to override them, in case of conflicts between two same IDs. The syntax proposed here makes the most sense as it’s widely used already, so minimal backwards compatibility issues.

  • Indicating rel links.
  • Indicating dir, at least for the code blocks example.

FYI: So far this is the kind of attribute syntax that we are agreeing upon in Generic directives/plugins syntax

Is this what you guys are ultimately talking about in terms of consistency in attribute?

Url Links

 [description](url){#myId .myClass  key=val key2="val 2"}

Embedded Media

!mediaType[description](url){#myId .myClass key=val key2="val 2"}
  • assumed to be image if mediaType left blank

  • syntactic sugar ( content of () handled by mediaType handler/extension):

      ![](file.mp4 "video title" 80x10 )
     is equivalent to typing: 
    
      !video[](file.mp4){title="video title" width=80 height=10}
    

Extension Directives (For extra extensions!):

@name[content](arg){#myId .myClass key=val key2="val 2"}
  • name :~ extention name

or

@@@name[content](arg){#myId .myClass key=val key2="val 2"}
    >>extension code/content to process here<<
@@@

Code:

`<someCodeHere>`{#myId .myClass key=val key2="val 2"}

Shorthand version:

`<someCodeHere>`myClass 

fenced code:

``````{#myId .myClass  key=val key2="val 2"}
     someFunction();
``````

short hand version:

``````myClass 
     someFunction();
``````

Header:

# HeaderTextHere # {#myId .myClass key=val key2="val 2"}

HeaderTextHere 
################## {#myId .myClass key=val key2="val 2"}

HeaderTextHere 
~~~~~~~~~~~~~~~~~~ {#myId .myClass key=val key2="val 2"}

HeaderTextHere 
------------------ {#myId .myClass key=val key2="val 2"}

HeaderTextHere 
================== {#myId .myClass key=val key2="val 2"}

Alt Possibility: wonder if we could include something in [] below… maybe summery?:

### HeaderTextHere ### [Short Summary of content]{#myId .myClass key=val key2="val 2"}

Edit: RWZY suggested a header example

1 Like

As long as the extension directives part is proposed to be an extension and not in the core, I’m okay with it. Except:

  • Have the same syntax proposed for headings too, to be able to specify custom anchors and such. (You didn’t list headings as an example.)

  • 136 got accepted.

This means that the shorthand inline code example:

`code`myClass

turns into:

<code class="language-myClass">code</code>

instead of:

<code class="myClass">code</code>

Same with the code block example. But I don’t think it’s a problem since it follows the html spec to do that. I’m just clarifying that if you want to actually just indicate myClass instead of language-myClass, you will have have to use curly braces as such:

`code`{.myClass}

  • Also, in your fenced code block examples, you use six backticks, but I’m assuming the same numbering rules apply as already outlined in the spec?

yea I’m not really counting back ticks, since that is not the point of the discussion.

I think the syntax for the extension directives should be implemented as core as a way for other extensions to cleanly hook into it. However the core should not include any extensions by default.

Your code block HTML representation proposal makes sense. I’m just defining the commonmark syntax


if you want to actually just indicate myClass instead of language-myClass, you will have have to use curly braces as such:

Oh, and yes this does make sense, since {} can be seen as ‘explicit’ rather than implicit without the curly braces.

  `````ruby

is just syntactic sugar (In human written language: Shorthand notation. E.g. “Don’t” ) for

 `````` {.language-ruby}

(Note: this gets rather long, but I hope that it’s a start towards something useful.)

This is an important feature to have, since without it there’s absolutely no way to style individual documents differently. If I want a particular element to act a certain way, I have to change it entirely into HTML instead of just adding a small {attributes} declaration to my existing Markdown. Human-readability is key here, and we all agree that raw HTML within a Markdown document is just plain ugly.

An argument exists that it looks too “developer-ey” (most likely stemming from the fact that it uses curly braces and can be used for CSS), but that’s ignoring one fact: users that don’t need the feature aren’t going to stumble across it accidentally. Nobody’s just going to randomly type # h1 {id="header"} without first needing that syntax and looking it up, and therefore they won’t be bothered by it. Even if they read a document using that syntax, it’s fairly obvious that whatever gets typed within the curly braces doesn’t get visibly rendered to the document (if they even bother to check).

I agree that we need to keep the language specifier for code blocks, and I especially support the notion that we look at it as “syntactic sugar” for the more verbose curly brace format.

A suggested start for the spec:

  1. Curly braces define attributes on an element:
    {class="hello" id="greeting"}

  2. Classes can be written shorthand by prefixing a word with a dot:
    {.shorthand-class .another-class}

  3. IDs can be written shorthand by prefixing a word with a pound sign:
    {#shorthand-id}

  4. Shorthand and longhand forms cannot exist for the same attribute at the same time:
    {class="not-allowed" .nope}

  5. On a fenced code block, the first word after the opening fence will be considered shorthand for the following (where x is the first word):
    {class="language-x"} or its equivalent: {.language-x}

  6. ID uniqueness will not be enforced by the Markdown parser (too problematic; should discuss)

  7. An attribute declaration must directly follow the declaration of another element type (inline or block) without any intermediate spaces. Attribute declarations can be placed on any element in a Markdown document. Any attribute declaration not at the end of an inline or block element will be treated as if it had no special meaning (plaintext).

As for point #7, here are some examples of how I think it would work:

This is a paragraph {.some-class}

[This is a link](url){.some-class}

# This is a header {.some-class}

`This is a code block`{.some-class}

This is a larger paragraph `with a code block`{.code-block-class} and more text **here**{.stong-text-class} and more here as well. {.paragraph-class}

It gets a little ugly **like this**{.strong-text-class}. {.paragraph-class}
5 Likes

Agreed on most points of ConnorKrammer’s post above with exceptions of:

(4.) If I recall. Markdown philosophy is that all input is valid input. (But I do support having warning outputs). So for:

{class="not-allowed" .nope}

Just accept it, but make class="not-allowed" have higher precedence than .nope .


(6.) I agree on not worrying about ID uniqueness. That is the responsibility of the author. As long as we are not auto generating ‘anchors’ from header names, writers won’t likely accidentally make non unique name (and if they do, it’s their own fault).


(7.) Bit worried about potential problems with putting {} after a paragraph. As for the later examples looking quite ugly with too many {}, it doesn’t matter since in most cases people will not need to use it. But when they do need it, it will be a lifesaver. (Take for instance: customizing a link to look like a CSS based button).


The biggest reason to adopt this into core. Is that {} is optional, and will often get out of the way, but will save your sanity when you need it.

1 Like

That’s a good idea for #4 – it fits the Markdown philosophy better. Another idea would be to apply both classes, so that it would have .not-allowed and .nope.

And I do agree that there are potential problems with putting {} after a paragraph, but I like the idea enough that I would be willing to put up with that.

I’d really like to get one of the maintainers to look at this. I think we’re off to a good start, but they’re the ones most likely to think up any serious objections. After that we can iterate.

1 Like

Yes, I mostly agree as well. Although as @mofosyne says 4. should be reformulated to either say that:

  1. the first of several attributes with the same name takes precedence: affects also {dir=rtl dir=auto}, or
  2. it’s the author’s responsibility (similar to 6.), which I actually prefer to make implementations easier.

I’d probably rather white-list elements that may contain attributes than saying “all of them can”. What about block quotes, lists, list items, hard line breaks or even inline HTML?

We may also want to restrict the {} to its own line at the end of a (nonempty) paragraph (RTL use case) or block quote to enhance readability and make clashes even more unlikely:

This is a paragraph with a lot of text. That's why it's somewhat hard to make out there is an attribute attached to it unless it's on another line.
{.some-class}

> This is a block quote.
> {.some-class}

To attach attributes to the entire list I guess this could work:

- item one
- item two
{.some-class}

But adding attributes to individual list items seems very tricky. How do you know whether the target is the last list item or the entire list? (Or even the last paragraph of the last list item?) It might be possible to distinguish these using indentation, but unless someone comes up with a good use case, I think we should not support attributes on list items to avoid confusion. Of course, you could argue that if the {} doesn’t have to be on its own line (like I just proposed) it would be somewhat easier to attach it to list items, but I’m not sure it’s worth the trouble.

1 Like

One solution could be to treat newline + {.some-class} as 'entire block operators, and {.some-class} at the end of a line as individual item operators (with the exception of text only paragraphs.

Ergo:

Normal list with indivudal item styling and block styling:

- item one {.some-class}
- item two {.some-class}
{.some-class}

This is a paragraph with an ignored class.

This is a paragraph with a lot of text. That's why it's somewhat hard to make out there is an attribute. {.this-class-is-ignored-and-left-as-it-is-in-text}
{.some-class}

Is that it? Any objection, or refinement? Should this feature request be place in https://github.com/jgm/stmd/issues now?