gettalong / kramdown

kramdown is a fast, pure Ruby Markdown superset converter, using a strict syntax definition and supporting several common extensions.
http://kramdown.gettalong.org
Other
1.72k stars 274 forks source link

Fenced codeblocks column (not the list indentation) should determine the stripped whitespace from the code #778

Closed T3sT3ro closed 1 year ago

T3sT3ro commented 1 year ago

The codeblocks that are inside ordered lists get an extra whitespace after rendering, because the codeblock must be aligned with the list label instead of a fenced code block marker. I don't see a scenario under which that would be an intended behavior...

Look at this:

1. <-this is a default indent of a label
<-there is an extra space (NOT on github)
```
  1. <-I have to add extra space to list item text to properly render the code below, violating MD030
    <-there is no extra whitespace

rendering it on a jekyll site results in the following html:

<ol>
  <li>&lt;-this is a default indent of a label
    <pre><code> &lt;-there is an extra space (NOT on github)
</code></pre>
  </li>
  <li>&lt;-This is what I have to do to make codeblocks insidee this list item indent properly
    <pre><code>&lt;-there is no extra whitespace
</code></pre>
  </li>
</ol>

This example renders differently here on github issues and differently in jekyll and github pages. Here (in issues) some magic stripping occurs that I cannot reproduce on a local jekyll. I use Jekyll 4.3.1 and a default implicit GFM kramdown parser with it.There is no available help in the web explaining how to achieve the same effect as github does for their codeblocks. You can see a live version of this problem on my site: https://t3st3ro.github.io/2022/11/02/self-contained-jekyll-with-docker.html. Check out the codeblocks inside lists, select them and notice that each line is prefixed with a space.

There are several problems with how it currently works:

gettalong commented 1 year ago

Tl;dr: Use the syntax provided by your chosen Markdown processor.

There will always be differences between the rendering on Github issues, Jekyll and a page converted with kramdown since they use different Markdown engines. If you write a Markdown document, you don't write "Markdown", you write kramdown, kramdown GFM variant, Github Issue Markdown, Github Flavored Markdown, Gitlab Markdown, Reddit Markdown, ... This means you need to decide on one Markdown engine with which you handle your documents and adhere to its specification of "Markdown".

You are posting this here, so I assume you are using kramdown's markup as per the specification.

The rules for list indentation and content inside lists in kramdown is easy to remember. The indentation is based on the first non-whitespace character after the list item marker. All content of the list item has to be indented that amount of spaces. However, due to the allowed laziness with respect to line wrapping, continuation lines may not be indented. The indentation is removed from the content and then it is parsed like it wasn't indented and all the normal rules apply.

Here is an example:

* indent 2 spaces

code 2 spaces


*  indent 3 spaces

code with 3 spaces


* indent 2 spaces

non-code with 3 spaces


* indent 2 spaces

code with no space, allowed due to laziness, marker with 2 spaces

need to indent here again

And here is the output:

ul>
  <li>
    <p>indent 2 spaces</p>

    <pre><code>code 2 spaces
</code></pre>
  </li>
  <li>
    <p>indent 3 spaces</p>

    <pre><code>code with 3 spaces
</code></pre>
  </li>
  <li>
    <p>indent 2 spaces</p>

    <p>~~~
 non-code with 3 spaces
 ~~~~</p>
  </li>
  <li>
    <p>indent 2 spaces</p>

    <pre><code>code with no space, allowed due to laziness, marker with 2 spaces

need to indent here again
</code></pre>
  </li>
</ul>

Concerning your list of problems:

T3sT3ro commented 1 year ago

By the MD030 I mean the linting rules of the widely used Markdown Lint. I do not use emacs, and I mainly use VSCode to edit my markdown notes and like other editors it assumes a sane default is a constant width indent, independent of file's content. Vim Doesn't provide a default continuation indent out of the box. Some basic search in the web for markdown plugins for vim show me, that the indent is often constant per level of a list(2 or 4 spaces), which makes it tedious to manually fix every code block that is misaligned. Even more so, if the user is not aware that the extra space indentation takes place ­— then he may never even notice the error. This may pose a problem for snippets of whitespace-sensitive languages like YAML. Using the same offset for item elements looks weird when list is under 10 elements long and requires fixing 1-9 if it suddenly becomes 10 items long and 3-wide indent was used previously. It also violates the linting rule, as stated before. Because inserting or removing a list item may require adjustment of other items, this also makes git diffs bigger.

Personally I think that if it's possible, the spec and the parser should be adjusted accordingly to make the fence indentation determine the length of stripped whitespace. It just feels sane for the default behavior.

gettalong commented 1 year ago

Thanks for your explanation though there won't be a change in the parser/spec since this might break backwards-compatibility.

kramdown can't know whether that space is intended or not and therefore a warning message is not really useful for your described case.

I still recommend using a single tool for converting your Markdown documents to avoid any problems.