mdast-util-to-markdown icon indicating copy to clipboard operation
mdast-util-to-markdown copied to clipboard

Figure out a way to support tab-size / aligning columns

Open wooorm opened this issue 3 years ago • 0 comments

Initial checklist

Problem

Other programming languages allow using different “tab stops”, e.g., columns of 2, 3, 4, 8 spaces.

  • Markdown does specify that most things can be optionally indented 1-3 spaces, but as that’s a bit ugly and we’re formatting here, we don’t have to deal with that.
  • Markdown does specify the use of 4 spaces for indented code, which we can’t get around.
  • GitHub in their footnotes also specifies 4 spaces for content in footnotes.
  • In markdown block quotes, 1 space is allowed, which creates a column of 2.
  • In markdown lists, there’s room (see GH-48), so we can make columns of 2, 3, or 4.

Tab stops of 8 don’t work, as everything turns into code:

Paragraph[^fn].

> unindented block quote.

***

>       indented block quotes (💥 turns into code, w/ spaces)

*       indented unordered list (💥 turns into code, w/ spaces)

1.      indented ordered list (💥 turns into code, w/ spaces)
11.     indented ordered list (💥 turns into code)
111.    indented ordered list (fine)

        code 1? (💥 spaces show up)

<section>
        <article>
                HTML.
        </article>
</section>

[^fn]:
        Footnote (💥 turns into code)

Tab stops of 4 work perfectly (although indenting block quotes doesn‘t work):

Paragraph[^fn].

> unindented block quote.

***

>   indented block quotes (⚠️ fine, but becomes complex when adding indented code blocks in block quotes)

*   indented unordered list

1.  indented ordered list
11. indented ordered list
111.    indented ordered list
1111.   indented ordered list
11111.  indented ordered list

    code?

<section>
    <article>
        HTML.
    </article>
</section>

[^fn]:
    Footnote.

Tab stops of 3 don’t work well due to indented code and the locked sizes of footnotes and block quotes.

Paragraph[^fn1][^fn2].

> unindented block quote.

***

>  indented block quotes (⚠️ fine, but becomes complex when adding indented code blocks in block quotes)

*  indented unordered list

1. indented ordered list
11.   indented ordered list
111.  indented ordered list
1111. indented ordered list
11111.   indented ordered list

   code 1? (💥 not enough)

      code 2? (💥 too much, spaces show up)

<section>
   <article>
      HTML.
   </article>
</section>

[^fn1]:
   Footnote 1 (💥 not enough)

[^fn2]:
      Footnote 2 (⚠️ fine, but becomes complex when adding indented code blocks in block quotes)

Finally, tab stops of 2 work really well, assuming you use 4 spaces for footnotes and indented code:

Paragraph[^fn1][^fn2].

> unindented block quote.

* indented unordered list

1.  indented ordered list
11. indented ordered list
111.  indented ordered list
1111. indented ordered list
11111.  indented ordered list

  code 1? (💥 not enough)

    code 2

<section>
  <article>
    HTML.
  </article>
</section>

[^fn1]:
  Footnote.

[^fn2]:
    Footnote.

To summarize, considering constructs:

  • trying to indent block quotes doesn’t work
  • lists allow 2, 3, and 4 spaces (at 5 they start breaking and turning into code)
  • indented code is okay for 4 (see lists), and okay with 2. Though, it might be better to not use indented code (GH-49), and this new tabSize feature could throw when fences: false?
  • HTML doesn’t care about indent
  • footnotes are similar to indented code: 4 is perfect and 2 is okay. Note that it’s a new, non-CM feature, so we don’t have to put too much weight onto making it perfect.

Concluding, we can drop 8, as it won‘t work. Leaving us with 2, 3, and 4. Given that lists don’t matter and we can ignore HTML, now left with:

  • block quotes, which look best at 2, and can‘t be indented
  • indented code, look best at 4, are okay with 2, but should probably be ignored
  • footnotes, look best at 4, are okay with 2, and are uncommon and quite new

3 isn’t great to align things in monospace it seems. And well, it isn’t popular either. So let’s ditch that too. Leaving us with 2 and 4, which both do align as a nice grid.

There is another problem with lists: when they start with indented code. As we’re assuming here that a tab key is used which expands to an X amount of spaces to align, as follows:

*␉asd (one tab indent after the bullet to start the paragraph)
*␉␉qwe (another one to make code)

This actually renders:

  • asd
  •   qwe
    

(note the included spaces, “part” of the code).

Perhaps lists should, like block quotes, not be indented with a tab either? But just one space? This is quite a change. And a bit related to https://github.com/syntax-tree/mdast-util-to-markdown/issues/48.

Solution

I’m leaning to think that:

  • options.indentStyle = 'tab' | 'space', default: 'space'
  • options.indentList = boolean | 'mixed', default: now true, false with GH-48. (false is current 'one', true is current 'tab', 'mixed' is false for tight lists and true for loose lists, to match Markdown Style Guide)
    • This can throw when true / 'mixed' with fences: false (because a first child code interferes with the tab, note: that this currently is broken as it doesn’t roundtrip)
  • options.indentSize = 2 | 4, default: 4. Only affects actual spaces, so w/ indentStyle: 'space'. As indented code and footnotes require 4 spaces, it only affects lists w/ options.indentList. But it would affect MDX JSX
  • we should likely start recommending how folks should author markdown and configure their editorconfig, with:
    [*.md]
    trim_trailing_whitespace = false
    tab_width = 4
    
  • Perhaps unified-engine could start supporting loading an .editorconfig?

Alternatives

wooorm avatar Jan 13 '22 09:01 wooorm