Mdbook Embedify
This is a mdbook preprocessor plugin that allows you to embed apps to your book, like youtube, codepen and some other apps.
Usage
Installation
There are two ways to install this preprocessor.
You can install it from crates.io using cargo.
cargo install mdbook-embedify
Or you can download the binary from releases page.
Then you can check your installation by running:
mdbook-embedify --version
After installation, add the following code to your book.toml
file:
[preprocessor.embedify]
And that's it! You can now use embed
macro to embed apps to your book.
Syntax
The basic syntax is like this:
{% embed app options[] %}
options are key-value based array seperated by space and its value must be wrapped by quotes.
For example:
{% embed codepen user="MR-Addict" slug="NWBOqKw" height="600" theme="dark" loading="lazy" %}
See some examples at apps section.
Global Embedding
Some apps allow you to automatically embed to every chapter. You can do this by modifying book.toml
file to enable them.
For example:
[preprocessor.embedify]
scroll-to-top.enable = true
💥Attention
When you do this, you don't need to add
{% embed scroll-to-top %}
manually. It will be automatically added it to every chapter. If you do, it will be rendered twice.
Below is a full list of apps that support global configuration:
[preprocessor.embedify]
scroll-to-top.enable = true
footer.enable = true
footer.message = "Copyright © 2024 • Created with ❤️ by [MR-Addict](https://github.com/MR-Addict)"
announcement-banner.enable = true
announcement-banner.id = "0.2.11"
announcement-banner.theme = "default"
announcement-banner.message = "*Version **0.2.11** now has relased, check it out [here](https://github.com/MR-Addict/mdbook-embedify/releases/tag/0.2.11).*"
giscus.enable = true
giscus.repo = "MR-Addict/mdbook-embedify"
giscus.repo-id = "R_kgDOLCxX0Q"
giscus.category = "General"
giscus.category-id = "DIC_kwDOLCxX0c4CdGx-"
giscus.reactions-enabled = "1"
giscus.theme = "light"
giscus.lang = "en"
giscus.loading = "eager"
You can see more details about each app at its own page.
Ignore Embeds
Sometimes you may want preprocessor to ignore some embeds.
You can do it by wrapping content that you want to ignore with below two comments:
<!-- embed ignore begin -->
<!-- embed ignore end -->
For example:
<!-- embed ignore begin -->
{% embed youtube id="DyTCOwB0DVw" loading="lazy" %}
<!-- embed ignore end -->
And youtube embed won't be rendered.
More Apps
In this section, I will show you how to add more apps to this preprocessor.
Create a new app
You may have some other apps that preprocessor doesn't support yet. However, it's very easy to add a new app based on project custom template engine.
What we need to do is put a new app template in the templates folder. The template file name should be the app name ended with .html.
For example we want to add a new app called youtube, then we could create a youtube.html under templates folder.
We know that we can use an iframe to embed a youtube video. Template file could be like this:
<iframe
allowfullscreen
name="youtube"
loading="lazy"
src="https://www.youtube.com/embed/dQw4w9WgXcQ"
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>
💥Attention
You can even add style and js content to the template file. But the style and js content should be put in the style and js blocks.
However, we want video id and loading strategy to be dynamic and loading strategy has default lazy value. So we can replace them with placeholders like this:
<iframe
allowfullscreen
name="youtube"
loading="{% raw(loading=lazy) %}"
src="https://www.youtube.com/embed/{% raw(id) %}"
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>
The placeholder syntax is similar to a function call in programming languages, which is the combination of function name and argument wrapped by {% and %}.
Function name
The preprocessor reconginzes two function names, raw and markdown. Which raw will keep inner value as it is, markdown will treat the inner value as markdown content and render it to be html.
Function argument
The inner value is key follwed by a default value in the form of key=default_value. If the key is not provided, the default value will be used.
So raw(id) means the placeholder will be replaced by the value of id key and id is not optional because it doesn't have a default value.
raw(loading=lazy) means the placeholder will be replaced by the value of loading key. If user doesn't provide the value, the default value lazy will be used. And means loading is optional.
Build the project
After build the project, the new app will be automatically added to the preprocessor binary.
cargo build --release
And you can use it in your book:
{% embed youtube id="dQw4w9WgXcQ" loading="eager" %}
Because the loading
key has a default value lazy
, we can omit it.
{% embed youtube id="dQw4w9WgXcQ" %}
If you are using this repository as a template, then you can build your book to see the result by running:
mdbook build docs
That's it. If you have some apps need to be added, you can create a new issue or pull request.
Third Party Apps
Third party apps are apps that are hosted on third party sites. Below are all supported third party apps and its detailed options.
Gist
Gist is a simple way to share snippets and pastes with others. All gists are Git repositories, so they are automatically versioned, forkable and usable from Git.
Options
Option | Description | Required | Default |
---|---|---|---|
id | Gist ID | Yes | - - |
Example
{% embed gist id="76cf171d1bdd7da41d4ca96b908eb57a" %}
Vimeo
Vimeo is a video hosting platform that allows you to upload and share videos.
Options
Option | Description | Required | Default |
---|---|---|---|
id | Video ID | Yes | - - |
loading | Supports lazy and eager | No | lazy |
Example
{% embed vimeo id="914391191" loading="lazy" %}
Giscus
Giscus is a comments system powered by GitHub Discussions. Let visitors leave comments and reactions on your website via GitHub! Heavily inspired by utterances.
Options
Option | Description | Required | Default |
---|---|---|---|
repo | Repository | Yes | - - |
repo-id | Repository ID | Yes | - - |
category | Category | Yes | - - |
category-id | Category ID | Yes | - - |
reactions-enabled | Enable reactions | No | 1 |
theme | Supports book,light and dark | No | book |
lang | Language | No | en |
loading | Supports lazy and eager | No | lazy |
Example
{% embed giscus repo="MR-Addict/mdbook-embedify" repo-id="R_kgDOLCxX0Q" category="General" category-id="DIC_kwDOLCxX0c4CdGx-" theme="book" loading="eager" %}
This book's giscus is enabled, you can see it at the bottom of this page. And you can also have a try by commenting below.
However, you may want to enable it for the whole book. You can do this by adding below options to book.toml
file after [preprocessor.embedify]
section:
giscus.enable = true
giscus.repo = "MR-Addict/mdbook-embedify"
giscus.repo-id = "R_kgDOLCxX0Q"
giscus.category = "General"
giscus.category-id = "DIC_kwDOLCxX0c4CdGx-"
giscus.reactions-enabled = "1"
giscus.theme = "book"
giscus.lang = "en"
giscus.loading = "eager"
Refuse to Connect
Giscus will refuse to connect if you build and preview your book with file:// protocol. The easiest solution is to use some static server so that you can preview your book with http:// protocol.
For exampe:
node.js installed
npx serve book -p 3000
Which will serve your book at http://localhost:3000.
python installed
python -m http.server --directory book 8080
Which will serve your book at http://localhost:8080.
Youtube
YouTube is a popular online video sharing and social media platform.
Options
Option | Description | Required | Default |
---|---|---|---|
id | Video ID | Yes | - - |
loading | Supports lazy and eager | No | lazy |
Example
{% embed youtube id="DyTCOwB0DVw" loading="lazy" %}
Codepen
Codepen is a social development environment for front-end designers and developers. It's the best place to build and deploy a website, show off your work, build test cases, and find inspiration.
Options
Option | Description | Required | Default |
---|---|---|---|
user | username | Yes | - - |
slug | Project slug | Yes | - - |
height | Iframe height | No | 600 |
theme | Iframe theme | No | dark |
loading | Supports lazy and eager | No | lazy |
Example
{% embed codepen user="MR-Addict" slug="NWBOqKw" height="600" theme="dark" loading="lazy" %}
Stackblitz
Stackblitz is an instant fullstack web IDE for the JavaScript ecosystem. It's powered by WebContainers, the first WebAssembly-based operating system which boots the Node.js environment in milliseconds, securely within your browser tab.
Options
Option | Description | Required | Default |
---|---|---|---|
id | Project ID | Yes | - - |
theme | Iframe theme | No | dark |
loading | Supports lazy and eager | No | lazy |
Example
{% embed stackblitz id="vitejs-vite-y8mdxg" theme="light" loading="lazy" %}
Codesandbox
Codesandbox is an online code editor that allows you to create and share web applications. It is particularly useful for web developers who want to work on React, Vue, Angular, or any other front-end libraries.
Options
Option | Description | Required | Default |
---|---|---|---|
id | Project ID | Yes | - - |
theme | Iframe theme | No | dark |
loading | Supports lazy and eager | No | lazy |
Example
{% embed codesandbox id="ke8wx" theme="light" loading="lazy" %}
Bilibili
Bilibili is a Chinese video sharing website based in Shanghai, themed around animation, comic, and games (ACG), where users can submit, view, and add commentary subtitles on videos.
Options
Option | Description | Required | Default |
---|---|---|---|
id | Video ID | Yes | - - |
loading | Supports lazy and eager | No | lazy |
Example
{% embed bilibili id="BV1uT4y1P7CX" loading="lazy" %}
Local Apps
Local apps are apps hosted on your local book, so it is not necessary to have internet connection to use them.
Below are all supported local apps and its detailed options.
Footer
The footer app is useful for displaying copyright information, privacy policy, and other legal information. It supports markdown syntax so that you can easily customize the message.
Options
Option | Description | Required | Default |
---|---|---|---|
message | Footer message, markdown supported | Yes | - - |
Example
{% embed footer message="Copyright © 2024 • Created with ❤️ by [MR-Addict](https://github.com/MR-Addict)" %}
This book's footer is enabled, you can see it at the bottom of this page.
However, you may want to enable it for the whole book. You can do this by adding below options to book.toml
file after [preprocessor.embedify]
section:
footer.enable = true
footer.message = "Copyright © 2024 • Created with ❤️ by [MR-Addict](https://github.com/MR-Addict)"
Scroll to top button
Scroll to top button allows users to smoothly scroll back to the top of the page.
Options
Scroll to top button app has no options.
Example
{% embed scroll-to-top %}
Typically, we want to use it for the whole book. You can do this by adding below options to book.toml
file after [preprocessor.embedify]
section:
scroll-to-top.enable = true
This book uses this option. You can see it at the bottom right corner of this page. But it only shows when pages are long enough to scroll. Or you can see it my another book Notes.
Announcement Banner
Announcement banner allows you put important messages at the top of the page. It supports markdown syntax too.
Options
Option | Description | Required | Default |
---|---|---|---|
id | Announcement id | Yes | - - |
message | Announcement message, markdown supported | Yes | - - |
theme | Supports theme: default, ocean, forest, lava | No | default |
Example
{% embed announcement-banner id="0.2.11" theme="default" message="*Version **0.2.11** now has relased, check it out [here](https://github.com/MR-Addict/mdbook-embedify/releases/tag/0.2.11).*" %}
This book's announcement banner is enabled, you can see it at the top of this page.
However, you may want to enable it for the whole book. You can do this by adding below options to book.toml
file after [preprocessor.embedify]
section:
announcement-banner.enable = true
announcement-banner.id = "0.2.11"
announcement-banner.theme = "default"
announcement-banner.message = "*Version **0.2.11** now has relased, check it out [here](https://github.com/MR-Addict/mdbook-embedify/releases/tag/0.2.11).*"
Note that announcement banner id must be unique, otherwise it won't be shown if there is another announcement banner with the same id when user closed it.