#markdown-parser #markdown #common-mark #github #gfm #default #port

bin+lib comrak

100%兼容CommonMark的GitHub Flavored Markdown解析器和格式化器

68个版本 (26个破坏性版本)

0.27.0 2024年8月19日
0.26.0 2024年7月12日
0.25.0 2024年7月12日
0.22.0 2024年3月29日
0.1.6 2017年7月20日

#17 in 解析实现

Download history 10439/week @ 2024-05-03 8955/week @ 2024-05-10 10521/week @ 2024-05-17 8453/week @ 2024-05-24 10101/week @ 2024-05-31 11126/week @ 2024-06-07 10951/week @ 2024-06-14 10794/week @ 2024-06-21 10276/week @ 2024-06-28 9989/week @ 2024-07-05 9906/week @ 2024-07-12 8502/week @ 2024-07-19 10792/week @ 2024-07-26 8755/week @ 2024-08-02 9550/week @ 2024-08-09 8865/week @ 2024-08-16

每月下载量39,639
用于138个crate(113个直接使用)

BSD-2-Clause

1.5MB
36K SLoC

Comrak

Build status CommonMark: 652/652 GFM: 670/670 crates.io version docs.rs

Rust版本的github的cmark-gfm

默认模式下符合CommonMark 0.31.2。GFM支持与版本0.29.0.gfm.13同步。

安装

Cargo.toml中指定为需求

[dependencies]
comrak = "0.27"

Comrak的库支持Rust 1.62.1+。

命令行界面

  • 在任何拥有Rust工具链的地方
    • cargo安装comrak
  • 许多Unix发行版
    • pacman -S comrak
    • brew安装comrak
    • dnf安装comrak
    • nix run nixpkgs#comrak

您还可以在我的GitHub发行版中找到我发布的构建版本,但它们仅限于我在构建它们时所访问的机器!webinstall.dev提供curl | shell风格的最新版本安装,适用于您的操作系统。

使用方法

点击展开CLI --help输出。
$ comrak --help
A 100% CommonMark-compatible GitHub Flavored Markdown parser and formatter

Usage: comrak [OPTIONS] [FILE]...

Arguments:
  [FILE]...
          CommonMark file(s) to parse; or standard input if none passed

Options:
  -c, --config-file <PATH>
          Path to config file containing command-line arguments, or 'none'
          
          [default: /home/runner/.config/comrak/config]

  -i, --inplace
          To perform an in-place formatting

      --hardbreaks
          Treat newlines as hard line breaks

      --smart
          Use smart punctuation

      --github-pre-lang
          Use GitHub-style <pre lang> for code blocks

      --full-info-string
          Enable full info strings for code blocks

      --gfm
          Enable GitHub-flavored markdown extensions: strikethrough, tagfilter, table, autolink, and
          tasklist. Also enables --github-pre-lang and --gfm-quirks

      --gfm-quirks
          Enables GFM-style quirks in output HTML, such as not nesting <strong> tags, which
          otherwise breaks CommonMark compatibility

      --relaxed-tasklist-character
          Enable relaxing which character is allowed in a tasklists

      --relaxed-autolinks
          Enable relaxing of autolink parsing, allow links to be recognized when in brackets and
          allow all url schemes

      --default-info-string <INFO>
          Default value for fenced code block's info strings if none is given

      --unsafe
          Allow raw HTML and dangerous URLs

      --gemojis
          Translate gemojis into UTF-8 characters

      --escape
          Escape raw HTML instead of clobbering it

      --escaped-char-spans
          Wrap escaped characters in span tags

  -e, --extension <EXTENSION>
          Specify extension name(s) to use
          
          Multiple extensions can be delimited with ",", e.g. --extension strikethrough,table
          
          [possible values: strikethrough, tagfilter, table, autolink, tasklist, superscript,
          footnotes, description-lists, multiline-block-quotes, math-dollars, math-code,
          wikilinks-title-after-pipe, wikilinks-title-before-pipe, underline, spoiler, greentext]

  -t, --to <FORMAT>
          Specify output format
          
          [default: html]
          [possible values: html, xml, commonmark]

  -o, --output <FILE>
          Write output to FILE instead of stdout

      --width <WIDTH>
          Specify wrap width (0 = nowrap)
          
          [default: 0]

      --header-ids <PREFIX>
          Use the Comrak header IDs extension, with the given ID prefix

      --front-matter-delimiter <DELIMITER>
          Ignore front-matter that starts and ends with the given string

      --syntax-highlighting <THEME>
          Syntax highlighting for codefence blocks. Choose a theme or 'none' for disabling
          
          [default: base16-ocean.dark]

      --list-style <LIST_STYLE>
          Specify bullet character for lists (-, +, *) in CommonMark output
          
          [default: dash]
          [possible values: dash, plus, star]

      --sourcepos
          Include source position attribute in HTML and XML output

      --experimental-inline-sourcepos
          Include inline sourcepos in HTML output, which is known to have issues

      --ignore-setext
          Ignore setext headers

      --ignore-empty-links
          Ignore empty links

  -h, --help
          Print help information (use `-h` for a summary)

  -V, --version
          Print version information

By default, Comrak will attempt to read command-line options from a config file specified by
--config-file. This behaviour can be disabled by passing --config-file none. It is not an error if
the file does not exist.

还有一个Rust接口。您可以直接使用comrak::markdown_to_html

use comrak::{markdown_to_html, Options};
assert_eq!(markdown_to_html("Hello, **世界**!", &Options::default()),
           "<p>Hello, <strong>世界</strong>!</p>\n");

或者您可以自己解析输入到AST中,对其进行操作,然后使用您想要的格式化器

use comrak::nodes::NodeValue;
use comrak::{format_html, parse_document, Arena, Options};

fn replace_text(document: &str, orig_string: &str, replacement: &str) -> String {
    // The returned nodes are created in the supplied Arena, and are bound by its lifetime.
    let arena = Arena::new();

    // Parse the document into a root `AstNode`
    let root = parse_document(&arena, document, &Options::default());

    // Iterate over all the descendants of root.
    for node in root.descendants() {
        if let NodeValue::Text(ref mut text) = node.data.borrow_mut().value {
            // If the node is a text node, perform the string replacement.
            *text = text.replace(orig_string, replacement);
        }
    }

    let mut html = vec![];
    format_html(root, &Options::default(), &mut html).unwrap();

    String::from_utf8(html).unwrap()
}

fn main() {
    let doc = "This is my input.\n\n1. Also [my](#) input.\n2. Certainly *my* input.\n";
    let orig = "my";
    let repl = "your";
    let html = replace_text(&doc, &orig, &repl);

    println!("{}", html);
    // Output:
    //
    // <p>This is your input.</p>
    // <ol>
    // <li>Also <a href="#">your</a> input.</li>
    // <li>Certainly <em>your</em> input.</li>
    // </ol>
}

对于更实际的例子,请参阅我如何从包含嵌入式YAML的基本文档生成我的GitHub用户README,该YAML本身包含嵌入式Markdown,或者查看Comrak在crates.io的一些依赖项GitHub上的依赖项

安全

cmarkcmark-gfm一样,Comrak会对原始HTML和潜在危险的链接进行清洗。这一变化是在Comrak 0.4.0版本中引入的,以支持默认安全模式,后来也被同行采用。:)

要启用这些功能,请使用unsafe_选项(或在命令行程序中使用--unsafe)。如果这样做,我们建议使用配置针对您需求的消毒库,如ammonia

扩展

Comrak支持GitHub Flavored Markdown规范中定义的CommonMark的五个扩展,该规范可在GitHub Flavored Markdown Spec中找到。

Comrak还支持其自身的扩展,这些扩展尚未具体说明(欢迎提交PR!)

  • 上标
  • 标题ID
  • 脚注
  • 描述列表
  • 前导内容
  • 多行块引用
  • 数学公式
  • 表情符号简码
  • 维基链接
  • 下划线
  • 隐藏文本
  • "绿色文字"

默认情况下,所有扩展均未启用;通过在每个解析过程中设置ExtensionOptions结构体中的适当值来单独启用它们。

插件

代码块语法高亮

您可以提供自己的语法高亮引擎。

创建一个SyntaxHighlighterAdapter特质的实现,然后将此类适配器的实例提供给Plugins.render.codefence_syntax_highlighter。要使用插件格式化Markdown文档,请使用markdown_to_html_with_plugins函数,该函数接受您的插件对象作为参数。

有关更多详细信息,请参阅syntax_highlighter.rssyntect.rs示例。

Syntect

syntect是一个用于Rust的语法高亮库。默认情况下,comrak提供对其的插件。要利用它,创建一个plugins::syntect::SyntectAdapter的实例,并在您的Plugins选项中使用它。

Comrak的设计目标是尽可能地模拟上游cmark-gfm的代码结构。好处是,cmark-gfm的任何更改都会在Comrak中产生可预测的变化。同样,任何在cmark-gfm中的错误也很可能在Comrak中重现。这可能是优点也可能是缺点,具体取决于您的用例。

当然,缺点是代码往往与惯用的Rust不同,尤其是在AST中广泛使用RefCell,尽管贡献者已尽可能使其变得尽可能快,但它仍然不如一些其他基于CommonMark的解析器快。以下是一些其他可以考虑的项目:

  • Raph Levienpulldown-cmark。它非常快,使用了一种新颖的解析算法,并且不构建AST(但如果你想,可以使用它来构建)。cargo doc使用了这个,生态系统中的许多其他项目也使用了这个。
  • markdown-rs(1.x)值得关注。
  • 知道其他库?请提交PR以添加它!

据我所知,Comrak是唯一一个严格实现GitHub Flavored Markdown扩展的库。

基准测试

您需要安装hyperfine和CMake,如果您想与cmark-gfm进行比较。

如果您只想为comrak二进制文件本身运行基准测试,请运行

make bench-comrak

这将以发布模式构建Comrak并对其运行基准测试。您将在控制台中看到hyperfine报告的时间测量值。

Makefile还提供了一个运行comrak当前状态(包括您的更改)、comrak主分支、cmark-gfmpulldown-cmarkmarkdown-it.rs基准测试的方法。您需要CMake,并确保子模块已准备就绪

make bench-all

这将构建并运行所有基准测试,并报告每个基准测试的时间以及相对时间。

贡献

贡献是非常受欢迎的;如果您想提供帮助,请考虑查看具有good first issue标签的问题!我很乐意在整个过程中提供指导和帮助,即使(尤其是!)您是Rust或开源的新手。

在可能的情况下,我实践了Peter Hintjens所描述的乐观合并。请记住也要遵守行为准则

感谢Comrak的众多贡献者为PR和问题打开!

代码贡献者

Small chart showing Comrak contributors.

财务贡献者

成为财务贡献者,帮助维持Comrak的开发。我是自雇的——开源软件依赖于集体。

联系方式

Asherah Connor <ashe kivikakk ee>

版权(c)2017–2024,Asherah Connor和Comrak贡献者。许可协议为2-Clause BSD License

cmark本身是版权(c)2014,John MacFarlane。

有关所有详细信息,请参阅COPYING

依赖关系

~4–16MB
~243K SLoC