mdast-util-to-markdown
mdast-util-to-markdown copied to clipboard
Figure out a way to support tab-size / aligning columns
Initial checklist
- [X] I read the support docs
- [X] I read the contributing guide
- [X] I agree to follow the code of conduct
- [X] I searched issues and couldn’t find anything (or linked relevant results below)
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 whenfences: 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: nowtrue
,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'
withfences: false
(because a first child code interferes with the tab, note: that this currently is broken as it doesn’t roundtrip)
- This can throw when
-
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
?