是否有一种标准方法可用于解析Textile / Markdown中的内联修饰符

时间:2012-08-01 23:54:32

标签: html parsing markdown markup textile

我一直在考虑使用Scala的解析器组合库(基本上是PEG解析器)编写一个Textile解析器,并且想知道我应该使用哪种方法来解析内联修饰符

This is *bold* text, _italic_ text, +underlined+ text, etc.

在这种情况下,它非常清楚什么是什么,应该解析什么。但是,有很多边缘情况并不那么清楚。只关注粗体文字:

Which sections get bolded: 
*onomato*poeia* ?
bold *word*, without a space after?
tyr*annos*aurus
a bold word in a (*bracket*)?
How about *This *case?

显然,这是主观(事情应该算作粗体)和客观(如何使解析规则正确解析)的混合。

我倾向于选择像

这样的PEG
wordChar = [a-zA-Z]
nonWordChar = [^a-zA-Z]
boldStart = nonWordChar ~ * ~ wordChar
boldEnd = wordChar ~ * ~ nonWordChar
boldSection = boldStart ~ rep(not(boldEnd) ~ anyChar) ~ boldEnd

将解析上述内容如下:

<b>onomato*poeia</b> ?
bold <b>word</b>, without a space after?
tyr*annos*aurus    <- fails because of lack of whitespace
a bold word in a (<b>bracket</b>)?
How about *This *case? <- fails because there is no correct closing *

但是,我不确定这种方法是否适用于所有用例,并且适用于所有边缘情况。有没有一种标准的方法可以复制和依赖?如果我能避免的话,我宁可不要依赖我的特殊思维方式。

2 个答案:

答案 0 :(得分:1)

在降价的情况下没有标准,并且边缘情况的实现不同。对于markdown的一组选择,您可以查看peg-markdown,它也用于MultiMarkdown。当然,降价在这方面比纺织品更复杂,因为它使用**表示粗体,*表示斜体,从而产生更多关于如何对待*hello**there**之类的事情的决定。

PHP markdown extra的开发人员Michel Fortin有test suite,其中包含大量粗体/斜体的边缘情况。但是,我不认为他的决定在这里有普遍的一致意见,并且许多实现解析不同。

那就是说,我认为以下决定在降价方面毫无争议:

  • *仅在下一个字符为非空格时才开始强调。
  • 如果前面的字符是非空格,
  • *只会结束强调。
  • 强调可以在一个单词中发生,所以在he*ll*o中,两个l被强调(尽管一些降价实现为_字符禁用此功能,因为下划线在标识符中很常见。)

答案 1 :(得分:0)

在采购一段时间后,我找到了inline markup recognition rules for reStructuredText

它不遵循降价规则;特别是像t*hi*s这样的东西不会被解析为内联标签,但它非常相似,并且具有类似的总体目的。

这也是一个有点复杂的规范(例如,带有括号和标点符号的特殊外壳)但它的指定非常明确,经过彻底解释和证明。我发现它的规格是建立起来的坚实基础。