unified如何處理markdown解析器詳解
unified是什么
unified
是用于文檔處理的生態(tài)系統(tǒng),核心包提供了文檔處理的流程控制,具體功能由生態(tài)系統(tǒng)中各個(gè)插件提供。例如我們?nèi)绻枰幚韒arkdown,就需要使用markdown處理相關(guān)的插件。當(dāng)然除了markdwon以外,還提供了處理HTML、JSX等的插件。其良好的擴(kuò)展能力能讓我們很方便的在解析文檔過(guò)程中添加各種新功能。
如果我們遇到了需要處理markdown文檔、markdown轉(zhuǎn)HTML、HTML轉(zhuǎn)markdown等操作,那么可以嘗試使用unified來(lái)作為解析器。
unified生態(tài)簡(jiǎn)介
上面說(shuō)到unified除了用于解析markdown外,還有各種各樣的插件用于不同類型的文檔解析。
unified主要有以下四個(gè)生態(tài)系統(tǒng):
每個(gè)生態(tài)系統(tǒng)下面都有用于處理各自文檔類型的插件,以remark
生態(tài)來(lái)說(shuō),如常用有以下插件:
- remark-parse - 用于將markdown字符串轉(zhuǎn)換為語(yǔ)法樹。通常來(lái)講處理markdown都會(huì)首先用到這個(gè)插件,后續(xù)的插件會(huì)根據(jù)業(yè)務(wù)場(chǎng)景增刪或替換語(yǔ)法樹內(nèi)容。
- remark-stringify - 用于將markdown語(yǔ)法樹轉(zhuǎn)換為markdown字符串,是
remark-parse
的逆過(guò)程,經(jīng)過(guò)處理后的語(yǔ)法樹可通過(guò)該插件恢復(fù)成為markdown輸出。 - remark-frontmatter - 用于處理markdown的‘元信息’,
frontmatter
是一種在文檔頭部用于備注元信息的格式,通常我們用于配置該markdown的基本屬性如標(biāo)題、作者、標(biāo)簽等,這個(gè)插件可以幫助我們提取這些信息并轉(zhuǎn)成結(jié)構(gòu)化對(duì)象。
工作原理
unified
工作流程由三個(gè)階段組成:
| ............................... process ....................................... | | .......... 解析(parse) ... | ... 處理(run) ... | ... 序列化(stringify) ..........| +--------+ +----------+ Input ->- | Parser | ->- Syntax Tree ->- | Compiler | ->- Output +--------+ | +----------+ X | +--------------+ | Transformers | +--------------+
Parse
該階段用于將Markdown, HTML, 或其他格式文檔轉(zhuǎn)換為抽象語(yǔ)法樹(AST),基于語(yǔ)法樹可以讓程序更容易處理非結(jié)構(gòu)化文檔。常用的語(yǔ)法樹有以下幾種
remark-parse
插件就是在該階段工作。
Transform
該階段用于根據(jù)業(yè)務(wù)場(chǎng)景處理AST,是整個(gè)流程的核心階段,生態(tài)中大部分插件及我們自定義的插件大都運(yùn)行在這個(gè)階段。當(dāng)然這個(gè)階段是可選的,沒(méi)有這個(gè)階段也能運(yùn)行,但是沒(méi)有太大意義。remark-frontmatter
插件就是在這個(gè)階段工作。
還有一類稱為橋接(Bridge)的插件也是運(yùn)行在這個(gè)階段,這類插件用于不同結(jié)構(gòu)的AST相互轉(zhuǎn)換。例如我們需要將處理后的Markdown轉(zhuǎn)換為HTML,就需要將mdast
轉(zhuǎn)換為hast
,常見的幾種Bridge插件有:
- remark-rehype — Markdown 轉(zhuǎn) HTML
- rehype-remark — HTML 轉(zhuǎn) Markdown
- remark-retext — Markdown 轉(zhuǎn) 自然語(yǔ)言
- rehype-retext — HTML 轉(zhuǎn) 自然語(yǔ)言
Stringify
該階段用于將AST序列化為字符串輸出。 remark-stringify
插件就是在這個(gè)階段工作。
牛刀小試
環(huán)境搭建
安裝依賴
npm install unified remark-parse remark-stringify remark-frontmatter js-yaml
編寫運(yùn)行代碼
// index.js const unified = require('unified') console.log(unified)
運(yùn)行
node index.js
報(bào)錯(cuò)
處理ESM類型包
由于unified
使用的是ESM
方式打包,而我們通常寫的node代碼用CommonJS
方式在這里是無(wú)法正常運(yùn)行的,所以我們需要使用ESM
的方式來(lái)編寫運(yùn)行代碼。
- 首先將
index.js
改名為index.mjs
(使用package.json配置也行,這里不舉例了) - 將引入方式改為
ESM
的import
// index.mjs // 由于unified沒(méi)有導(dǎo)出default,這里要用{}括起來(lái) import { unified } from 'unified' console.log(unified)
- 運(yùn)行
node index.mjs
可以看到已經(jīng)可以正常運(yùn)行,基本運(yùn)行環(huán)境就完成了。
最簡(jiǎn)用法
修改運(yùn)行文件
import { unified } from 'unified' import remarkParse from 'remark-parse' import remarkStringify from 'remark-stringify' // 初始化一個(gè)unified解析器 const res = unified() // 使用Markdown解析器將文本轉(zhuǎn)為AST .use(remarkParse) // 將MarkdownAST轉(zhuǎn)為字符串 .use(remarkStringify) // 開始同步執(zhí)行解析 .processSync('# hello unified') console.log(res)
這個(gè)例子僅是最基礎(chǔ)的運(yùn)行沒(méi)有什么實(shí)際功能,運(yùn)行結(jié)果:
加載文檔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的插件,會(huì)將具有yaml塊標(biāo)志(默認(rèn)為---)的文檔塊解析成為yaml類型節(jié)點(diǎn), .use(remarkFrontmatter, ['yaml']) // 添加一個(gè)自定義插件來(lái)處理yaml類型節(jié)點(diǎn) .use(() => (tree, vFile) => { console.log(tree) // unist-util-visit 提供了更多便捷訪問(wèn)AST的工具,這里我們先簡(jiǎn)單獲取 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) // 賦值到該文件的解析數(shù)據(jù)中返回給外部使用 vFile.data.meta = meta } }) .use(remarkStringify) .processSync(`--- title: I AM TITLE tags: - unified - good --- # hello unified' `) console.log(res)
從打印結(jié)果可以看到,經(jīng)過(guò)remark-frontmatter
處理后,被---
標(biāo)志包含的文檔塊被轉(zhuǎn)換成了yaml
類型的節(jié)點(diǎn),我們就可以方便的基于這個(gè)節(jié)點(diǎn)來(lái)解析數(shù)據(jù)了。
同時(shí)我們還自定義了一個(gè)簡(jiǎn)易的插件,用于處理yaml
類型的節(jié)點(diǎn),最終結(jié)果如下所示,已經(jīng)正確提取出出來(lái)Markdown中的自定義屬性數(shù)據(jù):
一個(gè)實(shí)際使用例子:
dumi - 為組件研發(fā)而生的靜態(tài)站點(diǎn)框架
該項(xiàng)目使用了unified來(lái)將markdown轉(zhuǎn)換為react-jsx,markdown用于寫組件說(shuō)明文檔,jsx用于渲染為網(wǎng)站。其中除了使用unified生態(tài)的部分插件外,dumi還實(shí)現(xiàn)了許多自定義的功能插件用于擴(kuò)展markdown的語(yǔ)法。
本章后續(xù)將逐一拆解相關(guān)代碼,深入學(xué)習(xí)unified插件開發(fā)及實(shí)戰(zhàn)運(yùn)用,更多關(guān)于unified處理markdown解析器的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
以上就是unified如何處理markdown解析器詳解的詳細(xì)內(nèi)容,更多關(guān)于unified處理markdown解析器的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- python使用html2text庫(kù)實(shí)現(xiàn)從HTML轉(zhuǎn)markdown的方法詳解
- python 自動(dòng)化將markdown文件轉(zhuǎn)成html文件的方法
- Python?mistune庫(kù)靈活的Markdown解析器使用實(shí)例探索
- Python自動(dòng)創(chuàng)建Markdown表格使用實(shí)例探究
- uniapp中解析markdown支持網(wǎng)頁(yè)和小程序?qū)崿F(xiàn)示例
- 微信小程序?qū)崿F(xiàn)動(dòng)態(tài)渲染Markdown示例詳解
- 一款功能強(qiáng)大的markdown編輯器tui.editor使用示例詳解
- umi插件開發(fā)仿dumi項(xiàng)目加載markdown文件實(shí)現(xiàn)詳解
- python markdown轉(zhuǎn)html自定義實(shí)現(xiàn)工具解析
相關(guān)文章
微信小程序 實(shí)現(xiàn)動(dòng)態(tài)顯示和隱藏某個(gè)控件
這篇文章主要介紹了微信小程序 實(shí)現(xiàn)動(dòng)態(tài)顯示和隱藏某個(gè)控件的相關(guān)資料,需要的朋友可以參考下2017-04-04TypeScript編寫自動(dòng)創(chuàng)建長(zhǎng)度固定數(shù)組的類型工具詳解
這篇文章主要為大家介紹了TS編寫自動(dòng)創(chuàng)建長(zhǎng)度固定數(shù)組的類型工具詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08創(chuàng)建圖片對(duì)比slider滑塊示例詳解
這篇文章主要為大家介紹了創(chuàng)建圖片對(duì)比slider滑塊示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08業(yè)務(wù)層hooks封裝useSessionStorage實(shí)例詳解
這篇文章主要為大家介紹了業(yè)務(wù)層hooks封裝useSessionStorage實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08Javascript中彈窗confirm與prompt的區(qū)別
今天小編就為大家分享一篇關(guān)于Javascript中彈窗confirm與prompt的區(qū)別,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-10-10