MarkBind/markbind

"markdown-it-attrs limitation: New line attributes not correctly assigned to list items"

Opened this issue ยท 7 comments

SPWwj commented

Please confirm that you have searched existing issues in the repo

Yes, I have searched the existing issues

Any related issues?

#2272

Tell us about your environment

Window 10

MarkBind version

v4.1.0

Describe the bug and the steps to reproduce it

Consider the following code:

* item 1
* item 2 
  * item 2.1
  * item 2.2
  
  {icons="light-bulb"}
* item 3

{icons="thumbs-up"}

Here is the rendered output:

248452486-8deb39ba-782b-42a4-9b6b-9eec5a4d441b

Observe that despite both the nested list and the outer list being declared identically, they render differently in HTML.

Innermost list items are output as standalone <li> elements, whereas the outer list items are wrapped within <li><p>{item}</p></li>. This inconsistency suggests a potential bug in our current processing pipeline, meriting further investigation and potentially the filing of a new issue.

However, all parameters are preserved, enabling DOM manipulation to achieve the desired output. Consequently, we should refine our processing pipeline to standardize and bring consistency to the output, thereby enhancing the predictability and reliability of our rendering process.

Expected behavior

Both outer layer and inter layer should be render the same way:
Code:

* item 1 Without P Fix this
  * item 1.1 With P

  * item 1.2 With P
* item 2 Without P Fix this
  * item 2.1 With P
    * item 2.1 Without P
    * item 2.2 Without P

  * item 2.2 With P
* item 3 Without P Fix this
  * item 3.1 Without P Fix this
    * item 3.1.1 Without P
    * item 3.1.2 Without P
  * item 3.2 Without P Fix this

  {icons="light-3"}
* item 4 Without P Fix this
  * item 4.1 With P 
    * item 4.1.1 Without P
    * item 4.1.2 Without P
    
  * item 4.2 With P 

  {icons="light-4"}

{icons="thumbs-up"}

Output:
image

Anything else?

Please refer to the official markdown-it-attrs documentation on GitHub for an explanation of ambiguous syntax: markdown-it-attrs Ambiguity Syntax.

The recommended way of declaring block variables is not consistent and intuitive. Therefore, a standardization and improvement is required. It might look something like this:

* item 1 With P Fix this
  * item 1.1 With P

  * item 1.2 With P
* item 2 With P Fix this
  * item 2.1 With P
    * item 2.1 Without P
    * item 2.2 Without P

  * item 2.2 With P
  
  {icons="light-2"}
* item 3 With P Fix this
  * item 3.1 Without P Fix this
    * item 3.1.1 Without P
    * item 3.1.2 Without P
  * item 3.2 Without P Fix this

  {icons="light-3"}
* item 4 With P Fix this
  * item 4.1 With P Fix this
    * item 4.1.1 Without P
    * item 4.1.2 Without P
    
  * item 4.2 With P Fix this

  {icons="light-4"}

{icons="thumbs-up"}

@SPWwj From what I remember, this problematic behavior is not related to attributes. It happens even when there aren't attributes, but there are blank lines inside a list.

The extra lines was mentioned in this comment

SPWwj commented

@SPWwj From what I remember, this problematic behavior is not related to attributes. It happens even when there aren't attributes, but there are blank lines inside a list.

Yes it is the new line, introduced by attrs, is causing unexpected formatting in nested lists. The empty attribute {} is removed during tokenization, leaving an extra line in the list, which results in the creation of an outer <p> tag.

For instance:

* item 1
* item 2 
  * item 2.1
  * item 2.2
  
  {icons="light-bulb"}
* item 3

{icons="thumbs-up"}

becomes:

* item 1
* item 2 
  * item 2.1
  * item 2.2
  
* item 3

This formatting difference can be attributed to the interpretation of

tags in Markdown, which are defined with a blank line in between, as shown below:

* item 1

* item 2
SPWwj commented

The extra lines was mentioned in this comment

Thanks for sharing this information. However, I believe it would be beneficial to address this issue. Given that markdown-it-attrs is an additional plugin layered on top of markdown-it, and it's not entirely designed to align with the markdown syntax, there could be room for improvements to ensure better compatibility.

@damithc @SPWwj disregarding the attributes, the extra <p> tags is a feature of the spec https://spec.commonmark.org/0.30/. A quick way (most of the time) you could use to figure if something is a "feature" of the spec is to just put it in the Github renderer ๐Ÿ™‚

A list is loose if any of its constituent list items are separated by blank lines, or if any of its constituent list items directly contain two block-level elements with a blank line between them. Otherwise a list is tight. (The difference in HTML output is that paragraphs in a loose list are wrapped in <p> tags, while paragraphs in a tight list are not.)

I agree with finding a way to specify attributes for nested lists easily however, without breaking any of the original spec. I have not looked at the PR but do not think this will be easy, the markdown-it-attrs author mentions it here in the README: https://github.com/arve0/markdown-it-attrs#ambiguity which seems like a limitation of the syntax and markdown-it.

E.g.

- a
  - a
  - a
    - a
    - a
  
  {.applies-to-first-nested-list}
- a

We cannot say for sure if the author meant to put a tight (forced by markdown-it-attrs) or loose (where and when the author already wanted one) list.

I do not think MarkBind is best place to address this as well (discussing it upstream would be better).

SPWwj commented

@damithc @SPWwj disregarding the attributes, the extra <p> tags is a feature of the spec https://spec.commonmark.org/0.30/. A quick way (most of the time) you could use to figure if something is a "feature" of the spec is to just put it in the Github renderer ๐Ÿ™‚

As illustrated in the preceding example, the additional line is a requirement dictated by Markdown syntax that we must adhere to.

* item 1

* item 2

Let understand why this code produce the extra P tag

* item 4 Without P Fix this
  * item 4.1 With P 
    * item 4.1.1 Without P
    * item 4.1.2 Without P
    
  * item 4.2 With P 

  {icons="light-4"}

{icons="thumbs-up"}
  • item 4 Without P Fix this (Use developer tool to inspect this line)
    • item 4.1 With P

      • item 4.1.1 Without P
      • item 4.1.2 Without P
    • item 4.2 With P

Note that item 4 is without 4 p tag, the spacing is due tool 4.1 p tag, which is slightly different from our markbind css as we do not have margin-top: 16px;

From above example we can clear see that our markbind syntax is not adhere to the spec https://spec.commonmark.org/0.30/.

But why?

This occurs because, when using markdown-it-attrs, our markdown code undergoes multiple renderings, eventually leading our list to end at {icons="thumbs-up"}. However, markdown-it-attrs removes the attributes in this line, leaving it empty. The same process applies to {icons="light-4"}. Consequently, the final render by markdown-it appears as follows:

* item 4 Without P Fix this (Use developer tool to inspect this line)
  * item 4.1 With P 
    * item 4.1.1 Without P
    * item 4.1.2 Without P
    
  * item 4.2 With P 
 
Just a placeholder to show empty line 1

Just a placeholder to show empty line 2

Please note that this is not in text form, but has already been transformed into tokens. According to the specification found at https://spec.commonmark.org/0.30/, item 4 will contain a 'p' tag because of Just a placeholder to show empty line 1.

I do not think MarkBind is best place to address this as well (discussing it upstream would be better).

In my opinion, this is a design issue, and interpretations may vary. A resolution does not necessarily require any modifications to the markdown-it-attrs code. For additional perspectives, please refer to the discussions in PR #2314.

SPWwj commented

@damithc @SPWwj disregarding the attributes, the extra <p> tags is a feature of the spec https://spec.commonmark.org/0.30/. A quick way (most of the time) you could use to figure if something is a "feature" of the spec is to just put it in the Github renderer ๐Ÿ™‚

This tool might be useful for visualizing both the HTML code and its rendered output: Spirify-Ui Markdown Editor