Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Last updated: Monday 07 September 2026 @ 20:44:27

mdbook-embedify 操作手册

mdbook-embedify 用来把第三方应用或本地内容嵌入 mdBook 页面。当前 0.3.x 与 mdBook 0.5.x 配套使用。

原仓库:https://github.com/MR-Addict/mdbook-embedify

通用语法

所有 Embedify 应用都遵循:

{% embed app option="value" another-option="value" %}

参数使用空格分隔,值需要放在引号中。

YouTube

样例

<!-- {% embed youtube id="DyTCOwB0DVw" loading="lazy" %} -->

<div data-embedify data-app="youtube" data-option-id="DyTCOwB0DVw" data-option-loading="lazy" style="display:none"></div>

<iframe allowfullscreen name="youtube" loading="lazy" src="https://www.youtube.com/embed/DyTCOwB0DVw" style="width: 100%; height: 100%; border: none; aspect-ratio: 16/9; border-radius: 1rem; background: black" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"></iframe>

常用参数:

参数含义
idYouTube 视频 ID
loadinglazy 或 eager

Bilibili

样例

<!-- {% embed bilibili id="BV1uT4y1P7CX" loading="lazy" %} -->

<div data-embedify data-app="bilibili" data-option-id="BV1uT4y1P7CX" data-option-loading="lazy" style="display:none"></div>

<iframe allowfullscreen name="bilibili" loading="lazy" src="https://player.bilibili.com/player.html?bvid=BV1uT4y1P7CX&danmaku=0" style="width: 100%; height: 100%; border: none; aspect-ratio: 16/9; border-radius: 1rem; background: black"></iframe>

id 使用 BV 号。

Vimeo

<!-- {% embed vimeo id="914391191" loading="lazy" %} -->

<div data-embedify data-app="vimeo" data-option-id="914391191" data-option-loading="lazy" style="display:none"></div>

<iframe name="vimeo" loading="lazy" allow="autoplay; fullscreen; picture-in-picture" src="https://player.vimeo.com/video/914391191" style="width: 100%; height: 100%; border: none; aspect-ratio: 16/9; border-radius: 1rem; background: black"></iframe>

GitHub Gist

<!-- {% embed gist id="76cf171d1bdd7da41d4ca96b908eb57a" %} -->

<div data-embedify data-app="gist" data-option-id="76cf171d1bdd7da41d4ca96b908eb57a" style="display:none"></div>

<script src="https://gist.github.com/76cf171d1bdd7da41d4ca96b908eb57a.js"></script>

适合把较长代码片段维护在 Gist 中,再嵌入文档。

CodePen

<!-- {% embed codepen user="MR-Addict" slug="NWBOqKw" height="600" theme="dark" loading="lazy" %} -->

<div data-embedify data-app="codepen" data-option-user="MR-Addict" data-option-slug="NWBOqKw" data-option-height="600" data-option-theme="dark" data-option-loading="lazy" style="display:none"></div>

<iframe allowfullscreen name="codepen" loading="lazy" height="600" style="width: 100%; border: none; border-radius: 1rem; background: black" src="https://codepen.io/MR-Addict/embed/NWBOqKw?default-tab=result&theme-id=dark"></iframe>

常用参数:

user
slug
height
theme
loading

StackBlitz

<!-- {% embed stackblitz id="vitejs-vite-y8mdxg" theme="light" loading="lazy" %} -->

<div data-embedify data-app="stackblitz" data-option-id="vitejs-vite-y8mdxg" data-option-theme="light" data-option-loading="lazy" style="display:none"></div>

<iframe name="stackblitz" loading="lazy" src="https://stackblitz.com/edit/vitejs-vite-y8mdxg?embed=1&theme=light&view=preview" style="width: 100%; height: 100%; border: none; aspect-ratio: 16/9; border-radius: 1rem; background: black"></iframe>

CodeSandbox

<!-- {% embed codesandbox id="ke8wx" theme="light" loading="lazy" %} -->

<div data-embedify data-app="codesandbox" data-option-id="ke8wx" data-option-theme="light" data-option-loading="lazy" style="display:none"></div>

<iframe name="sandbox" loading="lazy" src="https://codesandbox.io/embed/ke8wx?&theme=light" style="width: 100%; height: 100%; border: none; aspect-ratio: 16/9; border-radius: 1rem; background: black"></iframe>

Giscus 评论

Giscus 依赖 GitHub Discussions。

单页嵌入

<!-- {% embed giscus repo="owner/repo" repo-id="R_XXXXXXXXXX" category="General" category-id="DIC_XXXXXXXXXXXXXXXX" theme="book" loading="eager" %} -->

<div data-embedify data-app="giscus" data-option-repo="owner/repo" data-option-repo-id="R_XXXXXXXXXX" data-option-category="General" data-option-category-id="DIC_XXXXXXXXXXXXXXXX" data-option-theme="book" data-option-loading="eager" style="display:none"></div>

<style>.giscus { margin-top: 6rem; }</style><script src="https://giscus.app/client.js" data-repo="owner/repo" data-repo-id="R_XXXXXXXXXX" data-category="General" data-category-id="DIC_XXXXXXXXXXXXXXXX" data-mapping="title" data-strict="0" data-reactions-enabled="1" data-emit-metadata="0" data-input-position="bottom" data-lang="en" data-loading="eager" crossorigin="anonymous" data-theme="book" async></script><script>(() => { const giscusScript = document.querySelector("script[data-repo][data-repo-id]"); if (giscusScript?.getAttribute("data-theme") !== "book") return; const mapTheme = (theme) => (["light", "rust"].includes(theme) ? "light" : "dark"); const bookTheme = localStorage.getItem("mdbook-theme") || html.getAttribute("class"); giscusScript.setAttribute("data-theme", mapTheme(bookTheme)); document.querySelectorAll("button[role='menuitem'].theme").forEach((btn) => { btn.addEventListener("click", (event) => { const theme = mapTheme(event.target.id); const iframe = document.querySelector("iframe.giscus-frame"); if (iframe) iframe.contentWindow.postMessage({ giscus: { setConfig: { theme } } }, "*"); }); }); })();</script>

常用参数:

参数必需说明
repo是GitHub 仓库
repo-id是仓库 ID
category是Discussion 分类
category-id是分类 ID
reactions-enabled否是否启用 reactions
theme否book、light、dark
lang否语言
loading否lazy / eager

全书启用 Giscus

[preprocessor.embedify]
giscus.enable = true
giscus.repo = "owner/repo"
giscus.repo-id = "R_XXXXXXXXXX"
giscus.category = "General"
giscus.category-id = "DIC_XXXXXXXXXXXXXXXX"
giscus.reactions-enabled = "1"
giscus.theme = "book"
giscus.lang = "zh-CN"
giscus.loading = "lazy"

如果直接用 file:// 打开生成的 HTML,Giscus 可能拒绝连接;应通过 mdbook serve 或其他 HTTP server 预览。

Include:把本地文件显示为代码块

include 会读取文件,并把内容包成 Markdown code block,而不是把文件当作正文继续解析。

文件路径相对于 mdBook 书籍根目录。

完整文件

<!-- {% embed include file="src/SUMMARY.md" %} -->

<div data-embedify data-app="include" data-option-file="src/SUMMARY.md" style="display:none"></div>

```markdown
# Summary

[Homepage](Homepage.md)
[Frontmatter Render Test](Frontmatter-Render-Test.md)

# Paper

- [ANNS](Paper/ANNS/ANNS.md)
	- [Quake](Paper/ANNS/Quake.md)
	- [FlowANN](Paper/ANNS/FlowANN.md)
	- [HELMESMAN](Paper/ANNS/HELMESMAN.md)
	- [GustANN](Paper/ANNS/GustANN.md)
- [LLM](Paper/LLM/LLM.md)

# Note

- [Quant](Note/Quant/Quant.md)
	- [股票基金与量化投资_零基础核心名词手册](Note/Quant/股票基金与量化投资_零基础核心名词手册.md)
- [Slay the spine 2](Note/Slay%20the%20spine%202/Slay%20the%20spine%202.md)
	- [毒雾与触媒的数学建模分析](Note/Slay%20the%20spine%202/毒雾与触媒的数学建模分析.md)
- [Orion](Note/Orion/Orion.md)
	- [系统设计](Note/Orion/系统设计.md)
# Project

- [1zone](Project/1zone/1zone.md)
- [Betterfly](Project/Betterfly/Betterfly.md)
- [Golden Compass](Project/Golden%20Compass/Golden%20Compass.md)
- [mdbook frontmatter render](Project/mdbook%20frontmatter%20render/mdbook%20frontmatter%20render.md)
- [Pixrompt](Project/Pixrompt/Pixrompt.md)
- [Qoffee](Project/Qoffee/Qoffee.md)
- [Sharkdown](Project/Sharkdown/Sharkdown.md)
- [sts2stats](Project/sts2stats/sts2stats.md)
- [Surge lens](Project/Surge%20lens/Surge%20lens.md)
- [traintrace](Project/traintrace/traintrace.md)
- [typst](Project/typst/typst.md)

# Musing
- [常用代码](Musing/常用代码/常用代码.md)
	- [查看 codex 额度](Musing/常用代码/查看%20codex%20额度.md)
- [降低人工生成率](Musing/降低人工生成率.md)

# Example
- [embedify](Example/embedify.md)
- [frontmatter-render](Example/frontmatter-render.md)
- [gitinfo](Example/gitinfo.md)
- [inline-highlighting](Example/inline-highlighting.md)
- [katex](Example/katex.md)
- [mermaid](Example/mermaid.md)
- [obsidian-format](Example/obsidian-format.md)
- [pikchr](Example/pikchr.md)
- [qr](Example/qr.md)
- [reading-time](Example/reading-time.md)
- [toc](Example/toc.md)

### 指定代码语言

```text
<!-- {% embed include file="src/SUMMARY.md" lang="markdown" %} -->

<div data-embedify data-app="include" data-option-file="src/SUMMARY.md" data-option-lang="markdown" style="display:none"></div>

```markdown
# Summary

[Homepage](Homepage.md)
[Frontmatter Render Test](Frontmatter-Render-Test.md)

# Paper

- [ANNS](Paper/ANNS/ANNS.md)
	- [Quake](Paper/ANNS/Quake.md)
	- [FlowANN](Paper/ANNS/FlowANN.md)
	- [HELMESMAN](Paper/ANNS/HELMESMAN.md)
	- [GustANN](Paper/ANNS/GustANN.md)
- [LLM](Paper/LLM/LLM.md)

# Note

- [Quant](Note/Quant/Quant.md)
	- [股票基金与量化投资_零基础核心名词手册](Note/Quant/股票基金与量化投资_零基础核心名词手册.md)
- [Slay the spine 2](Note/Slay%20the%20spine%202/Slay%20the%20spine%202.md)
	- [毒雾与触媒的数学建模分析](Note/Slay%20the%20spine%202/毒雾与触媒的数学建模分析.md)
- [Orion](Note/Orion/Orion.md)
	- [系统设计](Note/Orion/系统设计.md)
# Project

- [1zone](Project/1zone/1zone.md)
- [Betterfly](Project/Betterfly/Betterfly.md)
- [Golden Compass](Project/Golden%20Compass/Golden%20Compass.md)
- [mdbook frontmatter render](Project/mdbook%20frontmatter%20render/mdbook%20frontmatter%20render.md)
- [Pixrompt](Project/Pixrompt/Pixrompt.md)
- [Qoffee](Project/Qoffee/Qoffee.md)
- [Sharkdown](Project/Sharkdown/Sharkdown.md)
- [sts2stats](Project/sts2stats/sts2stats.md)
- [Surge lens](Project/Surge%20lens/Surge%20lens.md)
- [traintrace](Project/traintrace/traintrace.md)
- [typst](Project/typst/typst.md)

# Musing
- [常用代码](Musing/常用代码/常用代码.md)
	- [查看 codex 额度](Musing/常用代码/查看%20codex%20额度.md)
- [降低人工生成率](Musing/降低人工生成率.md)

# Example
- [embedify](Example/embedify.md)
- [frontmatter-render](Example/frontmatter-render.md)
- [gitinfo](Example/gitinfo.md)
- [inline-highlighting](Example/inline-highlighting.md)
- [katex](Example/katex.md)
- [mermaid](Example/mermaid.md)
- [obsidian-format](Example/obsidian-format.md)
- [pikchr](Example/pikchr.md)
- [qr](Example/qr.md)
- [reading-time](Example/reading-time.md)
- [toc](Example/toc.md)

### 指定行范围

```text
<!-- {% embed include file="src/SUMMARY.md" range="1-20" %} -->

<div data-embedify data-app="include" data-option-file="src/SUMMARY.md" data-option-range="1-20" style="display:none"></div>

```markdown
# Summary

[Homepage](Homepage.md)
[Frontmatter Render Test](Frontmatter-Render-Test.md)

# Paper

- [ANNS](Paper/ANNS/ANNS.md)
	- [Quake](Paper/ANNS/Quake.md)
	- [FlowANN](Paper/ANNS/FlowANN.md)
	- [HELMESMAN](Paper/ANNS/HELMESMAN.md)
	- [GustANN](Paper/ANNS/GustANN.md)
- [LLM](Paper/LLM/LLM.md)

# Note

- [Quant](Note/Quant/Quant.md)
	- [股票基金与量化投资_零基础核心名词手册](Note/Quant/股票基金与量化投资_零基础核心名词手册.md)
- [Slay the spine 2](Note/Slay%20the%20spine%202/Slay%20the%20spine%202.md)
	- [毒雾与触媒的数学建模分析](Note/Slay%20the%20spine%202/毒雾与触媒的数学建模分析.md)

支持的 range 形式:

```text
1-10
1-
-10

同时指定语言和范围

<!-- {% embed include file="book.toml" lang="toml" range="1-30" %} -->

<div data-embedify data-app="include" data-option-file="book.toml" data-option-lang="toml" data-option-range="1-30" style="display:none"></div>

```toml
[book]
title = "Pages"
authors = ["quaternijkon"]
description = "Digital garden of quaternijkon"
language = "zh-CN"

# [preprocessor.obsidian-format]
# after = ["index", "frontmatter-render"]
# warn-on-missing = true
# transform-embeds = true

[preprocessor.frontmatter-render]
# Source-linked development mode: plugin updates take effect on the next build.
command = "cargo run --quiet --manifest-path /Users/ruoyangdong/project/rust/mdbook-frontmatter-render/Cargo.toml --"

# 基础外观:普通用户通常只需要调整下面几项。
layout = "card"          # card | badges | table
placement = "after-title" # after-title | before-title
style = "embedded"       # embedded 使用内置样式;none 使用自定义 CSS
collapsible = true        # 是否允许折叠
default-open = true       # 初始是否展开

# https://github.com/MR-Addict/mdbook-embedify
[preprocessor.embedify]

# https://github.com/CompEng0001/mdbook-gitinfo
[preprocessor.gitinfo]
enable = true

# choose placement(s)

如果不写 `lang`,插件会尝试根据文件扩展名自动识别语言。

## Footer

### 单页 footer

```text
<!-- {% embed footer message="Copyright © 2026 Quaternijkon" %} -->

<div data-embedify data-app="footer" data-option-message="Copyright © 2026 Quaternijkon" style="display:none"></div>

<style>footer { text-align: center; text-wrap: balance; margin-top: 5rem; display: flex; flex-direction: column; justify-content: center; align-items: center; } footer p { margin: 0; }</style><footer><p>Copyright © 2026 Quaternijkon</p></footer>

message 支持 Markdown。

Scroll to Top

单页启用

<!-- {% embed scroll-to-top %} -->

<div data-embedify data-app="scroll-to-top"  style="display:none"></div>

<style>.scroll-to-top { font-size: 2.5rem; width: 3.2rem; height: 3.2rem; display: none; align-items: center; justify-content: center; position: fixed; padding: 0.75rem; bottom: 4rem; right: calc(1.25rem + 90px + var(--page-padding)); z-index: 999; cursor: pointer; border: none; color: var(--bg); background: var(--fg); border-radius: 50%; } .scroll-to-top.hidden { display: none; } .scroll-to-top i { transform: translateY(-2px); } @media (min-width: 1080px) { .scroll-to-top { display: flex; } }</style><button type="button" aria-label="scroll-to-top" class="scroll-to-top hidden" onclick="scrollToTop()"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"> <path d="m18 15-6-6-6 6"></path> </svg></button><script>const scrollToTop = () => window.scroll({ top: 0, behavior: "smooth" }); window.addEventListener("scroll", () => { const button = document.querySelector(".scroll-to-top"); button.classList.toggle("hidden", window.scrollY <200); });</script>

全书启用

[preprocessor.embedify]
scroll-to-top.enable = true

全局启用后,不要再在每个章节手动嵌入,否则会重复出现。

Announcement Banner

单页公告

<!-- {% embed announcement-banner id="2026-09" message="*文档站已更新*" %} -->

<div data-embedify data-app="announcement-banner" data-option-id="2026-09" data-option-message="*文档站已更新*" style="display:none"></div>

<style>.announcement-banner { --site-announcement-bar-stripe-color1: #e5e7eb; --site-announcement-bar-stripe-color2: #d1d5db; z-index: 150; position: relative; flex-direction: column; justify-content: center; align-items: center; margin: 0; padding: 1rem 3.5rem; background: repeating-linear-gradient( 45deg, var(--site-announcement-bar-stripe-color1), var(--site-announcement-bar-stripe-color1) 20px, var(--site-announcement-bar-stripe-color2) 10px, var(--site-announcement-bar-stripe-color2) 40px ); } html:is(.navy, .coal, .ayu) .announcement-banner { --site-announcement-bar-stripe-color1: #1f2937; --site-announcement-bar-stripe-color2: #111827; } .announcement-banner p { color: var(--fg); width: 100%; margin: 0; padding: 0; overflow: hidden; text-align: center; white-space: nowrap; text-overflow: ellipsis; text-wrap: balance; } .announcement-banner button[data-close] { top: 50%; right: 1rem; position: absolute; transform: translateY(-50%); width: 3rem; height: 3rem; cursor: pointer !important; border: none; font-weight: 900; border-radius: 50%; background-color: transparent; }</style><div style="display: none" data-id="2026-09" class="announcement-banner"> <p><em>文档站已更新</em></p> <button type="button" data-close>X</button></div><script>(() => { const banner = document.querySelector(".announcement-banner"); const id = banner.getAttribute("data-id"); const message = banner.querySelector("p").textContent; const localData = JSON.parse(localStorage.getItem("mdbook-announcement-banner")); if (!localData || localData.id !== id || localData.hide !== true) { banner.style.display = "flex"; const page = document.querySelector(".page"); page.parentNode.insertBefore(banner, page); banner.querySelector("button").addEventListener("click", () => { banner.remove(); localStorage.setItem("mdbook-announcement-banner", JSON.stringify({ id, hide: true, message })); }); } })();</script>

message 支持 Markdown。

公告内容发生明显变化时建议更新 id。

全局嵌入

部分应用支持在 book.toml 中直接全局启用,例如:

[preprocessor.embedify]
scroll-to-top.enable = true

此类全局应用会自动加入每一章,不需要再手写对应 embed macro。

在操作手册中展示 Embedify 语法,而不执行它

这是编写本页这类手册时最重要的功能。

把 embed 改成 embed-ignore:

{% embed youtube id="DyTCOwB0DVw" loading="lazy" %}

插件会保留并显示相应 embed 语法,而不会真正渲染视频。

批量忽略一段区域

<!-- embed ignore begin -->

这里的 Embedify 宏不会执行。

<!-- embed ignore end -->

适合手册中一次展示很多 embed 示例。

当前书库配置

[preprocessor.embedify]

因此所有局部 embed 功能均可以直接在章节 Markdown 中使用。

使用选择

  • 在线视频:YouTube / Bilibili / Vimeo;
  • 在线代码演示:CodePen / StackBlitz / CodeSandbox;
  • 代码片段:Gist;
  • 评论区:Giscus;
  • 展示仓库中的真实源码:Include;
  • 页面附加 UI:Footer、Scroll to Top、Announcement Banner。