3 个版本

0.1.2 2021 年 8 月 4 日
0.1.1 2021 年 8 月 3 日
0.1.0 2021 年 8 月 3 日

#2814解析器实现

每月 24 次下载

GPL-3.0-only

30KB
374

discord-markdown

解析 Discord 风格的 Markdown

crates.io 0.1.2 license

这个解析器是为与 cheesecake 一起使用而编写的,因此提供的转换函数是为该目的设计的。如果此函数不适合您的用例,您可以编写自己的转换函数以从解析的 AST 生成 HTML。生成的 HTML 中的文本将进行 HTML 转义,因此您可以安全地将输出插入 DOM。

文档

docs.rs 上阅读 API 文档。

用法

在输入字符串上调用 parser::parse,它将返回一个 Expression 向量。将此向量提供给 convertor::to_html 以获取 HTML 字符串。如果您的输入文本还将包含自定义表情符号、用户提及、角色提及或频道提及,则请使用 convertor::to_html_with_callbacks

如果想要解析带有 alt 文本的链接,请使用 parser::parse_with_md_hyperlinks 替代。

注意

在代码块内部不将换行符转换为 Expression::Newline,因此必须在转换器中处理。

示例

如果您只想生成 AST,则非常简单

use discord_markdown::parser::{parse, Expression::*};

fn main() {
    let ast = parse("> _**example** formatted_ ||string||");
    assert_eq!(ast, vec![
        Blockquote(vec![
            Italics(vec![
                Bold(vec![Text("example")]),
                Text(" formatted"),
            ]),
            Text(" "),
            Spoiler(vec![Text("string")]),
        ]),
    ]);
}

如果您想生成 HTML 字符串,则如下所示

use discord_markdown::{parser::parse, convertor::*};

fn dummy_callback(x: &str) -> (String, Option<String>) {
    (x.to_owned(), None)
}

fn id_to_name(id: &str) -> (String, Option<String>) {
    (
        if id == "123456789123456789" {"member"} else {"unknown role"}.to_owned(),
        Some("#ff0000".to_owned()),
    )
}

fn main() {
    let html = to_html(parse("> _**example** formatted_ ||string||"));
    assert_eq!(html, "<blockquote><em><strong>example</strong> formatted\
    </em> <span class=\"spoiler\">string</span></blockquote>");

    // With role mentions
    let html = to_html_with_callbacks(
        parse("<@&123456789123456789>"),
        dummy_callback,
        dummy_callback,
        id_to_name,
        dummy_callback,
    );
    assert_eq!(html, "<div class=\"role\" style=\"color: #ff0000\">@member\
    <span style=\"background-color: #ff0000\"></span></div>");
}

然后您可以在样式表中添加对 .role.role span 的样式。以下是一些示例 CSS

.role {
    background-color: initial;
    display: inline-block;
    position: relative;
    word-break: keep-all;
}

.role span {
    border-radius: 4px;
    height: 100%;
    width: 100%;
    opacity: .12;
    position: absolute;
    left: 0;
    top: 0;
}

依赖项

~5.5MB
~103K SLoC