1

我正在尝试使用UnifiedRemark-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 插件可以做到这一点?如果没有,我将如何创建一个这样做的插件?

谢谢。

4

1 回答 1

1

第一:为什么 AST 看起来像它一样,为什么 Remark 很可能没有选择不同的方法

AST 以这种方式表示它的原因是 CommonMark 规范为原始内联 HTMLHTML 块指定的内容。具体来说,CommonMark 指定HTML 标签是通过的,而不是被解析的。

对于内联 HTML,规范支持内联 HTML标签,这与支持内联 HTML不同。标签只是按原样传递。没有匹配的开始和结束标签。原因如下:

  • 表现
  • 解析器复杂度
  • 只有当 Markdown 没有您需要的功能时,HTML 标签才被支持作为“使用风险自负”“最后手段”选项。

对于少量的 HTML 标签,在块级别支持打开和关闭标签匹配。pre, script,styletextarea, 后者最近才在规范的 v0.30 中添加。

您可以阅读规范的上述链接部分,并在CommonMark 论坛中搜索讨论以更好地了解原因,但要直截了当,请阅读:

第二:你能做些什么

Remark 是“统一集合的一部分”,它是以处理 AST(抽象语法树)为中心的基础设施。从你的问题来看,听起来你已经明白了。

统一的页面上有很多关于如何编写插件的帮助:

但是,了解如何执行此操作并快速了解实现的最佳方法是查看许多现有的 mdast 特定操纵器

于 2021-06-23T14:06:30.723 回答