你会如何解析Markdown?

时间:2009-03-03 07:27:38

标签: parsing markdown

  

编辑:我最近了解了一个名为CommonMark的项目   正确识别并处理原文中的含糊之处   降价规格。 http://commonmark.org/它有很棒的C#库   支持。

您可以找到语法here

下载的源代码是用Perl编写的,我无意表达。它充满了正则表达式,它依赖于MD5哈希来逃避某些字符。对此有些不对劲!

我即将为Markdown的解析器进行硬编码。这有什么经验?

如果你对Markdown的实际解析没有任何意义,请给我时间。 (这可能听起来很苛刻,但是,我正在寻找洞察力,而不是解决方案,即第三方库。)

为了帮助解决问题,正则表达式意味着识别模式!不要解析整个语法。人们认为这样做是foobar。

  • 如果你考虑Markdown,它基本上是基于段落的概念。
  • 因此,合理的方法可能是将输入分成段落。
  • 有多种段落,例如标题,文本,列表,块引用和代码。
  • 因此,挑战是确定这些段落及其发生的背景。

一旦我发现它值得分享,我会回来找一个解决方案。

10 个答案:

答案 0 :(得分:64)

我所知道的唯一使用实际解析器的降价实现是Jon MacFarleanepeg-markdownIts parser基于名为Parsing Expression Grammarpeg解析器生成器。


编辑:Mauricio Fernandez最近发布了他的Simple Markup Markdown parser,他在OcsiBlog Weblog引擎中写道。因为解析器是用OCaml编写的,所以非常简单和简短(parser为268 SLOC,HTML emitter为43 SLOC),但{{ 3}}(比blazingly fast(写入手动优化的C)快20%,discountBlueCloth)快六百倍,尽管事实如此它甚至没有针对性能进行优化。因为它仅供Mauricio自己内部用于他的博客,所以与Ruby有一些偏差,但Mauricio创建了official Markdown specification

答案 1 :(得分:17)

我上周发布了一个新的基于解析器的Markdown Java实现,名为pegdown。 pegdown使用PEG解析器首先构建一个抽象语法树,然后将其写入HTML。因此,与基于正则表达式的方法相比,它非常干净且更易于阅读,维护和扩展。 PEG语法基于John MacFarlanes C实现的“peg-markdown”。

也许你感兴趣的东西......

答案 2 :(得分:6)

如果我要尝试解析markdown(及其扩展名Markdown extra),我想我会尝试使用状态机并一次解析一个char,将表示文本位的一些内部结构链接在一起然后,一旦解析完毕,我就会生成所有被串在一起的对象的输出。

基本上,当我读取输入文件时,我会构建一个类似迷你DOM的树 要生成输出,我只需遍历树并输出HTML或其他任何内容(PS,LaTex,RTF,...)

可能会增加复杂性的事情:

  • 虽然规则很容易实现,但您可以混合HTML和降价这一事实:只需忽略两个平衡标签之间的任何内容并逐字输出即可。

  • 网址和注释的引用可以在文本的底部。使用超链接的数据结构可以简单地记录如下内容:

    [my text to a link][linkkey]
    results in a structure like: 
        URLStructure: 
        |  InnerText : "my text to a link"
        |  Key       : "linkkey"
        |  URL       : <null>
    
  • 标题可以用下划线定义,这可能会迫使我们在通用段落中使用简单的数据结构,并在读取文件时修改其属性:

    ParagraphStructure:
    |  InnerText    : the current paragraph text 
    |                 (beginning of line until end of line).
    |  HeadingLevel : <null> or 1-4 when we can assess 
    |                 that paragraph heading level, if any.
    

无论如何,只是一些想法。

我确信有很多小细节要处理,我很确定Regexes在这个过程中会变得很方便。
毕竟,它们是为了处理文本。

答案 3 :(得分:3)

我可能已经阅读了足够多的语法规范来了解它,并了解如何解析它。

阅读现有的解析器代码当然很棒,既可以看到似乎是复杂性的主要来源,也可以使用任何特殊的巧妙技巧。 MD5校验和的使用似乎有点奇怪,但我还没有研究足够的代码来理解它为什么要完成。名为_EscapeSpecialChars()的例程中的注释声明:

  

我们用相应的MD5校验和值替换每个这样的字符;   这可能是矫枉过正,但它应该可以防止我们与逃跑相撞   意外的价值观。

用完整的MD5替换单个角色确实看起来很奢侈,但也许它真的很有意义。

当然,考虑为Flex之类的工具创建一个“真正的”语法来摆脱正则表达式的沼泽是很聪明的。

答案 4 :(得分:2)

如果Perl不是你的事,那么at least 10 other languages中有Markdown实现。他们可能并非都具有100%的兼容性,但往往非常接近。

答案 5 :(得分:2)

MarkdownPapers是另一个Java实现,其解析器以JavaCC语法定义。

答案 6 :(得分:0)

Here您可以找到Markdown的JavaScript实现。它也非常依赖于正则表达式,因为这只是解析文本的最快速,最简单的方法。

但是它使MD5失去了部分。

我无法直接帮助解析编码,但也许这个链接可以帮助你这样或那样。

答案 7 :(得分:0)

有多种语言的库可用,包括php,ruby,java,c#,javascript。我建议看一些这些想法。

这取决于您希望使用哪种语言,为了实现它的最佳方式,将会有惯用的和非惯用的方法来实现它。

正则表达式在perl中工作,因为perl和regex是最好的朋友。

答案 8 :(得分:0)

如果您使用的是其他三种以上的编程语言 用户,您应该能够找到一个库来为您解析它。一个 快速Google-ing显示了CL,Haskell,Python的库, JavaScript,Ruby等等。你不太可能需要 重新发明这个轮子。

如果你真的必须从头开始写,我建议写一个 适当的解析器。使用这种技术,您不必逃避任何事情 使用MD5哈希值。 (我同意,如果你必须这样做, 是时候重新考虑你的设计了。)

答案 9 :(得分:0)

Markdown是一个JAWL(只是另一种维基语言)

有很多开源维基,你可以检查解析器的代码。大多数人使用REGEX

查看screwturn wiki,有一个有趣的多通道格式化程序管道,这是一个非常好的技术 - 请参阅/core/Formatter.cs和/core/FormatterPipeline.cs

最好是使用/加入现有项目,这些事情总是比它们出现的要难得多