什么是 @types/commonmark
@types/commonmark 是 CommonMark 标准的 TypeScript 类型定义。它定义了节点和解析器等常用类和方法,方便在 TypeScript 项目中使用 CommonMark。如果你正在开发或者维护一个 TypeScript 的项目,需要使用 CommonMark 解析或者生成 Markdown,那么 @types/commonmark 可以非常方便地帮助你完成这个任务。
安装 @types/commonmark
首先,你需要安装 @types/commonmark。你可以使用 npm 安装它:
npm install --save-dev @types/commonmark
在这里我们加上了 --save-dev
参数,因为 @types/commonmark 只是 TypeScript 项目的开发时依赖,而不是运行时依赖。所以我们只需要在开发时安装它即可。
从 Markdown 转换成 HTML
接下来,我们来看看如何使用 @types/commonmark 将 Markdown 转换成 HTML。
-- -------------------- ---- ------- ------ - -- ---------- ---- ------------ ----- ------ - --- ------------------- ----- ------ - --- ------------------------- ----- -------- - -- ------ -------------- -- - ---------------------------- ----- ------ - ---------------------- ----- ---- - --------------------- ----------------- -- ---------- -------------------- -- - -- -----------------------------------------
在这个例子中,我们首先引入了 @types/commonmark 的模块。然后我们创建了两个实例:一个是 Parser
,另一个是 HtmlRenderer
。接着,我们将 Markdown 字符串传入到 Parser
实例中,将其解析成一个抽象语法树(AST)。然后我们将 AST 传入到 HtmlRenderer
实例中,将其渲染成 HTML 字符串。
最后,我们输出了渲染出的 HTML 字符串。
高级用法
除了基本的用法之外,@types/commonmark 还提供了很多其他的 API,如下所示:
Token 和 Node
在 CommonMark 中,解析器会将 Markdown 文本解析成一个 Token 的数组。每个 Token 都表示一种 Markdown 元素,如标题、段落、链接等。
而在 @types/commonmark 中,Token 是一个抽象基类,它定义了不同 Token 的基本共性。具体的 Token 类型则是 Lexer.HRuleToken
、Lexer.BlockquoteStartToken
、Lexer.AtxHeadingStartToken
等。
除了 Token 之外,CommonMark 中的解析器还会将 Token 转换成 Node。Node 则用于表示解析出的 Markdown 元素和它们的属性。
在 @types/commonmark 中,Node 也是一个抽象基类,它定义了不同 Node 的基本共性。具体的 Node 类型则是 Node.BlockQuote
、Node.Paragraph
、Node.Link
等。
下面是一个例子,展示如何使用 Node 来遍历一个文档的节点:
-- -------------------- ---- ------- ------ - -- ---------- ---- ------------ ----- ------ - --- ------------------- ----- -------- - -- ------ -------------- -- - ---------------------------- ----- ------ - ---------------------- --- ---- - ----------------- ----- ----- --- ----- - ---------------------- -- -------- ---------- ---- ---- - --------- -
在这个例子中,我们首先解析了一个 Markdown 字符串,并得到了它的根节点。然后我们使用一个 while 循环遍历了这个节点以下的所有节点,输出了它们的类型。
扩展解析器
@types/commonmark 允许你扩展原有的解析器,以支持自定义的 Markdown 元素。这是通过继承 InlineParser
、BlockParser
类并实现自己的解析方法来实现的。
还是用一个例子来说明如何实现一个自定义的解析器,以扩展 CommonMark 的语法。
首先,我们需要定义我们的解析器:
-- -------------------- ---- ------- ------ - -- ---------- ---- ------------ ----- -------------- ------- ----------------------- - ------------- - --------- --------------------- -------- ----- -- - ----- ---- - ---------------------- ----- ----- - --- ------------------------ ----- ----------------------- -- - - ----- ------------- ------- ---------------------- - ------------- - --------- ----- -------- - - ---------- ------ ----------- ----- --------- ---- - ----------------- --------- ------------------- --- ------- ----- -- ------------------------ - --------- ----- ------ ------ --------- -------- ----- -- - ----- ---- - --- ------------------------------------ --- ---------------- - ---------------------------------------- -- ------- ---------- - ---------------- ---------------------------------- ------------------------------- - - ------ ----------------- ----- ---- - ------------------------ - -- ---------------------- - --------- ----- ------ ------ --------- -------- ----- -- - --------- - -------- ------------ - ----- - -- - - ----- ------ - --- ------------------- ------- --- ----------------- ------ --- --------------- --
在这个例子中,我们定义了一个 MyInlineParser
和一个 MyBlockParser
类,分别用于解析内联元素和块级元素。
要实现自定义解析器,我们需要继承 InlineParser
、BlockParser
类,并实现我们自己的解析方法。
在这个例子中,我们实现了两个自定义的 Markdown 元素::)
和脚注(footnote)。
:)
用于在 Markdown 中输入笑脸,它在渲染时会被渲染成一个 Unicode 字符(😊)。我们在 MyInlineParser
中添加了一个名为 ":)" 的解析规则。
脚注用于在 Markdown 文档中添加注释,它的用法是在段落中添加一个类似 [text][^1]
的字符串,然后在文档结尾处添加一个类似于 [^1]: footnote text
的字符串。我们在 MyBlockParser
中添加了一个名为 "footnote" 的解析规则。
最后,我们将我们的自定义解析器传递给 Parser
中:
const markdown = '# Hello, world! :)\n\nThis is a footnote.[^1]\n\n[^1]: This is the footnote text.' const parsed = reader.parse(markdown) const html = writer.render(parsed) console.log(html) // <h1>Hello, world! 😊</h1>\n<p>This is a footnote.<sup><a href="#fn1" id="fnref1">1</a></sup></p>\n<div class="footnotes">\n<hr>\n<ol>\n<li id="fn1">\n<p>This is the footnote text. <a href="#fnref1" class="footnote-backref">↑</a></p>\n</li>\n</ol>\n</div>\n
在这个例子中,我们使用了 MyInlineParser
中定义的 :)
符号。同时,我们也使用了 MyBlockParser
中定义的脚注语法。
总结
本文中介绍了 @types/commonmark 的用法和一些高级用法,包括如何扩展解析器。如果你正在开发或者维护一个 TypeScript 的项目,需要使用 CommonMark 解析或者生成 Markdown,那么 @types/commonmark 可以非常方便地帮助你完成这个任务。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/types-commonmark