安全的做法是使用以下内容:
<div class="aside">
<h2>My heading</h2>
<p>Some text, some text, some more text.</p>
</div>
然而,实际情况比这更加复杂,有许多可能的答案。适用于您的答案取决于您使用的Markdown实现,因为它们之间存在微妙的差异。让我们从参考实现(markdown.pl)和
原始规则开始,因为这是Hoedown声称遵循的规则(见下文)。
旧版Markdown
许多旧解析器最初是在从HTML4转换到XHTML1期间开发的,它们对原始HTML的处理方式和处理方法反映了这一点。也就是说,一些解析器在最近几年已进行更新,以支持新的HTML特性。但是,参考实现已经超过十年没有更新了,所以这是一个很好的起点。通常,如果您能够在参考实现中使某些内容正常工作,则它将在任何实现中正常工作,因此让我们专注于此。
规则首先描述块级HTML标记的处理方式,然后将跨度级别的行为描述为特例。但是,在代码中,事情恰恰相反。跨度级别的行为是默认值,块级别的行为是特殊情况。
当使用跨度级别标记时,您希望结果包装在<p>
标记中。例如,foo <i>bar</i> baz
应该产生<p>foo <i>bar</i> baz</p>
。因此,为了避免在<p>
标记中包含原始HTML,规则要求满足一组非常特定的条件:
唯一的限制是块级HTML元素(例如
<div>
、
<table>
、
<pre>
、
<p>
等)必须由空行与周围内容分隔开,块的开始和结束标记不应缩进使用制表符或空格。Markdown足够智能,不会在HTML块级标记周围添加额外的(不需要的)
<p>
标记。有3个要求:
- 原始HTML块必须以已知的块级标记开头。如前所述,在旧实现中,这些标记必须是HTML4 / XHTML1规范中的有效块级标记。在HTML5中最近引入的任何内容可能无法在各种实现之间一致地工作。
- 开放标签必须在空白行或文档开头之前,并且关闭标签必须在空白行或文档结尾之后。
- 开放标记必须以行的第一个字符开头。任何缩进都将导致解析器无法识别文本块为块级原始HTML。
最后,规则说明如下:
请注意,Markdown格式语法不会在块级HTML标记内处理。例如,您不能在HTML块内使用Markdown样式的*emphasis*
。
请注意,这与跨度级HTML不同:
与块级HTML标记不同,Markdown语法在跨度级标记内处理。
在这种情况下,<span>foo *bar*</span>
会得到<p><span>foo <em>bar</em></span></p>
的结果,而<div>foo *bar*<div>
会得到<div>foo *bar*</div>
的结果。请注意,在第一个示例中,虽然Markdown语法(*bar*
)被处理了,但整个内容被包装在<p>
标签中。相反,在第二个示例中,Markdown语法(*bar*
)没有被处理,但该块未被包装在<p>
标签中。因此,任何包含在块级原始HTML中的内容必须全部使用原始HTML。
因此,让我们将这些规则应用于您的示例:
<div>
<aside>
<h2>My heading</h2>
<p>Some text, some text, some more text.</p>
</aside>
</div>
使用<div>
标签可以被老版本的实现所识别。内容都是原始HTML,因为它不会被处理成Markdown。Babelmark显示这在所有实现中都可行。
当然,同时使用<aside>
和<div>
标签是多余的,因此您可以简单地使用一个带有适当类的<div>
标签:
<div class="aside">
<h2>My heading</h2>
<p>Some text, some text, some more text.</p>
</div>
正如Babelmark 所示,这也适用于任何地方。
如果您使用的实现已经添加了对HTML5块级标签的支持,您可以直接使用<aside>
标签:
<aside>
<h2>My heading</h2>
<p>Some text, some text, some more text.</p>
</aside>
当然,我们仍需要使用所有原始HTML。正如Babelmark 所示, 这在大多数但不是所有实现中都有效。
扩展Markdown
多年来,许多Markdown实现已经添加了非标准的扩展语法,以添加额外的功能。因为明显的原因,许多用户希望能够在原始HTML块中处理Markdown语法。因此,多年前,PHP Markdown Extra 引入了markdown="1"
的变通方法,并被许多实现复制。但是,大多数支持扩展的实现需要显式启用扩展。它不是默认启用的。
如果您使用的实现支持扩展,并且已启用该扩展,则可以使用以下内容(如果支持较新的HTML5标签):
<aside markdown="1">
## My heading
Some text, some text, some more text.
</aside>
或者这样写(如果不支持HTML5标签):
<div markdown="1">
<aside>
## My heading
Some text, some text, some more text.
</aside>
</div>
或者...
<div class="aside" markdown="1">
Some text, some text, some more text.
</div>
Commonmark
有些人对实现不一致感到沮丧,于是开始定义一个严格的规范,这就是所谓的Commonmark spec。然而,讽刺的是,该规范自己承认违反了原始实现的一些非常明确定义的规则,这只会增加更多的不一致性。其中最糟糕的问题之一是原始 HTML 处理。
只要您的原始 HTML 块不包含任何空行,Commonmark 将以与老式 Markdown 实现相同的方式处理您的块。然而,一旦您引入空行,任何接下来的内容都将被解析为Markdown。
此外,Commonmark 规范清楚地定义了哪些标签被视为块级标签。恰好,<aside>
是在标签列表中的。
因此,如果您使用符合 Commonmark 的实现,以下内容将起作用:
<aside>
## My heading
Some text, some text, some more text.
</aside>
请注意,
<aside>
标签紧接着一个空行,这告诉解析器将标签后面的任何内容视为Markdown。正如Babelmark
演示的那样,这适用于Commonmark实现,但不适用于老式实现。
Hoedown
Hoedown专门声称“完全符合”“官方Markdown v1.0.0和v1.0.3测试套件”。请注意,这些是老式参考实现的测试套件,而不是较新的Commonmark规范。在这种情况下,我们可以假设处理原始HTML块内Markdown的Commonmark技巧将无法起作用。当然,您可以尝试并确保其可行性。
Hoedown还声称具有“可选支持几个(非官方)Markdown扩展”。但是,没有可用扩展的综合列表,也没有任何有关如何启用它们的说明。我没有安装该工具,但也许有命令行中的说明?如果您能找到一种启用markdown="1"
扩展的方法,那么您就可以使用该技巧在原始HTML块中进行Markdown处理。
然而,如果没有明确的文档证明,我认为Hoedown是一种老派的实现。我还注意到repo中的
html_block_names.gperf文件未列出
aside
作为已知的HTML块级标记。因此,我们可以假设任何原始HTML块都必须包含在该文件中列出的24个标记之一中。
考虑到上述情况,我们可以安全地假设以下是从Hoedown获得所需结果的唯一确定方法:
<div>
<aside>
<h2>My heading</h2>
<p>Some text, some text, some more text.</p>
</aside>
</div>
或者...
<div class="aside">
<h2>My heading</h2>
<p>Some text, some text, some more text.</p>
</div>
<aside>
是 HTML 5 中的一个新标签,在旧的 Markdown 实现中不支持该标签,因为这些实现是在该标签引入之前创建的。由于 Hoedown 在4-5年前就已经被放弃,我怀疑它从未添加对<aside>
的支持作为“块级”标签。<div>
的行为与我上面链接的两个其他问题中描述的一样。 - Waylan<p>
标签中。如果这导致切换到不同的Markdown处理器有很好的理由,那么我将考虑将其作为解决方案的一部分,尽管这并不是最理想的。 - fluffy