npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

jc-marked

v0.0.2

Published

Markdown AST (Abstract syntax tree) parser based on finite-state machine (FSM).

Downloads

3

Readme

jc-marked

中文 | English

<b>bref</b>

#title JC Marked ##title FSM for Markdown Syntex Parsing and extension #author "Jack Lee" "[email protected]" "https://blog.csdn.net/qq_28550263?spm=1001.2101.3001.5343" "17670845663" #last 《暂无上一篇文章》 #next 《暂无下一篇文章》 #summary jc-marked 是一个基于 FSM 的,用于扩展和解析 Markdown 为 AST(抽象语法树)的插件。


1. 简介

jc-marked 是一个基于 FSM 的,用于扩展和解析 Markdown 为 AST(抽象语法树)的插件。

2.安装

# use npm
npm install jc-marked
# use yarn
yarn add jc-marked
# use pnpm
pnpm install jc-marked

3. 编写解析程序

jc-marked 对外暴露 Loader、Tree 两个FSM,都可以对文本进行解析,但是 Loader 并不会将文本解析成一棵真正的语法树,它只

import { Loader } from 'jc-marked';
import { text } from './markdown.ts'; // 假定 text 是一个保存markdown文本的字符串 

cosnt machine = new Loader()
const lines = text.split("\n");

// 将文本逐行作为输入喂给状态机进行处理
for (let index = 0; index < lines.length; index++) {
  machine.push(lines[index]);
}

// 通过 getter nodes 获取解析后的节点集
cosnt res = machine.nodes;

这些节点可以比较方便地用于不关系文章层次结构地场景,只是将各个结构模块的位置初步归纳了出来,其解析速度相对快一些。

进一步地,Tree 对象是一个递归状态机,它将不同章节的内容放置在了相应的树枝下。其解析速度会略为慢一些。

import { Tree } from 'jc-marked';

const machine = new Tree(text);
machine.run()

const lines = machine.lines;  // 获取文本行数组
const nodes = machine.nodes;  // 与 Loader 实例的 getter nodes 返回的结果一样
const tree = machine.tree;    // 获取文章 AST(不含元数据,因为这很多情况下与 UI 渲染无关)
const infos = machine.infos;  // 获取文章元数据
const res = machine.res;      // 获取 { tree, infos }

4. 元数据扩展语法

4.1 什么是元数据

元数据用于描述一篇文章的作者与关联信息。包括 一级标题、二级标题、作者信息、上一篇文章、下一篇文章、本文概述。

4.2 元数据语法

1.标题

标题元数据包括一级标题元数据 和 二级标题元数据。其语法格式为:

#title 一级标题文本值
##title 二级标题文本值

2.作者信息

作者信息使用一个#author标记,包括作者名、电子邮箱地址、主页地址、手机号。一个完整的作者信息元数据描述格式示范如下:

#author "Jack Lee" "[email protected]" "https://blog.csdn.net/qq_28550263?spm=1001.2101.3001.5343" "17670845663"

3.上下文元数据

上下文元数据用于表示一篇文章处于某个文集中的前后文关系,包括上一篇文章和下一篇文章。他们的语法格式分别为:

#last [上一篇文章的标题](上一篇文章的地址)
#next [下一篇文章的标题](下一篇文章的地址)

4.文章总结元数据

文章总结用于描述文章的大概信息,向读者介绍文章的主旨内容等等。其语法格式为:

#summary 介绍文字

5. 信息块拓展语法

信息块拓展语法用于以一种更加明确的方式提示相关信息,例如:

::info 这个是 info 的标题 这是一个 warn 级别的 information 框,用于提示一些信息。 这是一个 warn 级别的 information 框,用于提示一些信息。 ::

::info 也可以没有标题 ::

::debug 这个是 debug 的标题 这是一个 warn 级别的 information 框,用于提示一些信息。 这是一个 warn 级别的 information 框,用于提示一些信息。 ::

::debug 也可以没有标题 ::

::warn 这个是 warn 的标题 这是一个 warn 级别的 information 框,用于提示一些信息。 这是一个 warn 级别的 information 框,用于提示一些信息。 ::

::warn 也可以没有标题 ::

::error 这个是 error 的标题 这是一个 error 级别的 information 框,用于提示一些信息。 这是一个 error 级别的 information 框,用于提示一些信息。 ::

::error 也可以没有标题 ::

::fatal 这个是 fatal 的标题 这是一个 error 级别的 information 框,用于提示一些信息。 这是一个 error 级别的 information 框,用于提示一些信息。 ::

::fatal 也可以没有标题 ::

6. 代码块用法与代码组扩展语法

6.1 代码块

在 Markdown 中,我们一般使用 "```语言名" 语法来表示一个代码块,例如:

\`\`\`javascript
// 注释文字
console.log("Hello World!")
\`\`\`

其效果为:

// 注释文字
console.log("Hello World!")

6.2 代码组

代码组是若干个代码块的集合,用于更方便地切换比较代码块。例如:

::: code-group

\`\`\`js [config.js]
/**
 * @type {import('vitepress').UserConfig}
 */
const config = {
  // ...
}

export default config
\`\`\`

\`\`\`ts [config.ts]
import type { UserConfig } from 'vitepress'

const config: UserConfig = {
  // ...
}

export default config
\`\`\`

:::

其效果为:

::: code-group

/**
 * @type {import('vitepress').UserConfig}
 */
const config = {
  // ...
}

export default config
import type { UserConfig } from 'vitepress'

const config: UserConfig = {
  // ...
}

export default config

:::

7. 公式块语法

$$ A_1^2 \ B_{12} \ 2^{x^2+y} $$

$$ \frac{x}{1+x^2} \ \frac{\frac{1}{2}+x}{y} \ \tfrac{a}{b} \frac{a}{b} $$

8. 表格

|第一列|第二列|第三列| :-|:-|:- 1-1|1-2|1-3 2-1|2-2|2-3 3-1|3-2|3-3

表格是可编辑的。

9. 美人鱼图表

几乎当代 Markdown 编辑器都会支持 美人鱼图表 拓展。你参考本节地例子去描述一个美人鱼图表。

例1

\`\`\`mermaid
graph LR
A[长方形] -- 链接 --> B((圆))
A --> C(圆角长方形)
B --> D{菱形}
C --> D
\`\`\`

其效果如下:

graph LR
A[长方形] -- 链接 --> B((圆))
A --> C(圆角长方形)
B --> D{菱形}
C --> D

例2

\`\`\`mermaid
pie showData
    title Key elements in Product X
    "Calcium" : 42.96
    "Potassium" : 50.05
    "Magnesium" : 10.01
    "Iron" :  5
\`\`\`

其效果如下:

pie showData
    title Key elements in Product X
    "Calcium" : 42.96
    "Potassium" : 50.05
    "Magnesium" : 10.01
    "Iron" :  5

例3

\`\`\`mermaid
gitGraph
commit
commit id: "Normal" tag: "v1.0.0"
commit
commit id: "Reverse" type: REVERSE tag: "RC_1"
commit
commit id: "Highlight" type: HIGHLIGHT tag: "8.8.4"
commit
\`\`\`

其效果如下:

gitGraph
commit
commit id: "Normal" tag: "v1.0.0"
commit
commit id: "Reverse" type: REVERSE tag: "RC_1"
commit
commit id: "Highlight" type: HIGHLIGHT tag: "8.8.4"
commit

例4

\`\`\`mermaid
flowchart TD
    A[Start] --> B{Is it?}
    B -->|Yes| C[OK]
    C --> D[Rethink]
    D --> B
    B ---->|No| E[End]
\`\`\`

其效果如下:

flowchart TD
    A[Start] --> B{Is it?}
    B -->|Yes| C[OK]
    C --> D[Rethink]
    D --> B
    B ---->|No| E[End]

例5

\`\`\`mermaid
flowchart TB
    c1-->a2
    subgraph one
    a1-->a2
    end
    subgraph two
    b1-->b2
    end
    subgraph three
    c1-->c2
    end
\`\`\`

其效果如下:

flowchart TB
    c1-->a2
    subgraph one
    a1-->a2
    end
    subgraph two
    b1-->b2
    end
    subgraph three
    c1-->c2
    end

例6

\`\`\`mermaid
flowchart LR
    id1(Start)-->id2(Stop)
    style id1 fill:#f9f,stroke:#333,stroke-width:4px
    style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5

\`\`\`

其效果如下:

flowchart LR
    id1(Start)-->id2(Stop)
    style id1 fill:#f9f,stroke:#333,stroke-width:4px
    style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5

例7

\`\`\`mermaid
flowchart LR
    A:::someclass --> B
    classDef someclass fill:#f96

\`\`\`

其效果如下:

flowchart LR
    A:::someclass --> B
    classDef someclass fill:#f96

例8

\`\`\`mermaid
mindmap
  root((mindmap))
    Origins
      Long history
      ::icon(fa fa-book)
      Popularisation
        British popular psychology author Tony Buzan
    Research
      On effectiveness<br/>and features
      On Automatic creation
        Uses
            Creative techniques
            Strategic planning
            Argument mapping
    Tools
      Pen and paper
      Mermaid
\`\`\`

其效果如下:

mindmap
  root((mindmap))
    Origins
      Long history
      ::icon(fa fa-book)
      Popularisation
        British popular psychology author Tony Buzan
    Research
      On effectiveness<br/>and features
      On Automatic creation
        Uses
            Creative techniques
            Strategic planning
            Argument mapping
    Tools
      Pen and paper
      Mermaid

例9

\`\`\`mermaid
sequenceDiagram
    actor Alice
    actor Bob
    Alice->>Bob: Hi Bob
    Bob->>Alice: Hi Alice
\`\`\`

其效果如下:

sequenceDiagram
    actor Alice
    actor Bob
    Alice->>Bob: Hi Bob
    Bob->>Alice: Hi Alice

例10

\`\`\`mermaid
sequenceDiagram
box Purple Alice & John
participant A
participant J
end
box Another Group
participant B
participant C
end
A->>J: Hello John, how are you?
J->>A: Great!
A->>B: Hello Bob, how is Charly ?
B->>C: Hello Charly, how are you?

\`\`\`

其效果如下:

sequenceDiagram
box Purple Alice & John
participant A
participant J
end
box Another Group
participant B
participant C
end
A->>J: Hello John, how are you?
J->>A: Great!
A->>B: Hello Bob, how is Charly ?
B->>C: Hello Charly, how are you?

例11

\`\`\`mermaid
timeline
    title History of Social Media Platform
    2002 : LinkedIn
    2004 : Facebook
         : Google
    2005 : Youtube
    2006 : Twitter
\`\`\`

其效果如下:

timeline
    title History of Social Media Platform
    2002 : LinkedIn
    2004 : Facebook
         : Google
    2005 : Youtube
    2006 : Twitter

例12

\`\`\`mermaid
sequenceDiagram
    Alice->John: Hello John, how are you?
    Note over Alice,John: A typical interaction
\`\`\`

其效果如下:

sequenceDiagram
    Alice->John: Hello John, how are you?
    Note over Alice,John: A typical interaction

例13

\`\`\`mermaid
sequenceDiagram
    participant web as Web Browser
    participant blog as Blog Service
    participant account as Account Service
    participant mail as Mail Service
    participant db as Storage

    Note over web,db: The user must be logged in to submit blog posts
    web->>+account: Logs in using credentials
    account->>db: Query stored accounts
    db->>account: Respond with query result

    alt Credentials not found
        account->>web: Invalid credentials
    else Credentials found
        account->>-web: Successfully logged in

        Note over web,db: When the user is authenticated, they can now submit new posts
        web->>+blog: Submit new post
        blog->>db: Store post data

        par Notifications
            blog--)mail: Send mail to blog subscribers
            blog--)db: Store in-site notifications
        and Response
            blog-->>-web: Successfully posted
        end
    end
\`\`\`

其效果如下:

sequenceDiagram
    participant web as Web Browser
    participant blog as Blog Service
    participant account as Account Service
    participant mail as Mail Service
    participant db as Storage

    Note over web,db: The user must be logged in to submit blog posts
    web->>+account: Logs in using credentials
    account->>db: Query stored accounts
    db->>account: Respond with query result

    alt Credentials not found
        account->>web: Invalid credentials
    else Credentials found
        account->>-web: Successfully logged in

        Note over web,db: When the user is authenticated, they can now submit new posts
        web->>+blog: Submit new post
        blog->>db: Store post data

        par Notifications
            blog--)mail: Send mail to blog subscribers
            blog--)db: Store in-site notifications
        and Response
            blog-->>-web: Successfully posted
        end
    end

例14

\`\`\`mermaid
---
title: Animal example
---
classDiagram
    note "From Duck till Zebra"
    Animal <|-- Duck
    note for Duck "can fly
can swim
can dive
can help in debugging"
    Animal <|-- Fish
    Animal <|-- Zebra
    Animal : +int age
    Animal : +String gender
    Animal: +isMammal()
    Animal: +mate()
    class Duck{
        +String beakColor
        +swim()
        +quack()
    }
    class Fish{
        -int sizeInFeet
        -canEat()
    }
    class Zebra{
        +bool is_wild
        +run()
    }

\`\`\`

其效果如下:

---
title: Animal example
---
classDiagram
    note "From Duck till Zebra"
    Animal <|-- Duck
    note for Duck "can fly
can swim
can dive
can help in debugging"
    Animal <|-- Fish
    Animal <|-- Zebra
    Animal : +int age
    Animal : +String gender
    Animal: +isMammal()
    Animal: +mate()
    class Duck{
        +String beakColor
        +swim()
        +quack()
    }
    class Fish{
        -int sizeInFeet
        -canEat()
    }
    class Zebra{
        +bool is_wild
        +run()
    }

例15

\`\`\`mermaid
classDiagram
classA --|> classB : Inheritance
classC --* classD : Composition
classE --o classF : Aggregation
classG --> classH : Association
classI -- classJ : Link(Solid)
classK ..> classL : Dependency
classM ..|> classN : Realization
classO .. classP : Link(Dashed)
\`\`\`

其效果如下:

classDiagram
classA --|> classB : Inheritance
classC --* classD : Composition
classE --o classF : Aggregation
classG --> classH : Association
classI -- classJ : Link(Solid)
classK ..> classL : Dependency
classM ..|> classN : Realization
classO .. classP : Link(Dashed)

例16

\`\`\`mermaid
stateDiagram-v2
    [*] --> First
    First --> Second
    First --> Third

    state First {
        [*] --> fir
        fir --> [*]
    }
    state Second {
        [*] --> sec
        sec --> [*]
    }
    state Third {
        [*] --> thi
        thi --> [*]
    }
\`\`\`

其效果如下:

stateDiagram-v2
    [*] --> First
    First --> Second
    First --> Third

    state First {
        [*] --> fir
        fir --> [*]
    }
    state Second {
        [*] --> sec
        sec --> [*]
    }
    state Third {
        [*] --> thi
        thi --> [*]
    }

例17

\`\`\`mermaid
erDiagram
    CUSTOMER ||--o{ ORDER : places
    CUSTOMER {
        string name
        string custNumber
        string sector
    }
    ORDER ||--|{ LINE-ITEM : contains
    ORDER {
        int orderNumber
        string deliveryAddress
    }
    LINE-ITEM {
        string productCode
        int quantity
        float pricePerUnit
    }
\`\`\`

其效果如下:

erDiagram
    CUSTOMER ||--o{ ORDER : places
    CUSTOMER {
        string name
        string custNumber
        string sector
    }
    ORDER ||--|{ LINE-ITEM : contains
    ORDER {
        int orderNumber
        string deliveryAddress
    }
    LINE-ITEM {
        string productCode
        int quantity
        float pricePerUnit
    }

例18

\`\`\`mermaid
erDiagram
    CAR ||--o{ NAMED-DRIVER : allows
    CAR {
        string registrationNumber PK
        string make
        string model
        string[] parts
    }
    PERSON ||--o{ NAMED-DRIVER : is
    PERSON {
        string driversLicense PK "The license #"
        string(99) firstName "Only 99 characters are allowed"
        string lastName
        string phone UK
        int age
    }
    NAMED-DRIVER {
        string carRegistrationNumber PK, FK
        string driverLicence PK, FK
    }
    MANUFACTURER only one to zero or more CAR : makes
\`\`\`

其效果如下:

erDiagram
    CAR ||--o{ NAMED-DRIVER : allows
    CAR {
        string registrationNumber PK
        string make
        string model
        string[] parts
    }
    PERSON ||--o{ NAMED-DRIVER : is
    PERSON {
        string driversLicense PK "The license #"
        string(99) firstName "Only 99 characters are allowed"
        string lastName
        string phone UK
        int age
    }
    NAMED-DRIVER {
        string carRegistrationNumber PK, FK
        string driverLicence PK, FK
    }
    MANUFACTURER only one to zero or more CAR : makes

例19

\`\`\`mermaid
journey
    title My working day
    section Go to work
      Make tea: 5: Me
      Go upstairs: 3: Me
      Do work: 1: Me, Cat
    section Go home
      Go downstairs: 5: Me
      Sit down: 5: Me
\`\`\`

其效果如下:

journey
    title My working day
    section Go to work
      Make tea: 5: Me
      Go upstairs: 3: Me
      Do work: 1: Me, Cat
    section Go home
      Go downstairs: 5: Me
      Sit down: 5: Me

例20

\`\`\`mermaid
gantt
    dateFormat  YYYY-MM-DD
    title       Adding GANTT diagram functionality to mermaid
    excludes    weekends
    %% (`excludes` accepts specific dates in YYYY-MM-DD format, days of the week ("sunday") or "weekends", but not the word "weekdays".)

    section A section
    Completed task            :done,    des1, 2014-01-06,2014-01-08
    Active task               :active,  des2, 2014-01-09, 3d
    Future task               :         des3, after des2, 5d
    Future task2              :         des4, after des3, 5d

    section Critical tasks
    Completed task in the critical line :crit, done, 2014-01-06,24h
    Implement parser and jison          :crit, done, after des1, 2d
    Create tests for parser             :crit, active, 3d
    Future task in critical line        :crit, 5d
    Create tests for renderer           :2d
    Add to mermaid                      :1d
    Functionality added                 :milestone, 2014-01-25, 0d

    section Documentation
    Describe gantt syntax               :active, a1, after des1, 3d
    Add gantt diagram to demo page      :after a1  , 20h
    Add another diagram to demo page    :doc1, after a1  , 48h

    section Last section
    Describe gantt syntax               :after doc1, 3d
    Add gantt diagram to demo page      :20h
    Add another diagram to demo page    :48h
\`\`\`

其效果如下:

gantt
    dateFormat  YYYY-MM-DD
    title       Adding GANTT diagram functionality to mermaid
    excludes    weekends
    %% (`excludes` accepts specific dates in YYYY-MM-DD format, days of the week ("sunday") or "weekends", but not the word "weekdays".)

    section A section
    Completed task            :done,    des1, 2014-01-06,2014-01-08
    Active task               :active,  des2, 2014-01-09, 3d
    Future task               :         des3, after des2, 5d
    Future task2              :         des4, after des3, 5d

    section Critical tasks
    Completed task in the critical line :crit, done, 2014-01-06,24h
    Implement parser and jison          :crit, done, after des1, 2d
    Create tests for parser             :crit, active, 3d
    Future task in critical line        :crit, 5d
    Create tests for renderer           :2d
    Add to mermaid                      :1d
    Functionality added                 :milestone, 2014-01-25, 0d

    section Documentation
    Describe gantt syntax               :active, a1, after des1, 3d
    Add gantt diagram to demo page      :after a1  , 20h
    Add another diagram to demo page    :doc1, after a1  , 48h

    section Last section
    Describe gantt syntax               :after doc1, 3d
    Add gantt diagram to demo page      :20h
    Add another diagram to demo page    :48h

10 echarts 图表

美人鱼图表确实很棒,不过我们试图寻找比美人鱼更美观、使用起来也更加方便地替代方式,那就是 chart 语法:

::chart
line{
  "title":"线图",
  "xlable":"x轴标签",
  "ylable":"y轴标签",
  "graid":true,
  "smooth":false,
  "y":{
    type:"value",
    "data":[
      {"name":"y1", "data": [120, 132, 101, 134, 90, 230, 210]},
      {"name":"y2", "data": [220, 182, 191, 234, 290, 330, 310]},
      {"name":"y3", "data": [150, 232, 201, 154, 190, 330, 410]},
      {"name":"y4", "data": [320, 332, 301, 334, 390, 330, 320]},
      {"name":"y5", "data": [820, 932, 901, 934, 1290, 1330, 1320]}
    ]
  },
  "x":{
    "type":"category",
    "data": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
  }
}
::

其效果如下:

::chart line{ "title":"线图", "xlable":"x轴标签", "ylable":"y轴标签", "graid":true, "smooth":false, "y":{ "type":"value", "data":[ {"name":"y1", "data": [120, 132, 101, 134, 90, 230, 210]}, {"name":"y2", "data": [220, 182, 191, 234, 290, 330, 310]}, {"name":"y3", "data": [150, 232, 201, 154, 190, 330, 410]}, {"name":"y4", "data": [320, 332, 301, 334, 390, 330, 320]}, {"name":"y5", "data": [820, 932, 901, 934, 1290, 1330, 1320]} ] }, "x":{ "type":"category", "data": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"] } } ::

附录

为了向读者更清楚的表达 getter nodes、tree 的区别,这里给出文本的 nodes 和 tree。以下结果均不包含附录部分。

附录1 - 本文 nodes

[
  { "type": "meta", "index": 0 },
  { "type": "meta", "index": 1 },
  { "type": "meta", "index": 2 },
  { "type": "meta", "index": 3 },
  { "type": "meta", "index": 4 },
  { "type": "meta", "index": 5 },
  { "type": "text", "from": 6, "to": 6 },
  { "type": "breakLine", "index": 7 },
  { "type": "text", "from": 8, "to": 8 },
  { "type": "title", "index": 9 },
  { "type": "text", "from": 10, "to": 12 },
  { "type": "title", "index": 13 },
  { "type": "text", "from": 14, "to": 14 },
  { "type": "code", "from": 15, "to": 22 },
  { "type": "text", "from": 23, "to": 24 },
  { "type": "title", "index": 25 },
  { "type": "text", "from": 26, "to": 28 },
  { "type": "code", "from": 29, "to": 43 },
  { "type": "text", "from": 44, "to": 48 },
  { "type": "code", "from": 49, "to": 60 },
  { "type": "text", "from": 61, "to": 61 },
  { "type": "title", "index": 62 },
  { "type": "text", "from": 63, "to": 63 },
  { "type": "title", "index": 64 },
  { "type": "text", "from": 65, "to": 67 },
  { "type": "title", "index": 68 },
  { "type": "text", "from": 69, "to": 69 },
  { "type": "title", "index": 70 },
  { "type": "text", "from": 71, "to": 73 },
  { "type": "code", "from": 74, "to": 77 },
  { "type": "text", "from": 78, "to": 78 },
  { "type": "title", "index": 79 },
  { "type": "text", "from": 80, "to": 82 },
  { "type": "code", "from": 83, "to": 85 },
  { "type": "text", "from": 86, "to": 86 },
  { "type": "title", "index": 87 },
  { "type": "text", "from": 88, "to": 90 },
  { "type": "code", "from": 91, "to": 94 },
  { "type": "text", "from": 95, "to": 95 },
  { "type": "title", "index": 96 },
  { "type": "text", "from": 97, "to": 99 },
  { "type": "code", "from": 100, "to": 102 },
  { "type": "text", "from": 103, "to": 104 },
  { "type": "title", "index": 105 },
  { "type": "text", "from": 106, "to": 109 },
  { "type": "info", "from": 110, "to": 115 },
  { "type": "text", "from": 116, "to": 116 },
  { "type": "info", "from": 117, "to": 119 },
  { "type": "text", "from": 120, "to": 120 },
  { "type": "info", "from": 121, "to": 126 },
  { "type": "text", "from": 127, "to": 127 },
  { "type": "info", "from": 128, "to": 130 },
  { "type": "text", "from": 131, "to": 131 },
  { "type": "info", "from": 132, "to": 137 },
  { "type": "text", "from": 138, "to": 138 },
  { "type": "info", "from": 139, "to": 141 },
  { "type": "text", "from": 142, "to": 143 },
  { "type": "info", "from": 144, "to": 149 },
  { "type": "text", "from": 150, "to": 150 },
  { "type": "info", "from": 151, "to": 153 },
  { "type": "text", "from": 154, "to": 154 },
  { "type": "info", "from": 155, "to": 160 },
  { "type": "text", "from": 161, "to": 161 },
  { "type": "info", "from": 162, "to": 164 },
  { "type": "text", "from": 165, "to": 165 },
  { "type": "title", "index": 166 },
  { "type": "text", "from": 167, "to": 167 },
  { "type": "title", "index": 168 },
  { "type": "text", "from": 169, "to": 171 },
  { "type": "code", "from": 172, "to": 177 },
  { "type": "text", "from": 178, "to": 180 },
  { "type": "code", "from": 181, "to": 184 },
  { "type": "text", "from": 185, "to": 185 },
  { "type": "title", "index": 186 },
  { "type": "text", "from": 187, "to": 189 },
  { "type": "code", "from": 190, "to": 216 },
  { "type": "text", "from": 217, "to": 219 },
  { "type": "code-group", "from": 220, "to": 243 },
  { "type": "text", "from": 244, "to": 244 },
  { "type": "title", "index": 245 },
  { "type": "text", "from": 246, "to": 246 },
  { "type": "math", "from": 247, "to": 253 },
  { "type": "text", "from": 254, "to": 254 },
  { "type": "math", "from": 255, "to": 262 },
  { "type": "text", "from": 263, "to": 264 },
  { "type": "title", "index": 265 },
  { "type": "text", "from": 266, "to": 266 },
  { "type": "table", "from": 267, "to": 271 },
  { "type": "text", "from": 272, "to": 274 },
  { "type": "title", "index": 275 },
  { "type": "text", "from": 276, "to": 278 },
  { "type": "title", "index": 279 },
  { "type": "text", "from": 280, "to": 280 },
  { "type": "code", "from": 281, "to": 289 },
  { "type": "text", "from": 290, "to": 292 },
  { "type": "code", "from": 293, "to": 299 },
  { "type": "text", "from": 300, "to": 300 },
  { "type": "title", "index": 301 },
  { "type": "text", "from": 302, "to": 302 },
  { "type": "code", "from": 303, "to": 312 },
  { "type": "text", "from": 313, "to": 315 },
  { "type": "code", "from": 316, "to": 323 },
  { "type": "text", "from": 324, "to": 324 },
  { "type": "title", "index": 325 },
  { "type": "text", "from": 326, "to": 326 },
  { "type": "code", "from": 327, "to": 338 },
  { "type": "text", "from": 339, "to": 341 },
  { "type": "code", "from": 342, "to": 351 },
  { "type": "text", "from": 352, "to": 352 },
  { "type": "title", "index": 353 },
  { "type": "text", "from": 354, "to": 354 },
  { "type": "code", "from": 355, "to": 364 },
  { "type": "text", "from": 365, "to": 367 },
  { "type": "code", "from": 368, "to": 375 },
  { "type": "text", "from": 376, "to": 376 },
  { "type": "title", "index": 377 },
  { "type": "text", "from": 378, "to": 378 },
  { "type": "code", "from": 379, "to": 393 },
  { "type": "text", "from": 394, "to": 396 },
  { "type": "code", "from": 397, "to": 409 },
  { "type": "text", "from": 410, "to": 410 },
  { "type": "title", "index": 411 },
  { "type": "text", "from": 412, "to": 412 },
  { "type": "code", "from": 413, "to": 421 },
  { "type": "text", "from": 422, "to": 424 },
  { "type": "code", "from": 425, "to": 431 },
  { "type": "text", "from": 432, "to": 433 },
  { "type": "title", "index": 434 },
  { "type": "text", "from": 435, "to": 435 },
  { "type": "code", "from": 436, "to": 443 },
  { "type": "text", "from": 444, "to": 446 },
  { "type": "code", "from": 447, "to": 451 },
  { "type": "text", "from": 452, "to": 452 },
  { "type": "title", "index": 453 },
  { "type": "text", "from": 454, "to": 454 },
  { "type": "code", "from": 455, "to": 475 },
  { "type": "text", "from": 476, "to": 478 },
  { "type": "code", "from": 479, "to": 497 },
  { "type": "text", "from": 498, "to": 498 },
  { "type": "title", "index": 499 },
  { "type": "text", "from": 500, "to": 500 },
  { "type": "code", "from": 501, "to": 509 },
  { "type": "text", "from": 510, "to": 512 },
  { "type": "code", "from": 513, "to": 519 },
  { "type": "text", "from": 520, "to": 520 },
  { "type": "title", "index": 521 },
  { "type": "text", "from": 522, "to": 522 },
  { "type": "code", "from": 523, "to": 540 },
  { "type": "text", "from": 541, "to": 543 },
  { "type": "code", "from": 544, "to": 558 },
  { "type": "text", "from": 559, "to": 559 },
  { "type": "title", "index": 560 },
  { "type": "text", "from": 561, "to": 561 },
  { "type": "code", "from": 562, "to": 572 },
  { "type": "text", "from": 573, "to": 575 },
  { "type": "code", "from": 576, "to": 584 },
  { "type": "text", "from": 585, "to": 585 },
  { "type": "title", "index": 586 },
  { "type": "text", "from": 587, "to": 587 },
  { "type": "code", "from": 588, "to": 594 },
  { "type": "text", "from": 595, "to": 597 },
  { "type": "code", "from": 598, "to": 602 },
  { "type": "text", "from": 603, "to": 604 },
  { "type": "title", "index": 605 },
  { "type": "text", "from": 606, "to": 606 },
  { "type": "code", "from": 607, "to": 638 },
  { "type": "text", "from": 639, "to": 641 },
  { "type": "code", "from": 642, "to": 671 },
  { "type": "text", "from": 672, "to": 673 },
  { "type": "title", "index": 674 },
  { "type": "text", "from": 675, "to": 675 },
  { "type": "code", "from": 676, "to": 709 },
  { "type": "text", "from": 710, "to": 712 },
  { "type": "code", "from": 713, "to": 744 },
  { "type": "text", "from": 745, "to": 746 },
  { "type": "title", "index": 747 },
  { "type": "text", "from": 748, "to": 748 },
  { "type": "code", "from": 749, "to": 761 },
  { "type": "text", "from": 762, "to": 764 },
  { "type": "code", "from": 765, "to": 775 },
  { "type": "text", "from": 776, "to": 776 },
  { "type": "title", "index": 777 },
  { "type": "text", "from": 778, "to": 778 },
  { "type": "code", "from": 779, "to": 799 },
  { "type": "text", "from": 800, "to": 802 },
  { "type": "code", "from": 803, "to": 821 },
  { "type": "text", "from": 822, "to": 823 },
  { "type": "title", "index": 824 },
  { "type": "text", "from": 825, "to": 825 },
  { "type": "code", "from": 826, "to": 846 },
  { "type": "text", "from": 847, "to": 849 },
  { "type": "code", "from": 850, "to": 868 },
  { "type": "text", "from": 869, "to": 870 },
  { "type": "title", "index": 871 },
  { "type": "text", "from": 872, "to": 872 },
  { "type": "code", "from": 873, "to": 897 },
  { "type": "text", "from": 898, "to": 900 },
  { "type": "code", "from": 901, "to": 923 },
  { "type": "text", "from": 924, "to": 926 },
  { "type": "title", "index": 927 },
  { "type": "text", "from": 928, "to": 928 },
  { "type": "code", "from": 929, "to": 941 },
  { "type": "text", "from": 942, "to": 944 },
  { "type": "code", "from": 945, "to": 955 },
  { "type": "text", "from": 956, "to": 956 },
  { "type": "title", "index": 957 },
  { "type": "text", "from": 958, "to": 958 },
  { "type": "code", "from": 959, "to": 992 },
  { "type": "text", "from": 993, "to": 995 },
  { "type": "code", "from": 996, "to": 1027 },
  { "type": "text", "from": 1028, "to": 1030 },
  { "type": "title", "index": 1031 },
  { "type": "text", "from": 1032, "to": 1034 },
  { "type": "code", "from": 1035, "to": 1059 },
  { "type": "text", "from": 1060, "to": 1062 },
  { "type": "chart", "from": 1063, "to": 1085 },
  { "type": "text", "from": 1086, "to": 1088 }
]

附录2 - 本文 tree

[
  { "type": "text", "from": 6, "to": 6 },
  { "type": "breakLine", "index": 7 },
  { "type": "text", "from": 8, "to": 8 },
  {
    "type": "title",
    "index": 1,
    "name": "1. 简介",
    "body": [{ "type": "text", "from": 10, "to": 12 }]
  },
  {
    "type": "title",
    "index": 2,
    "name": "2.安装",
    "body": [
      { "type": "text", "from": 14, "to": 14 },
      { "type": "code", "from": 15, "to": 22 },
      { "type": "text", "from": 23, "to": 24 }
    ]
  },
  {
    "type": "title",
    "index": 3,
    "name": "3. 编写解析程序",
    "body": [
      { "type": "text", "from": 26, "to": 28 },
      { "type": "code", "from": 29, "to": 43 },
      { "type": "text", "from": 44, "to": 48 },
      { "type": "code", "from": 49, "to": 60 },
      { "type": "text", "from": 61, "to": 61 }
    ]
  },
  {
    "type": "title",
    "index": 4,
    "name": "4. 元数据扩展语法",
    "body": [
      { "type": "text", "from": 63, "to": 63 },
      {
        "type": "title",
        "index": 1,
        "name": "4.1 什么是元数据",
        "body": [{ "type": "text", "from": 65, "to": 67 }]
      },
      {
        "type": "title",
        "index": 2,
        "name": "4.2 元数据语法",
        "body": [
          { "type": "text", "from": 69, "to": 69 },
          {
            "type": "title",
            "index": 1,
            "name": "1.标题",
            "body": [
              { "type": "text", "from": 71, "to": 73 },
              { "type": "code", "from": 74, "to": 77 },
              { "type": "text", "from": 78, "to": 78 }
            ]
          },
          {
            "type": "title",
            "index": 2,
            "name": "2.作者信息",
            "body": [
              { "type": "text", "from": 80, "to": 82 },
              { "type": "code", "from": 83, "to": 85 },
              { "type": "text", "from": 86, "to": 86 }
            ]
          },
          {
            "type": "title",
            "index": 3,
            "name": "3.上下文元数据",
            "body": [
              { "type": "text", "from": 88, "to": 90 },
              { "type": "code", "from": 91, "to": 94 },
              { "type": "text", "from": 95, "to": 95 }
            ]
          },
          {
            "type": "title",
            "index": 4,
            "name": "4.文章总结元数据",
            "body": [
              { "type": "text", "from": 97, "to": 99 },
              { "type": "code", "from": 100, "to": 102 },
              { "type": "text", "from": 103, "to": 104 }
            ]
          }
        ]
      }
    ]
  },
  {
    "type": "title",
    "index": 5,
    "name": "5. 信息块拓展语法",
    "body": [
      { "type": "text", "from": 106, "to": 109 },
      { "type": "info", "from": 110, "to": 115 },
      { "type": "text", "from": 116, "to": 116 },
      { "type": "info", "from": 117, "to": 119 },
      { "type": "text", "from": 120, "to": 120 },
      { "type": "info", "from": 121, "to": 126 },
      { "type": "text", "from": 127, "to": 127 },
      { "type": "info", "from": 128, "to": 130 },
      { "type": "text", "from": 131, "to": 131 },
      { "type": "info", "from": 132, "to": 137 },
      { "type": "text", "from": 138, "to": 138 },
      { "type": "info", "from": 139, "to": 141 },
      { "type": "text", "from": 142, "to": 143 },
      { "type": "info", "from": 144, "to": 149 },
      { "type": "text", "from": 150, "to": 150 },
      { "type": "info", "from": 151, "to": 153 },
      { "type": "text", "from": 154, "to": 154 },
      { "type": "info", "from": 155, "to": 160 },
      { "type": "text", "from": 161, "to": 161 },
      { "type": "info", "from": 162, "to": 164 },
      { "type": "text", "from": 165, "to": 165 }
    ]
  },
  {
    "type": "title",
    "index": 6,
    "name": "6. 代码块用法与代码组扩展语法",
    "body": [
      { "type": "text", "from": 167, "to": 167 },
      {
        "type": "title",
        "index": 1,
        "name": "6.1 代码块",
        "body": [
          { "type": "text", "from": 169, "to": 171 },
          { "type": "code", "from": 172, "to": 177 },
          { "type": "text", "from": 178, "to": 180 },
          { "type": "code", "from": 181, "to": 184 },
          { "type": "text", "from": 185, "to": 185 }
        ]
      },
      {
        "type": "title",
        "index": 2,
        "name": "6.2 代码组",
        "body": [
          { "type": "text", "from": 187, "to": 189 },
          { "type": "code", "from": 190, "to": 216 },
          { "type": "text", "from": 217, "to": 219 },
          { "type": "code-group", "from": 220, "to": 243 },
          { "type": "text", "from": 244, "to": 244 }
        ]
      }
    ]
  },
  {
    "type": "title",
    "index": 7,
    "name": "7. 公式块语法",
    "body": [
      { "type": "text", "from": 246, "to": 246 },
      { "type": "math", "from": 247, "to": 253 },
      { "type": "text", "from": 254, "to": 254 },
      { "type": "math", "from": 255, "to": 262 },
      { "type": "text", "from": 263, "to": 264 }
    ]
  },
  {
    "type": "title",
    "index": 8,
    "name": "8. 表格",
    "body": [
      { "type": "text", "from": 266, "to": 266 },
      { "type": "table", "from": 267, "to": 271 },
      { "type": "text", "from": 272, "to": 274 }
    ]
  },
  {
    "type": "title",
    "index": 9,
    "name": "9. 美人鱼图表",
    "body": [
      { "type": "text", "from": 276, "to": 278 },
      {
        "type": "title",
        "index": 1,
        "name": "例1",
        "body": [
          { "type": "text", "from": 280, "to": 280 },
          { "type": "code", "from": 281, "to": 289 },
          { "type": "text", "from": 290, "to": 292 },
          { "type": "code", "from": 293, "to": 299 },
          { "type": "text", "from": 300, "to": 300 }
        ]
      },
      {
        "type": "title",
        "index": 2,
        "name": "例2",
        "body": [
          { "type": "text", "from": 302, "to": 302 },
          { "type": "code", "from": 303, "to": 312 },
          { "type": "text", "from": 313, "to": 315 },
          { "type": "code", "from": 316, "to": 323 },
          { "type": "text", "from": 324, "to": 324 }
        ]
      },
      {
        "type": "title",
        "index": 3,
        "name": "例3",
        "body": [
          { "type": "text", "from": 326, "to": 326 },
          { "type": "code", "from": 327, "to": 338 },
          { "type": "text", "from": 339, "to": 341 },
          { "type": "code", "from": 342, "to": 351 },
          { "type": "text", "from": 352, "to": 352 }
        ]
      },
      {
        "type": "title",
        "index": 4,
        "name": "例4",
        "body": [
          { "type": "text", "from": 354, "to": 354 },
          { "type": "code", "from": 355, "to": 364 },
          { "type": "text", "from": 365, "to": 367 },
          { "type": "code", "from": 368, "to": 375 },
          { "type": "text", "from": 376, "to": 376 }
        ]
      },
      {
        "type": "title",
        "index": 5,
        "name": "例5",
        "body": [
          { "type": "text", "from": 378, "to": 378 },
          { "type": "code", "from": 379, "to": 393 },
          { "type": "text", "from": 394, "to": 396 },
          { "type": "code", "from": 397, "to": 409 },
          { "type": "text", "from": 410, "to": 410 }
        ]
      },
      {
        "type": "title",
        "index": 6,
        "name": "例6",
        "body": [
          { "type": "text", "from": 412, "to": 412 },
          { "type": "code", "from": 413, "to": 421 },
          { "type": "text", "from": 422, "to": 424 },
          { "type": "code", "from": 425, "to": 431 },
          { "type": "text", "from": 432, "to": 433 }
        ]
      },
      {
        "type": "title",
        "index": 7,
        "name": "例7",
        "body": [
          { "type": "text", "from": 435, "to": 435 },
          { "type": "code", "from": 436, "to": 443 },
          { "type": "text", "from": 444, "to": 446 },
          { "type": "code", "from": 447, "to": 451 },
          { "type": "text", "from": 452, "to": 452 }
        ]
      },
      {
        "type": "title",
        "index": 8,
        "name": "例8",
        "body": [
          { "type": "text", "from": 454, "to": 454 },
          { "type": "code", "from": 455, "to": 475 },
          { "type": "text", "from": 476, "to": 478 },
          { "type": "code", "from": 479, "to": 497 },
          { "type": "text", "from": 498, "to": 498 }
        ]
      },
      {
        "type": "title",
        "index": 9,
        "name": "例9",
        "body": [
          { "type": "text", "from": 500, "to": 500 },
          { "type": "code", "from": 501, "to": 509 },
          { "type": "text", "from": 510, "to": 512 },
          { "type": "code", "from": 513, "to": 519 },
          { "type": "text", "from": 520, "to": 520 }
        ]
      },
      {
        "type": "title",
        "index": 10,
        "name": "例10",
        "body": [
          { "type": "text", "from": 522, "to": 522 },
          { "type": "code", "from": 523, "to": 540 },
          { "type": "text", "from": 541, "to": 543 },
          { "type": "code", "from": 544, "to": 558 },
          { "type": "text", "from": 559, "to": 559 }
        ]
      },
      {
        "type": "title",
        "index": 11,
        "name": "例11",
        "body": [
          { "type": "text", "from": 561, "to": 561 },
          { "type": "code", "from": 562, "to": 572 },
          { "type": "text", "from": 573, "to": 575 },
          { "type": "code", "from": 576, "to": 584 },
          { "type": "text", "from": 585, "to": 585 }
        ]
      },
      {
        "type": "title",
        "index": 12,
        "name": "例12",
        "body": [
          { "type": "text", "from": 587, "to": 587 },
          { "type": "code", "from": 588, "to": 594 },
          { "type": "text", "from": 595, "to": 597 },
          { "type": "code", "from": 598, "to": 602 },
          { "type": "text", "from": 603, "to": 604 }
        ]
      },
      {
        "type": "title",
        "index": 13,
        "name": "例13",
        "body": [
          { "type": "text", "from": 606, "to": 606 },
          { "type": "code", "from": 607, "to": 638 },
          { "type": "text", "from": 639, "to": 641 },
          { "type": "code", "from": 642, "to": 671 },
          { "type": "text", "from": 672, "to": 673 }
        ]
      },
      {
        "type": "title",
        "index": 14,
        "name": "例14",
        "body": [
          { "type": "text", "from": 675, "to": 675 },
          { "type": "code", "from": 676, "to": 709 },
          { "type": "text", "from": 710, "to": 712 },
          { "type": "code", "from": 713, "to": 744 },
          { "type": "text", "from": 745, "to": 746 }
        ]
      },
      {
        "type": "title",
        "index": 15,
        "name": "例15",
        "body": [
          { "type": "text", "from": 748, "to": 748 },
          { "type": "code", "from": 749, "to": 761 },
          { "type": "text", "from": 762, "to": 764 },
          { "type": "code", "from": 765, "to": 775 },
          { "type": "text", "from": 776, "to": 776 }
        ]
      },
      {
        "type": "title",
        "index": 16,
        "name": "例16",
        "body": [
          { "type": "text", "from": 778, "to": 778 },
          { "type": "code", "from": 779, "to": 799 },
          { "type": "text", "from": 800, "to": 802 },
          { "type": "code", "from": 803, "to": 821 },
          { "type": "text", "from": 822, "to": 823 }
        ]
      },
      {
        "type": "title",
        "index": 17,
        "name": "例17",
        "body": [
          { "type": "text", "from": 825, "to": 825 },
          { "type": "code", "from": 826, "to": 846 },
          { "type": "text", "from": 847, "to": 849 },
          { "type": "code", "from": 850, "to": 868 },
          { "type": "text", "from": 869, "to": 870 }
        ]
      },
      {
        "type": "title",
        "index": 18,
        "name": "例18",
        "body": [
          { "type": "text", "from": 872, "to": 872 },
          { "type": "code", "from": 873, "to": 897 },
          { "type": "text", "from": 898, "to": 900 },
          { "type": "code", "from": 901, "to": 923 },
          { "type": "text", "from": 924, "to": 926 }
        ]
      },
      {
        "type": "title",
        "index": 19,
        "name": "例19",
        "body": [
          { "type": "text", "from": 928, "to": 928 },
          { "type": "code", "from": 929, "to": 941 },
          { "type": "text", "from": 942, "to": 944 },
          { "type": "code", "from": 945, "to": 955 },
          { "type": "text", "from": 956, "to": 956 },
          {
            "type": "title",
            "index": 1,
            "name": "例20",
            "body": [
              { "type": "text", "from": 958, "to": 958 },
              { "type": "code", "from": 959, "to": 992 },
              { "type": "text", "from": 993, "to": 995 },
              { "type": "code", "from": 996, "to": 1027 },
              { "type": "text", "from": 1028, "to": 1030 }
            ]
          }
        ]
      }
    ]
  },
  {
    "type": "title",
    "index": 10,
    "name": "10 echarts 图表",
    "body": [
      { "type": "text", "from": 1032, "to": 1034 },
      { "type": "code", "from": 1035, "to": 1059 },
      { "type": "text", "from": 1060, "to": 1062 },
      { "type": "chart", "from": 1063, "to": 1085 },
      { "type": "text", "from": 1086, "to": 1088 }
    ]
  }
]