备注: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 标签,块级支持打开和关闭标签匹配。 prescriptstyletextarea,后者最近才在规范的 v0.30 中添加。

您可以阅读规范的上述链接部分,并搜索 CommonMark forum 中的讨论以更深入地了解原因,但要切中要点,请阅读:

第二:你能做些什么

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

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

但是学习如何执行此操作并快速了解实现的最佳方法是查看 many existing mdast-specific manipulators