备注:MDAST中如何解析HTML个标签及其内容
Remark: How to parse HTML tags and their content in MDAST
我正在尝试使用 Unified and Remark-Parse 解析 GitHub 风格的降价文件以生成 MDAST。我能够正确且轻松地解析其中的大部分内容,但是我在解析 HTML 标签及其来自 AST 的内容时遇到了问题。
在 AST 中,HTML 标签及其内容表示为兄弟姐妹,而不是父子关系。例如<sub>hi</sub>
被解析为
[
{
"type": "paragraph",
"children": [
{
"type": "html",
"value": "<sub>",
},
{
"type": "text",
"value": "hi",
},
{
"type": "html",
"value": "</sub>",
}
]
}
]
理想情况下,我希望它被解析为
[
{
"type": "paragraph",
"children": [
{
"type": "html",
"value": "sub",
"children": [
{
"type": "text",
"value": "hi",
},
]
},
]
}
]
以便我可以访问标签类型及其内容。 (具体来说,我的目标是跳过标签及其内容,因为我不需要它们)
这是我目前使用的配置:
import unified from 'unified';
import markdown from 'remark-parse';
import type {Block} from '@notionhq/client/build/src/api-types';
import {parseRoot} from './internal';
import gfm from 'remark-gfm';
export function parseBody(body: string): Block[] {
const tokens = unified().use(markdown).use(gfm).parse(body);
return parseRoot(tokens);
}
所以,我的问题是:是否有配置 Remark 的方法/是否有 Remark 插件来执行此操作?如果没有,我将如何着手创建一个这样做的插件?
谢谢。
首先:为什么 AST 看起来像它的样子,为什么 Remark 很可能没有选择以不同的方式做它
AST 以这种方式表示的原因是因为那是 CommonMark 规范为 raw inline HTML and for HTML blocks 指定的内容。具体来说,CommonMark指定HTML标签被传递,不被解析.
对于inline HTML,spec支持inline HTML tags,与支持inline [=82]不同=]。标签只是按原样传递。没有匹配的开始和结束标签。原因是:
- 性能
- 解析器复杂度
- HTML 标记仅在 Markdown 没有您需要的功能时作为“使用风险自负”“最后手段”选项才受支持。
对于少量 HTML 标签,块级支持打开和关闭标签匹配。 pre
、script
、style
和 textarea
,后者最近才在规范的 v0.30 中添加。
您可以阅读规范的上述链接部分,并搜索 CommonMark forum 中的讨论以更深入地了解原因,但要切中要点,请阅读:
-
跳到[本论坛的[原始HTML部分](https://talk.commonmark.org/t/beyond-markdown/2787?u=vas)post CommonMark 规范的作者和维护者,John MacFarlane (@jgm)。
This forum question and also this one 和@jgm 的回答。
第二:你能做些什么
Remark 是“统一集体的一部分”,它是一个以处理 AST(抽象语法树)为中心的基础设施。从你的问题来看,你似乎已经明白了。
统一的页面上有很多关于如何编写插件的帮助:
但是学习如何执行此操作并快速了解实现的最佳方法是查看 many existing mdast-specific manipulators。
我正在尝试使用 Unified and Remark-Parse 解析 GitHub 风格的降价文件以生成 MDAST。我能够正确且轻松地解析其中的大部分内容,但是我在解析 HTML 标签及其来自 AST 的内容时遇到了问题。
在 AST 中,HTML 标签及其内容表示为兄弟姐妹,而不是父子关系。例如<sub>hi</sub>
被解析为
[
{
"type": "paragraph",
"children": [
{
"type": "html",
"value": "<sub>",
},
{
"type": "text",
"value": "hi",
},
{
"type": "html",
"value": "</sub>",
}
]
}
]
理想情况下,我希望它被解析为
[
{
"type": "paragraph",
"children": [
{
"type": "html",
"value": "sub",
"children": [
{
"type": "text",
"value": "hi",
},
]
},
]
}
]
以便我可以访问标签类型及其内容。 (具体来说,我的目标是跳过标签及其内容,因为我不需要它们)
这是我目前使用的配置:
import unified from 'unified';
import markdown from 'remark-parse';
import type {Block} from '@notionhq/client/build/src/api-types';
import {parseRoot} from './internal';
import gfm from 'remark-gfm';
export function parseBody(body: string): Block[] {
const tokens = unified().use(markdown).use(gfm).parse(body);
return parseRoot(tokens);
}
所以,我的问题是:是否有配置 Remark 的方法/是否有 Remark 插件来执行此操作?如果没有,我将如何着手创建一个这样做的插件?
谢谢。
首先:为什么 AST 看起来像它的样子,为什么 Remark 很可能没有选择以不同的方式做它
AST 以这种方式表示的原因是因为那是 CommonMark 规范为 raw inline HTML and for HTML blocks 指定的内容。具体来说,CommonMark指定HTML标签被传递,不被解析.
对于inline HTML,spec支持inline HTML tags,与支持inline [=82]不同=]。标签只是按原样传递。没有匹配的开始和结束标签。原因是:
- 性能
- 解析器复杂度
- HTML 标记仅在 Markdown 没有您需要的功能时作为“使用风险自负”“最后手段”选项才受支持。
对于少量 HTML 标签,块级支持打开和关闭标签匹配。 pre
、script
、style
和 textarea
,后者最近才在规范的 v0.30 中添加。
您可以阅读规范的上述链接部分,并搜索 CommonMark forum 中的讨论以更深入地了解原因,但要切中要点,请阅读:
跳到[本论坛的[原始HTML部分](https://talk.commonmark.org/t/beyond-markdown/2787?u=vas)post CommonMark 规范的作者和维护者,John MacFarlane (@jgm)。
This forum question and also this one 和@jgm 的回答。
第二:你能做些什么
Remark 是“统一集体的一部分”,它是一个以处理 AST(抽象语法树)为中心的基础设施。从你的问题来看,你似乎已经明白了。
统一的页面上有很多关于如何编写插件的帮助:
但是学习如何执行此操作并快速了解实现的最佳方法是查看 many existing mdast-specific manipulators。