CommonMark 中的制表符是如何解释的?

How are tabs interpreted in CommonMark?

请参阅 CommonMark 规范中示例 6 之前的描述:http://spec.commonmark.org/0.27/#example-5

我试图了解以下代码如何导致以两个 space 开头的代码块。

>→→foo

示例 6 表明这将转化为以下内容。

<blockquote>
<pre><code>  foo
</code></pre>
</blockquote>

但是第2.2节明确指出:

However, in contexts where whitespace helps to define block structure, tabs behave as if they were replaced by spaces with a tab stop of 4 characters.

所以根据我的理解,上面的 Markdown 表现如下(我用点表示 space)。

>........foo

因为在>之后允许有一个可选的space,并且4个space用于缩进代码块,所以我们剩下,

>...foo

这是一个以三个 space 开头的代码块。那么 CommonMark 如何声称它应该导致以两个 space 开头的代码块?我错过了什么?

关键在 Tabs 部分的第一段(强调已添加):

Tabs in lines are not expanded to spaces. However, in contexts where whitespace helps to define block structure, tabs behave as if they were replaced by spaces with a tab stop of 4 characters.

注意是“4 个字符”而不是 4 spaces。

如果您将文本编辑器配置为使用长度为四的制表位将制表符替换为spaces (任何好的文本编辑器都应该提供此设置),文本编辑器将使用四个字符宽的列。当您按下 Tab 键时,它会将光标转到下一列,每列只有四个字符宽。如果该列已经包含任何字符,则只添加尽可能多的 space 到总共四个字符,在这种情况下将少于四个 space。

例如,如果您在编辑器中键入尖括号 (>) 字符,然后按 Tab 键,您将得到以下内容(当配置为用 spaces 替换制表符时):

>···

因此尖括号加上制表符向前移动到列的末尾(四个字符)总共三个spaces 。由于我们现在处于下一栏的开头,第二次按 Tab 键会将我们移动到下一栏(4 个 space 秒),总共 7 space 秒:

>·······

我们可以确认这是正确的解释,最近对 3bc01c5dc 中提交的规范进行了更改(显然还没有发布)。正如提交评论所暗示的那样,澄清有助于使数学更有意义(强调):

Normally the > that begins a block quote may be followed optionally by a space, which is not considered part of the content. In the following case > is followed by a tab, which is treated as if it were expanded into three spaces. Since one of these spaces is considered part of the delimiter, foo is considered to be indented six spaces inside the block quote context, so we get an indented code block starting with two spaces.

注意添加的句子(粗体),它确认第一个选项卡只添加了“three spaces”。

因此,正如我们现在确定的那样,我们从一个尖括号加上七个 space 开始。因此,首先我们断开 blockquote 分隔符,它由尖括号和第一个 space 组成(在以下示例中,| 用于指示解析器在何处断开字符串,不应算作字符):

>·|······

块引用中包含的文本现在缩进了 6spaces。其中四个是代码块分隔符:

>·|····|··

在代码块的开头留下 两个 space。

当然,正如开头(规范中的部分)所述,选项卡实际上并没有被 space 替换,它只是表现得好像它们被替换了一样。这有时会让人感到困惑。将您的文本编辑器配置为始终用 space 替换制表符可能会有所帮助,这样您就可以避免这种混淆。