Mdbook Embedify

Crates.io Crates.io

This is a mdbook preprocessor plugin that allows you to embed apps to your book, like youtube, codepen and some other apps.

Copyright © 2024 • Created with ❤️ by MR-Addict

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.

Copyright © 2024 • Created with ❤️ by MR-Addict

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.

Copyright © 2024 • Created with ❤️ by MR-Addict

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.

Copyright © 2024 • Created with ❤️ by MR-Addict

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.

Copyright © 2024 • Created with ❤️ by MR-Addict

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.

Copyright © 2024 • Created with ❤️ by MR-Addict

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

OptionDescriptionRequiredDefault
idGist IDYes- -

Example

{% embed gist id="76cf171d1bdd7da41d4ca96b908eb57a" %}

Copyright © 2024 • Created with ❤️ by MR-Addict

Vimeo

Vimeo is a video hosting platform that allows you to upload and share videos.

Options

OptionDescriptionRequiredDefault
idVideo IDYes- -
loadingSupports lazy and eagerNolazy

Example

{% embed vimeo id="914391191" loading="lazy" %}

Copyright © 2024 • Created with ❤️ by MR-Addict

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

OptionDescriptionRequiredDefault
repoRepositoryYes- -
repo-idRepository IDYes- -
categoryCategoryYes- -
category-idCategory IDYes- -
reactions-enabledEnable reactionsNo1
themeSupports book,light and darkNobook
langLanguageNoen
loadingSupports lazy and eagerNolazy

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.

Copyright © 2024 • Created with ❤️ by MR-Addict

Youtube

YouTube is a popular online video sharing and social media platform.

Options

OptionDescriptionRequiredDefault
idVideo IDYes- -
loadingSupports lazy and eagerNolazy

Example

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

Copyright © 2024 • Created with ❤️ by MR-Addict

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

OptionDescriptionRequiredDefault
userusernameYes- -
slugProject slugYes- -
heightIframe heightNo600
themeIframe themeNodark
loadingSupports lazy and eagerNolazy

Example

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

Copyright © 2024 • Created with ❤️ by MR-Addict

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

OptionDescriptionRequiredDefault
idProject IDYes- -
themeIframe themeNodark
loadingSupports lazy and eagerNolazy

Example

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

Copyright © 2024 • Created with ❤️ by MR-Addict

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

OptionDescriptionRequiredDefault
idProject IDYes- -
themeIframe themeNodark
loadingSupports lazy and eagerNolazy

Example

{% embed codesandbox id="ke8wx" theme="light" loading="lazy" %}

Copyright © 2024 • Created with ❤️ by MR-Addict

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

OptionDescriptionRequiredDefault
idVideo IDYes- -
loadingSupports lazy and eagerNolazy

Example

{% embed bilibili id="BV1uT4y1P7CX" loading="lazy" %}

Copyright © 2024 • Created with ❤️ by MR-Addict

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.

Copyright © 2024 • Created with ❤️ by MR-Addict

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

OptionDescriptionRequiredDefault
messageFooter message, markdown supportedYes- -

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)"

Copyright © 2024 • Created with ❤️ by 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.

Copyright © 2024 • Created with ❤️ by MR-Addict

Announcement Banner

Announcement banner allows you put important messages at the top of the page. It supports markdown syntax too.

Options

OptionDescriptionRequiredDefault
idAnnouncement idYes- -
messageAnnouncement message, markdown supportedYes- -
themeSupports theme: default, ocean, forest, lavaNodefault

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.

Copyright © 2024 • Created with ❤️ by MR-Addict