Skip to content

如何构建一颗语法树

🕒 Published at:

原文链接:https://unifiedjs.com/learn/recipe/build-a-syntax-tree/

当添加或者替换内容时,构建一颗新的语法树往往非常实用。使用纯对象和数组字面量(JSON) 或者用一个小工具编程来创建树,是可行的方案。甚至可以使用 JSX 来构建树。

JSON

创建树最基本的方法是使用纯对象和数组。为了避免类型问题,可以使用给定语法树语言的类型进行检查,在 mdast 的案例:

typescript
import type { Root } from 'mdast'

// Note the `: Root` is a TypeScript annotation. Remove it (and the import) for plain JavaScript.
const mdast: Root = {
  type: 'root',
  children: [
    {
      type: 'paragraph',
      children: [
        {
          type: 'text',
          value: 'example'
        }
      ]
    }
  ]
}

unist-builder

也可以使用 unist-builder 来构建树。它会使之更加简洁,类 "hyperscript" 的语法(也同样与 React.createElement 类似):

typescript
import { u } from 'unist-builder'

const mdast = u('root', [
  u('paragraph', [
    u('text', 'example')
  ])
])

hastscript

当使用 hast (HTML) 时,可以使用 hastscript

typescript
import { h, s } from 'hastscript'

console.log(
  h('div#some-id.foo', [
    h('span', 'some text'),
    h('input', {type: 'text', value: 'foo'}),
    h('a.alpha.bravo.charlie', {download: true}, 'delta')
  ])
)

// SVG:
console.log(
  s('svg', {xmlns: 'http://www.w3.org/2000/svg', viewbox: '0 0 500 500'}, [
    s('title', 'SVG `<circle>` element'),
    s('circle', {cx: 120, cy: 120, r: 100})
  ])
)

hastscript 也可以用作 JSX 配置注释:

jsx
/** @jsx h @jsxFrag null */
import { h } from 'hastscript'

console.log(
  <form method="POST">
    <input type="text" name="foo" />
    <input type="text" name="bar" />
    <input type="submit" name="send" />
  </form>
)

xastscript

当使用 xast (XML) 时,可以使用 xastscript

typescript
import { x } from 'xastscript'

console.log(
  x('album', {id: 123}, [
    x('name', 'Exile in Guyville'),
    x('artist', 'Liz Phair'),
    x('releasedate', '1993-06-22')
  ])
)

xastscript 也可以用作 JSX 配置注释:

jsx
/** @jsx x @jsxFrag null */
import { x } from 'xastscript'

console.log(
  <album id={123}>
    <name>Born in the U.S.A.</name>
    <artist>Bruce Springsteen</artist>
    <releasedate>1984-04-06</releasedate>
  </album>
)