parsing - 备注:如何在 MDAST 中解析 HTML 标签及其内容
问题描述
我正在尝试使用Unified和Remark-Parse解析 GitHub 风格的降价文件以生成 MDAST。我能够正确且轻松地解析其中的大部分内容,但是我无法从 AST 中解析 HTML 标记及其内容。
在 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 规范为原始内联 HTML和HTML 块指定的内容。具体来说,CommonMark 指定HTML 标签是通过的,而不是被解析的。
对于内联 HTML,规范支持内联 HTML标签,这与支持内联 HTML不同。标签只是按原样传递。没有匹配的开始和结束标签。原因如下:
- 表现
- 解析器复杂度
- 只有当 Markdown 没有您需要的功能时,HTML 标签才被支持作为“使用风险自负”“最后手段”选项。
对于少量的 HTML 标签,在块级别支持打开和关闭标签匹配。pre
, script
,style
和textarea
, 后者最近才在规范的 v0.30 中添加。
您可以阅读规范的上述链接部分,并在CommonMark 论坛中搜索讨论以更好地了解原因,但要直截了当,请阅读:
规范中对所做选择的解释。
跳到 [本论坛的原始 HTML部分]( https://talk.commonmark.org/t/beyond-markdown/2787?u=vas ) CommonMark 规范作者和维护者 John MacFarlane (@jgm) 的帖子.
第二:你能做些什么
Remark 是“统一集合的一部分”,它是以处理 AST(抽象语法树)为中心的基础设施。从你的问题来看,听起来你已经明白了。
统一的页面上有很多关于如何编写插件的帮助:
但是,了解如何执行此操作并快速了解实现的最佳方法是查看许多现有的 mdast 特定操纵器。
推荐阅读
- php - 根据 WooCommerce 中的付款方式提高购物车商品价格
- r - tune_bayes() 关于高斯过程不适合没有数据的错误
- javascript - 如何将使用 datetimepicker 获得的值转换为日期和时间?
- flutter - Flutter 后台服务
- reactjs - 在 React 的 Swiper 滑块中动态附加幻灯片
- r - R:只有年和月的日期格式
- graph - DAG 的信息
- html - 我怎样才能在不同角度的这些 li 之间建立联系?
- c# - 扩展方法的c#程序中的未知错误和逻辑错误
- java - 为什么Optional isPresent类方法以Consumer为参数,而不是Consumer
?