首頁 > 軟體

unified如何處理markdown解析器詳解

2023-01-28 18:02:58

unified是什麼

unified是用於檔案處理的生態系統,核心包提供了檔案處理的流程控制,具體功能由生態系統中各個外掛提供。例如我們如果需要處理markdown,就需要使用markdown處理相關的外掛。當然除了markdwon以外,還提供了處理HTML、JSX等的外掛。其良好的擴充套件能力能讓我們很方便的在解析檔案過程中新增各種新功能。

如果我們遇到了需要處理markdown檔案、markdown轉HTML、HTML轉markdown等操作,那麼可以嘗試使用unified來作為解析器。

unified生態簡介

上面說到unified除了用於解析markdown外,還有各種各樣的外掛用於不同型別的檔案解析。

unified主要有以下四個生態系統:

每個生態系統下面都有用於處理各自檔案型別的外掛,以remark生態來說,如常用有以下外掛:

  • remark-parse - 用於將markdown字串轉換為語法樹。通常來講處理markdown都會首先用到這個外掛,後續的外掛會根據業務場景增刪或替換語法樹內容。
  • remark-stringify - 用於將markdown語法樹轉換為markdown字串,是remark-parse的逆過程,經過處理後的語法樹可通過該外掛恢復成為markdown輸出。
  • remark-frontmatter - 用於處理markdown的‘元資訊’,frontmatter是一種在檔案頭部用於備註元資訊的格式,通常我們用於設定該markdown的基本屬性如標題、作者、標籤等,這個外掛可以幫助我們提取這些資訊並轉成結構化物件。

工作原理

unified工作流程由三個階段組成:

| ............................... process ....................................... |
| .......... 解析(parse) ... | ... 處理(run) ... | ... 序列化(stringify) ..........|
                  +--------+                     +----------+
        Input ->- | Parser | ->- Syntax Tree ->- | Compiler | ->- Output
                  +--------+          |          +----------+
                                      X
                                      |
                               +--------------+
                               | Transformers |
                               +--------------+

Parse

該階段用於將Markdown, HTML, 或其他格式檔案轉換為抽象語法樹(AST),基於語法樹可以讓程式更容易處理非結構化檔案。常用的語法樹有以下幾種

remark-parse外掛就是在該階段工作。

Transform

該階段用於根據業務場景處理AST,是整個流程的核心階段,生態中大部分外掛及我們自定義的外掛大都執行在這個階段。當然這個階段是可選的,沒有這個階段也能執行,但是沒有太大意義。remark-frontmatter外掛就是在這個階段工作。

還有一類稱為橋接(Bridge)的外掛也是執行在這個階段,這類外掛用於不同結構的AST相互轉換。例如我們需要將處理後的Markdown轉換為HTML,就需要將mdast轉換為hast,常見的幾種Bridge外掛有:

Stringify

該階段用於將AST序列化為字串輸出。 remark-stringify外掛就是在這個階段工作。

牛刀小試

環境搭建

安裝依賴

npm install unified remark-parse remark-stringify remark-frontmatter js-yaml

編寫執行程式碼

// index.js
const unified = require('unified')
console.log(unified)

執行

node index.js

報錯

處理ESM型別包

由於unified使用的是ESM方式打包,而我們通常寫的node程式碼用CommonJS方式在這裡是無法正常執行的,所以我們需要使用ESM的方式來編寫執行程式碼。

  • 首先將index.js改名為index.mjs(使用package.json設定也行,這裡不舉例了)
  • 將引入方式改為ESM的import
// index.mjs
// 由於unified沒有匯出default,這裡要用{}括起來
import { unified } from 'unified'
console.log(unified)
  • 執行
node index.mjs

可以看到已經可以正常執行,基本執行環境就完成了。

最簡用法

修改執行檔案

import { unified } from 'unified'
import remarkParse from 'remark-parse'
import remarkStringify from 'remark-stringify'
// 初始化一個unified解析器
const res = unified()
    // 使用Markdown解析器將文字轉為AST
    .use(remarkParse)
    // 將MarkdownAST轉為字串
    .use(remarkStringify)
    // 開始同步執行解析
    .processSync('# hello unified')
console.log(res)

這個例子僅是最基礎的執行沒有什麼實際功能,執行結果:

載入檔案meta

import { unified } from 'unified'
import remarkParse from 'remark-parse'
import remarkFrontmatter from 'remark-frontmatter'
import remarkStringify from 'remark-stringify'
import yaml from 'js-yaml'
const res = unified()
    .use(remarkParse)
    // 新增解析yaml的外掛,會將具有yaml塊標誌(預設為---)的檔案塊解析成為yaml型別節點,
    .use(remarkFrontmatter, ['yaml'])
    // 新增一個自定義外掛來處理yaml型別節點
    .use(() => (tree, vFile) => {
        console.log(tree)
        // unist-util-visit 提供了更多便捷存取AST的工具,這裡我們先簡單獲取
        const node = tree.children.find(n => n.type == 'yaml')
        if(node) {
            // 使用yaml解析器解析yaml格式字串
            const meta = yaml.load(node.value)
            // { title: 'I AM TITLE', tags: [ 'unified', 'good' ] }
            console.log(meta)
            // 賦值到該檔案的解析資料中返回給外部使用
            vFile.data.meta = meta
        }
    })
    .use(remarkStringify)
    .processSync(`---
title: I AM TITLE
tags:
    - unified
    - good
---
# hello unified'
`)
console.log(res)

從列印結果可以看到,經過remark-frontmatter處理後,被---標誌包含的檔案塊被轉換成了yaml型別的節點,我們就可以方便的基於這個節點來解析資料了。

同時我們還自定義了一個簡易的外掛,用於處理yaml型別的節點,最終結果如下所示,已經正確提取出出來Markdown中的自定義屬性資料:

一個實際使用例子:

dumi - 為元件研發而生的靜態站點框架

該專案使用了unified來將markdown轉換為react-jsx,markdown用於寫元件說明檔案,jsx用於渲染為網站。其中除了使用unified生態的部分外掛外,dumi還實現了許多自定義的功能外掛用於擴充套件markdown的語法。

本章後續將逐一拆解相關程式碼,深入學習unified外掛開發及實戰運用,更多關於unified處理markdown解析器的資料請關注it145.com其它相關文章!

以上就是unified如何處理markdown解析器詳解的詳細內容,更多關於unified處理markdown解析器的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com