通用标记解析 ***

CommonMark Parsing ***

假设我想使用 CommonMark 标准将字符串 ***cat*** 解析为 Markdown。标准说 (http://spec.commonmark.org/0.28/#phase-2-inline-structure):

....

If one is found:

Figure out whether we have emphasis or strong emphasis: if both closer and opener spans have length >= 2, we have strong, otherwise regular.

Insert an emph or strong emph node accordingly, after the text node corresponding to the opener.

Remove any delimiters between the opener and closer from the delimiter stack.

Remove 1 (for regular emph) or 2 (for strong emph) delimiters from the opening and closing text nodes. If they become empty as a result, remove them and remove the corresponding element of the delimiter stack. If the closing node is removed, reset current_position to the next element in the stack.

....

根据我的阅读,结果应该是 <em><strong>cat</strong></em>,因为首先添加了 <strong>,然后是 <em>。但是,所有在线降价编辑器我都在输出中尝试过这个<strong><em>cat</em></strong>。我错过了什么?

这是我认为应该发生的情况的直观表示

TextNode[***] TextNode[cat] TextNode[***]

TextNode[*] StrongEmphasis TextNode[cat] TextNode[*]

TextNode[] 强调 StrongEmphasis TextNode[cat] TextNode[]

强调 StrongEmphasis TextNode[cat]

记住 Commonmark 和 Markdown 不一定是一回事很重要。 Commonmark 是 Markdown 的最新变体。大多数 Markdown 解析器早在 Commonmark 规范开始之前就已经存在并建立了它们的行为。

虽然原始 Markdown rules make no comment on whether the <em> or <strong> tag should be first in the given example, the reference implementation's (markdown.pl) actual behavior was to list the <strong> tag before the <em> tag in the output. In fact, the MarkdownTest package, which was created by the author of Markdown and markdown.pl) explicitly required that output (the original is no longer available online that I know of, but mdtest is a faithful copy with its history 显示自从 MarkdownTest 初始导入以来该测试没有任何修改)。 AFAICT,每个(非 Commonmark)Markdown 解析器都完全遵循该行为。

Commonmark 规范采取了不同的路线。该规范在 Section 6.4 (Emphasis and strong emphasis) 的规则 14 中特别指出:

An interpretation <em><strong>...</strong></em> is always preferred to <strong><em>...</em></strong>.

... 并用 example 444:

进行备份
***foo***

<p><em><strong>foo</strong></em></p>

其实你可以看到,这就是Commonmark的参考实现behavior

顺便说一句,原始问题引用了 Appendix 中推荐如何实现解析器的规范。虽然对解析器创建者可能有用,但我不建议使用该部分来确定正确的语法处理 and/or 输出。应参考实际规则;事实上,在这种情况下,它们显然提供了预期的输出。但是这个问题是关于实现和规范之间的明显差异,而不是规范的解释。

有关更完整的比较,请参阅 Babelmark。除了一些(完全)损坏的实现之外,每个 "classic" Markdown 解析器都遵循 markdown.pl,而每个 Commonmark 解析器都遵循 Commonmark 规范。因此,规范和实现之间没有实际差异。 Markdown 和 Commonmark 之间的差异。

至于为什么 Commonmark 的作者在这方面选择了不同的路线,或者为什么他们在明显不同的情况下坚持调用 Commonmark "Markdown" 是题外话,最好问作者自己。