字串化
Fumadocs 如何將您的文件轉換為 Markdown。
Remark LLMs 與 Remark Structure 會輸出 Markdown,供 LLM 與搜尋使用。它們不會將語法樹字串化,而是直接從您撰寫的原始內容中切取片段:
- Markdown 會維持您撰寫時的原貌,不會經過跳脫或重新格式化。
- Remark 外掛只能透過記錄編輯來修改內容。
- 由於不需要序列化語法樹,處理速度很快。
運作原理
輸出內容是您文件的原始碼,並套用了外掛所做的修改。節點會依據其 position 定位:
- 具有
position的節點會輸出其原始碼。 - 沒有
position的節點 (例如由外掛插入的節點) 不會輸出任何內容,其 Markdown 改由對應的外掛定義。
例如,Remark Image 會將  轉換為 <img> 元素,但輸出內容仍保留 。
編輯輸出內容
若外掛會取代作者撰寫的內容,則應使用 replaceSource() 記錄其節點對應的 Markdown:
import type { Root } from 'mdast';
import type { VFile } from 'vfile';
import { visit } from 'unist-util-visit';
import { replaceSource } from 'fumadocs-core/mdx-plugins/stringifier';
export function remarkNote() {
return (tree: Root, file: VFile) => {
visit(tree, 'mdxJsxFlowElement', (node) => {
if (node.name !== 'Note') return;
replaceSource(file, node, (s) => `**Note:**\n\n${s.inner(node)}`);
// 轉換節點以供算繪……
});
};
}- 字串會取代整個節點,節點內部的編輯也會一併被取代。
- 函式會在所有外掛執行完畢後才執行。
s.stringify(node)與s.inner(node)(其子節點) 會回傳對應的 Markdown,其中包含內部的編輯。 - 同一個節點被編輯多次時,以最後一次編輯為準。
若只想編輯其中一種輸出,請將其命名空間作為最後一個引數傳入:search 對應 Remark Structure 的紀錄,markdown 對應 Remark LLMs。
// 給 LLM 的 Markdown 會保留這個標記,搜尋紀錄則不會
replaceSource(file, node, (s) => s.stringify(node).replace(' [step]', ''), 'search');在搜尋方面,外掛會透過 data.structuredData 加入其節點的紀錄。
執行階段的值
若 Markdown 內容要到執行階段才能得知,請使用 s.expression() 輸出 JS 表達式。Remark LLMs 會在匯出 Markdown 的位置對其求值,其他輸出則會使用備用值:
import type { Expression } from 'estree';
// 編譯後文件中 `import image from './image.png'` 的 URL
const url: Expression = { type: 'Identifier', name: 'image' };
replaceSource(file, node, (s) => `})`);嵌入內容
從其他來源解析出的節點 (例如引入的檔案) ,其位置資訊對應的是該來源。請使用 embedSource() 嵌入這些節點,就能像處理您自己的內容一樣將其字串化:
import { embedSource } from 'fumadocs-core/mdx-plugins/stringifier';
// 將 `node` 替換為從 `otherSource` 解析出的節點
embedSource(file, node, otherSource, otherTree.children);從字串解析出的其他節點不得保留其 position,因為該位置並未指向您的文件。
本頁的輔助函式適用於 unified 外掛。在 Sätteri 上,Remark LLMs 與 Remark Structure 同樣會輸出 Markdown,但沒有公開 API 可供編輯輸出內容。
How is this guide?
最後更新於
