From f2fba30786dee83187ea2d7b00abf0f0276ecb5d Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sun, 19 Dec 2021 20:26:37 -0800 Subject: [PATCH 01/38] Update documentation --- CONTRIBUTING.md | 2 +- README.md | 224 +-------------- guide/src/README.md | 36 ++- guide/src/SUMMARY.md | 12 +- guide/src/cli/README.md | 61 +--- guide/src/cli/completions.md | 16 ++ guide/src/continuous-integration.md | 221 +++++++-------- guide/src/for_developers/README.md | 5 +- guide/src/for_developers/backends.md | 55 +--- guide/src/for_developers/preprocessors.md | 21 +- guide/src/format/configuration/general.md | 13 + .../src/format/configuration/preprocessors.md | 57 ++-- guide/src/format/configuration/renderers.md | 263 ++++++++++++------ guide/src/format/markdown.md | 121 +++++++- guide/src/format/mdbook.md | 66 +++++ guide/src/format/theme/README.md | 4 + guide/src/format/theme/editor.md | 6 +- guide/src/guide/README.md | 7 + guide/src/guide/creating.md | 109 ++++++++ guide/src/guide/installation.md | 50 ++++ guide/src/guide/reading.md | 74 +++++ guide/src/misc/introduction.md | 3 - 22 files changed, 820 insertions(+), 606 deletions(-) create mode 100644 guide/src/cli/completions.md create mode 100644 guide/src/guide/README.md create mode 100644 guide/src/guide/creating.md create mode 100644 guide/src/guide/installation.md create mode 100644 guide/src/guide/reading.md delete mode 100644 guide/src/misc/introduction.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 924cfdba..72010ad2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -127,4 +127,4 @@ The following are instructions for updating [highlight.js](https://highlightjs.o 1. Compare the language list that it spits out to the one in [`syntax-highlighting.md`](https://github.com/camelid/mdBook/blob/master/guide/src/format/theme/syntax-highlighting.md). If any are missing, add them to the list and rebuild (and update these docs). If any are added to the common set, add them to `syntax-highlighting.md`. 1. Copy `build/highlight.min.js` to mdbook's directory [`highlight.js`](https://github.com/rust-lang/mdBook/blob/master/src/theme/highlight.js). 1. Be sure to check the highlight.js [CHANGES](https://github.com/highlightjs/highlight.js/blob/main/CHANGES.md) for any breaking changes. Breaking changes that would affect users will need to wait until the next major release. -1. Build mdbook with the new file and build some books with the new version and compare the output with a variety of languages to see if anything changes. (TODO: It would be nice to have a demo file in the repo to help with this.) +1. Build mdbook with the new file and build some books with the new version and compare the output with a variety of languages to see if anything changes. The [test_book](https://github.com/rust-lang/mdBook/tree/master/test_book) contains a chapter with many languages to examine. diff --git a/README.md b/README.md index c70cf225..b2177cf3 100644 --- a/README.md +++ b/README.md @@ -6,233 +6,15 @@ mdBook is a utility to create modern online books from Markdown files. +Check out the **[User Guide]** for a list of features and installation and usage information. +The User Guide also serves as a demonstration to showcase what a book looks like. -## What does it look like? - -The [User Guide] for mdBook has been written in Markdown and is using mdBook to -generate the online book-like website you can read. The documentation uses the -latest version on GitHub and showcases the available features. - -## Installation - -There are multiple ways to install mdBook. - -1. **Binaries** - - Binaries are available for download [here][releases]. Make sure to put the - path to the binary into your `PATH`. - -2. **From Crates.io** - - This requires at least [Rust] 1.46 and Cargo to be installed. Once you have installed - Rust, type the following in the terminal: - - ``` - cargo install mdbook - ``` - - This will download and compile mdBook for you, the only thing left to do is - to add the Cargo bin directory to your `PATH`. - - **Note for automatic deployment** - - If you are using a script to do automatic deployments, we recommend that - you specify a semver version range for mdBook when you install it through - your script! - - This will constrain the server to install the latest **non-breaking** - version of mdBook and will prevent your books from failing to build because - we released a new version. - - You can also disable default features to speed up compile time. - - Example: - - ``` - cargo install mdbook --no-default-features --vers "^0.4.0" - ``` - -3. **From Git** - - The version published to crates.io will ever so slightly be behind the - version hosted here on GitHub. If you need the latest version you can build - the git version of mdBook yourself. Cargo makes this ***super easy***! - - ``` - cargo install --git https://github.com/rust-lang/mdBook.git mdbook - ``` - - Again, make sure to add the Cargo bin directory to your `PATH`. - -4. **For Contributions** - - If you want to contribute to mdBook you will have to clone the repository on - your local machine: - - ``` - git clone https://github.com/rust-lang/mdBook.git - ``` - - `cd` into `mdBook/` and run - - ``` - cargo build - ``` - - The resulting binary can be found in `mdBook/target/debug/` under the name - `mdBook` or `mdBook.exe`. - - -## Usage - -mdBook is primarily used as a command line tool, even though it exposes -all its functionality as a Rust crate for integration in other projects. - -Here are the main commands you will want to run. For a more exhaustive -explanation, check out the [User Guide]. - -- `mdbook init ` - - The init command will create a directory with the minimal boilerplate to - start with. If the `` parameter is omitted, the current - directory will be used. - - ``` - book-test/ - ├── book - └── src - ├── chapter_1.md - └── SUMMARY.md - ``` - - `book` and `src` are both directories. `src` contains the markdown files - that will be used to render the output to the `book` directory. - - Please, take a look at the [CLI docs] for more information and some neat tricks. - -- `mdbook build` - - This is the command you will run to render your book, it reads the - `SUMMARY.md` file to understand the structure of your book, takes the - markdown files in the source directory as input and outputs static html - pages that you can upload to a server. - -- `mdbook watch` - - When you run this command, mdbook will watch your markdown files to rebuild - the book on every change. This avoids having to come back to the terminal - to type `mdbook build` over and over again. - -- `mdbook serve` - - Does the same thing as `mdbook watch` but additionally serves the book at - `http://localhost:3000` (port is changeable) and reloads the browser when a - change occurs. - -- `mdbook clean` - - Delete directory in which generated book is located. - -### 3rd Party Plugins - -The way a book is loaded and rendered can be configured by the user via third -party plugins. These plugins are just programs which will be invoked during the -build process and are split into roughly two categories, *preprocessors* and -*renderers*. - -Preprocessors are used to transform a book before it is sent to a renderer. -One example would be to replace all occurrences of -`{{#include some_file.ext}}` with the contents of that file. Some existing -preprocessors are: - -- `index` - a built-in preprocessor (enabled by default) which will transform - all `README.md` chapters to `index.md` so `foo/README.md` can be accessed via - the url `foo/` when published to a browser -- `links` - a built-in preprocessor (enabled by default) for expanding the - `{{# playground}}` and `{{# include}}` helpers in a chapter. -- [`katex`](https://github.com/lzanini/mdbook-katex) - a preprocessor rendering LaTex equations to HTML. - -Renderers are given the final book so they can do something with it. This is -typically used for, as the name suggests, rendering the document in a particular -format, however there's nothing stopping a renderer from doing static analysis -of a book in order to validate links or run tests. Some existing renderers are: - -- `html` - the built-in renderer which will generate a HTML version of the book -- `markdown` - the built-in renderer (disabled by default) which will run - preprocessors then output the resulting Markdown. Useful for debugging - preprocessors. -- [`linkcheck`] - a backend which will check that all links are valid -- [`epub`] - an experimental EPUB generator -- [`man`] - a backend that generates manual pages from the book - -> **Note for Developers:** Feel free to send us a PR if you've developed your -> own plugin and want it mentioned here. - -A preprocessor or renderer is enabled by installing the appropriate program and -then mentioning it in the book's `book.toml` file. - -```console -$ cargo install mdbook-linkcheck -$ edit book.toml && cat book.toml -[book] -title = "My Awesome Book" -authors = ["Michael-F-Bryan"] - -[output.html] - -[output.linkcheck] # enable the "mdbook-linkcheck" renderer - -$ mdbook build -2018-10-20 13:57:51 [INFO] (mdbook::book): Book building has started -2018-10-20 13:57:51 [INFO] (mdbook::book): Running the html backend -2018-10-20 13:57:53 [INFO] (mdbook::book): Running the linkcheck backend -``` - -For more information on the plugin system, consult the [User Guide]. - -### As a library - -Aside from the command line interface, this crate can also be used as a -library. This means that you could integrate it in an existing project, like a -web-app for example. Since the command line interface is just a wrapper around -the library functionality, when you use this crate as a library you have full -access to all the functionality of the command line interface with an easy to -use API and more! - -See the [User Guide] and the [API docs] for more information. - -## Contributions - -Contributions are highly appreciated and encouraged! Don't hesitate to -participate to discussions in the issues, propose new features and ask for -help. - -If you are just starting out with Rust, there are a series of issues that are -tagged [E-Easy] and **we will gladly mentor you** so that you can successfully -go through the process of fixing a bug or adding a new feature! Let us know if -you need any help. - -For more info about contributing, check out our [contribution guide] which helps -you go through the build and contribution process! - -There is also a [rendered version][master-docs] of the latest API docs -available, for those hacking on `master`. - +If you are interested in contributing to the development of mdBook, check out the [Contribution Guide]. ## License All the code in this repository is released under the ***Mozilla Public License v2.0***, for more information take a look at the [LICENSE] file. - [User Guide]: https://rust-lang.github.io/mdBook/ -[API docs]: https://docs.rs/mdbook/*/mdbook/ -[E-Easy]: https://github.com/rust-lang/mdBook/issues?q=is%3Aopen+is%3Aissue+label%3AE-Easy [contribution guide]: https://github.com/rust-lang/mdBook/blob/master/CONTRIBUTING.md [LICENSE]: https://github.com/rust-lang/mdBook/blob/master/LICENSE -[releases]: https://github.com/rust-lang/mdBook/releases -[Rust]: https://www.rust-lang.org/ -[CLI docs]: http://rust-lang.github.io/mdBook/cli/init.html -[master-docs]: http://rust-lang.github.io/mdBook/ -[`linkcheck`]: https://crates.io/crates/mdbook-linkcheck -[`epub`]: https://crates.io/crates/mdbook-epub -[`man`]: https://crates.io/crates/mdbook-man diff --git a/guide/src/README.md b/guide/src/README.md index 7bbfd995..a3aeb68d 100644 --- a/guide/src/README.md +++ b/guide/src/README.md @@ -1,22 +1,30 @@ # Introduction -**mdBook** is a command line tool and Rust crate to create books with Markdown. The output resembles tools like Gitbook, -and is ideal for creating product or API documentation, tutorials, course materials or anything that requires a clean, -easily navigable and customizable presentation. mdBook is written in [Rust](https://www.rust-lang.org); its performance -and simplicity made it ideal for use as a tool to publish directly to hosted websites such -as [GitHub Pages](https://pages.github.com) via automation. This guide, in fact, serves as both the mdBook documentation -and a fine example of what mdBook produces. +**mdBook** is a command line tool to create books with Markdown. +It is ideal for creating product or API documentation, tutorials, course materials or anything that requires a clean, +easily navigable and customizable presentation. -mdBook includes built in support for both preprocessing your Markdown and alternative renderers for producing formats -other than HTML. These facilities also enable other functionality such as -validation. [Searching](https://crates.io/search?q=mdbook&sort=relevance) Rust's [crates.io](https://crates.io) is a -great way to discover more extensions. +* Lightweight [Markdown] syntax helps you focus more on your content +* Integrated [search] support +* Color [syntax highlighting] for code blocks for many different languages +* [Theme] files allow customizing the formatting of the output +* [Preprocessors] can provide extensions for custom syntax and modifying content +* [Backends] can render the output to multiple formats +* Written in [Rust] for speed, safety, and simplicity +* Automated testing of [Rust code samples] -## API Documentation +This guide is an example of what mdBook produces. +mdBook is used by the Rust programming language project, and [The Rust Programming Language][trpl] book is another fine example of mdBook in action. -In addition to the above features, mdBook also has a Rust [API](https://docs.rs/mdbook/*/mdbook/). This allows you to -write your own preprocessor or renderer, as well as incorporate mdBook features into other applications. -The [For Developers](for_developers) section of this guide contains more information and some examples. +[Markdown]: format/markdown.md +[search]: guide/reading.md#search +[syntax highlighting]: format/theme/syntax-highlighting.md +[theme]: format/theme/index.html +[preprocessors]: format/configuration/preprocessors.md +[backends]: format/configuration/renderers.md +[Rust]: https://www.rust-lang.org/ +[trpl]: https://doc.rust-lang.org/book/ +[Rust code samples]: cli/test.md ## Contributing diff --git a/guide/src/SUMMARY.md b/guide/src/SUMMARY.md index 181d7972..974d65fa 100644 --- a/guide/src/SUMMARY.md +++ b/guide/src/SUMMARY.md @@ -1,6 +1,15 @@ # Summary -- [Introduction](README.md) +[Introduction](README.md) + +# User Guide + +- [Installation](guide/installation.md) +- [Reading Books](guide/reading.md) +- [Creating a Book](guide/creating.md) + +# Reference Guide + - [Command Line Tool](cli/README.md) - [init](cli/init.md) - [build](cli/build.md) @@ -8,6 +17,7 @@ - [serve](cli/serve.md) - [test](cli/test.md) - [clean](cli/clean.md) + - [completions](cli/completions.md) - [Format](format/README.md) - [SUMMARY.md](format/summary.md) - [Draft chapter]() diff --git a/guide/src/cli/README.md b/guide/src/cli/README.md index 9fc7c2a9..2fbe3781 100644 --- a/guide/src/cli/README.md +++ b/guide/src/cli/README.md @@ -1,55 +1,14 @@ # Command Line Tool -mdBook can be used either as a command line tool or a [Rust -crate](https://crates.io/crates/mdbook). Let's focus on the command line tool -capabilities first. +The `mdbook` command-line tool is used to create and build books. +After you have [installed](../guide/installation.md) `mdbook`, you can run the `mdbook help` command in your terminal to view the available commands. -## Install From Binaries +This following sections provide in-depth information on the different commands available. -Precompiled binaries are provided for major platforms on a best-effort basis. -Visit [the releases page](https://github.com/rust-lang/mdBook/releases) -to download the appropriate version for your platform. - -## Install From Source - -mdBook can also be installed by compiling the source code on your local machine. - -### Pre-requisite - -mdBook is written in **[Rust](https://www.rust-lang.org/)** and therefore needs -to be compiled with **Cargo**. If you haven't already installed Rust, please go -ahead and [install it](https://www.rust-lang.org/tools/install) now. - -### Install Crates.io version - -Installing mdBook is relatively easy if you already have Rust and Cargo -installed. You just have to type this snippet in your terminal: - -```bash -cargo install mdbook -``` - -This will fetch the source code for the latest release from -[Crates.io](https://crates.io/) and compile it. You will have to add Cargo's -`bin` directory to your `PATH`. - -Run `mdbook help` in your terminal to verify if it works. Congratulations, you -have installed mdBook! - - -### Install Git version - -The **[git version](https://github.com/rust-lang/mdBook)** contains all -the latest bug-fixes and features, that will be released in the next version on -**Crates.io**, if you can't wait until the next release. You can build the git -version yourself. Open your terminal and navigate to the directory of you -choice. We need to clone the git repository and then build it with Cargo. - -```bash -git clone --depth=1 https://github.com/rust-lang/mdBook.git -cd mdBook -cargo build --release -``` - -The executable `mdbook` will be in the `./target/release` folder, this should be -added to the path. +* [`mdbook init `](init.md) — Creates a new book with minimal boilerplate to start with. +* [`mdbook build`](build.md) — Renders the book. +* [`mdbook watch`](watch.md) — Rebuilds the book any time a source file changes. +* [`mdbook serve`](serve.md) — Runs a web server to view the book, and rebuilds on changes. +* [`mdbook test`](test.md) — Tests Rust code samples. +* [`mdbook clean`](clean.md) — Deletes the rendered output. +* [`mdbook completions`](completions.md) — Support for shell auto-completion. diff --git a/guide/src/cli/completions.md b/guide/src/cli/completions.md new file mode 100644 index 00000000..1246b1ee --- /dev/null +++ b/guide/src/cli/completions.md @@ -0,0 +1,16 @@ +# The completions command + +The completions command is used to generate auto-completions for some common shells. +This means when you type `mdbook` in your shell, you can then press your shell's auto-complete key (usually the Tab key) and it may display what the valid options are, or finish partial input. + +The completions first need to be installed for your shell: + +```bash +mdbook completions bash > ~/.local/share/bash-completion/completions/mdbook +``` + +The command prints a completion script for the given shell. +Run `mdbook completions --help` for a list of supported shells. + +Where to place the completions depend on which shell you are using and your operating system. +Consult your shell's documentation for more information one where to place the script. diff --git a/guide/src/continuous-integration.md b/guide/src/continuous-integration.md index ce075040..baf510be 100644 --- a/guide/src/continuous-integration.md +++ b/guide/src/continuous-integration.md @@ -1,154 +1,121 @@ # Running `mdbook` in Continuous Integration -While the following examples use Travis CI, their principles should -straightforwardly transfer to other continuous integration providers as well. +There are a variety of services such as [GitHub Actions] or [GitLab CI/CD] which can be used to test and deploy your book automatically. -## Ensuring Your Book Builds and Tests Pass +The following provides some general guidelines on how to configure your service to run mdBook. +Specific recipes can be found at the [Automated Deployment] wiki page. -Here is a sample Travis CI `.travis.yml` configuration that ensures `mdbook -build` and `mdbook test` run successfully. The key to fast CI turnaround times -is caching `mdbook` installs, so that you aren't compiling `mdbook` on every CI -run. +[GitHub Actions]: https://docs.github.com/en/actions +[GitLab CI/CD]: https://docs.gitlab.com/ee/ci/ +[Automated Deployment]: https://github.com/rust-lang/mdBook/wiki/Automated-Deployment -```yaml -language: rust -sudo: false +## Installing mdBook -cache: - - cargo +There are several different strategies for installing mdBook. +The particular method depends on your needs and preferences. -rust: - - stable +### Pre-compiled binaries -before_script: - - (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update) - - (test -x $HOME/.cargo/bin/mdbook || cargo install --vers "^0.3" mdbook) - - cargo install-update -a +Perhaps the easiest method is to use the pre-compiled binaries found on the [GitHub Releases page][releases]. +A simple approach would be to use the popular `curl` CLI tool to download the executable: -script: - - mdbook build && mdbook test # In case of custom book path: mdbook build path/to/mybook && mdbook test path/to/mybook +```sh +mkdir bin +curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.14/mdbook-v0.4.14-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=bin +bin/mdbook build ``` -## Deploying Your Book to GitHub Pages +Some considerations for this approach: -Following these instructions will result in your book being published to GitHub -pages after a successful CI run on your repository's `master` branch. +* This is relatively fast, and does not necessarily require dealing with caching. +* This does not require installing Rust. +* Specifying a specific URL means you have to manually update your script to get a new version. + This may be a benefit if you want to lock to a specific version. + However, some users prefer to automatically get a newer version when they are published. +* You are reliant on the GitHub CDN being available. -First, create a new GitHub "Personal Access Token" with the "public_repo" -permissions (or "repo" for private repositories). Go to your repository's Travis -CI settings page and add an environment variable named `GITHUB_TOKEN` that is -marked secure and *not* shown in the logs. +[releases]: https://github.com/rust-lang/mdBook/releases -Whilst still in your repository's settings page, navigate to Options and change the -Source on GitHub pages to `gh-pages`. +### Building from source -Then, append this snippet to your `.travis.yml` and update the path to the -`book` directory: +Building from source will require having Rust installed. +Some services have Rust pre-installed, but if your service does not, you will need to add a step to install it. -```yaml -deploy: - provider: pages - skip-cleanup: true - github-token: $GITHUB_TOKEN - local-dir: book # In case of custom book path: path/to/mybook/book - keep-history: false - on: - branch: main +After Rust is installed, `cargo install` can be used to build and install mdBook. +We recommend using a SemVer version specifier so that you get the latest **non-breaking** version of mdBook. +For example: + +```sh +cargo install mdbook --no-default-features --features search --vers "^0.4" --locked ``` -That's it! +This includes several recommended options: -Note: Travis has a new [dplv2](https://blog.travis-ci.com/2019-08-27-deployment-tooling-dpl-v2-preview-release) configuration that is currently in beta. To use this new format, update your `.travis.yml` file to: +* `--no-default-features` — Disables features like the HTTP server used by `mdbook serve` that is likely not needed on CI. + This will speed up the build time significantly. +* `--features search` — Disabling default features means you should then manually enable features that you want, such as the built-in [search] capability. +* `--vers "^0.4"` — This will install the most recent version of the `0.4` series. + However, versions after like `0.5.0` won't be installed, as they may break your build. + Cargo will automatically upgrade mdBook if you have an older version already installed. +* `--locked` — This will use the dependencies that were used when mdBook was released. + Without `--locked`, it will use the latest version of all dependencies, which may include some fixes since the last release, but may also (rarely) cause build problems. -```yaml -language: rust -os: linux -dist: xenial +You will likely want to investigate caching options, as building mdBook can be somewhat slow. -cache: - - cargo +[search]: guide/reading.md#search -rust: - - stable +## Running tests -before_script: - - (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update) - - (test -x $HOME/.cargo/bin/mdbook || cargo install --vers "^0.3" mdbook) - - cargo install-update -a +You may want to run tests using [`mdbook test`] every time you push a change or create a pull request. +This can be used to validate Rust code examples in the book. -script: - - mdbook build && mdbook test # In case of custom book path: mdbook build path/to/mybook && mdbook test path/to/mybook - -deploy: - provider: pages - strategy: git - edge: true - cleanup: false - github-token: $GITHUB_TOKEN - local-dir: book # In case of custom book path: path/to/mybook/book - keep-history: false - on: - branch: main - target_branch: gh-pages +This will require having Rust installed. +Some services have Rust pre-installed, but if your service does not, you will need to add a step to install it. + +Other than making sure the appropriate version of Rust is installed, there's not much more than just running `mdbook test` from the book directory. + +You may also want to consider running other kinds of tests, like [mdbook-linkcheck] which will check for broken links. +Or if you have your own style checks, spell checker, or any other tests it might be good to run them in CI. + +[`mdbook test`]: cli/test.md +[mdbook-linkcheck]: https://github.com/Michael-F-Bryan/mdbook-linkcheck#continuous-integration + +## Deploying + +You may want to automatically deploy your book. +Some may want to do this with every time a change is pushed, and others may want to only deploy when a specific release is tagged. + +You'll also need to understand the specifics on how to push a change to your web service. +For example, [GitHub Pages] just requires committing the output onto a specific git branch. +Other services may require using something like SSH to connect to a remote server. + +The basic outline is that you need to run `mdbook build` to generate the output, and then transfer the files (which are in the `book` directory) to the correct location. + +You may then want to consider if you need to invalidate any caches on your web service. + +See the [Automated Deployment] wiki page for examples of various different services. + +[GitHub Pages]: https://docs.github.com/en/pages + +### 404 handling + +mdBook automatically generates a 404 page to be used for broken links. +The default output is a file named `404.html` at the root of the book. +Some services like [GitHub Pages] will automatically use this page for broken links. +For other services, you may want to consider configuring the web server to use this page as it will provide the reader navigation to get back to the book. + +If your book is not deployed at the root of the domain, then you should set the [`output.html.site-url`] setting so that the 404 page works correctly. +It needs to know where the book is deployed in order to load the static files (like CSS) correctly. +For example, this guide is deployed at , and the `site-url` setting is configured like this: + +```toml +# book.toml +[output.html] +site-url = "/mdBook/" ``` -### Deploying to GitHub Pages manually +You can customize the look of the 404 page by creating a file named `src/404.md` in your book. +If you want to use a different filename, you can set [`output.html.input-404`] to a different filename. -If your CI doesn't support GitHub pages, or you're deploying somewhere else -with integrations such as Github Pages: - *note: you may want to use different tmp dirs*: - -```console -$> git worktree add /tmp/book gh-pages -$> mdbook build -$> rm -rf /tmp/book/* # this won't delete the .git directory -$> cp -rp book/* /tmp/book/ -$> cd /tmp/book -$> git add -A -$> git commit 'new book message' -$> git push origin gh-pages -$> cd - -``` - -Or put this into a Makefile rule: - -```makefile -.PHONY: deploy -deploy: book - @echo "====> deploying to github" - git worktree add /tmp/book gh-pages - rm -rf /tmp/book/* - cp -rp book/* /tmp/book/ - cd /tmp/book && \ - git add -A && \ - git commit -m "deployed on $(shell date) by ${USER}" && \ - git push origin gh-pages -``` - -## Deploying Your Book to GitLab Pages -Inside your repository's project root, create a file named `.gitlab-ci.yml` with the following contents: -```yml -stages: - - deploy - -pages: - stage: deploy - image: rust - variables: - CARGO_HOME: $CI_PROJECT_DIR/cargo - before_script: - - export PATH="$PATH:$CARGO_HOME/bin" - - mdbook --version || cargo install mdbook - script: - - mdbook build -d public - rules: - - if: '$CI_COMMIT_REF_NAME == "master"' - artifacts: - paths: - - public - cache: - paths: - - $CARGO_HOME/bin -``` - -After you commit and push this new file, GitLab CI will run and your book will be available! +[`output.html.site-url`]: format/configuration/renderers.md#html-renderer-options +[`output.html.input-404`]: format/configuration/renderers.md#html-renderer-options diff --git a/guide/src/for_developers/README.md b/guide/src/for_developers/README.md index 14a56d55..d8b97709 100644 --- a/guide/src/for_developers/README.md +++ b/guide/src/for_developers/README.md @@ -24,8 +24,9 @@ The process of rendering a book project goes through several steps. exist - Load the book chapters into memory - Discover which preprocessors/backends should be used -2. Run the preprocessors -3. Call each backend in turn +2. For each backend: + 1. Run all the preprocessors. + 2. Call the backend to render the processed result. ## Using `mdbook` as a Library diff --git a/guide/src/for_developers/backends.md b/guide/src/for_developers/backends.md index fcc44a47..78326a36 100644 --- a/guide/src/for_developers/backends.md +++ b/guide/src/for_developers/backends.md @@ -5,23 +5,17 @@ rendering process. This program is passed a JSON representation of the book and configuration information via `stdin`. Once the backend receives this information it is free to do whatever it wants. -There are already several alternative backends on GitHub which can be used as a -rough example of how this is accomplished in practice. +See [Configuring Renderers](../format/configuration/renderers.md) for more information about using backends. -- [mdbook-linkcheck] - a simple program for verifying the book doesn't contain - any broken links -- [mdbook-epub] - an EPUB renderer -- [mdbook-test] - a program to run the book's contents through [rust-skeptic] to - verify everything compiles and runs correctly (similar to `rustdoc --test`) -- [mdbook-man] - generate manual pages from the book +The community has developed several backends. +See the [Third Party Plugins] wiki page for a list of available backends. + +## Setting Up This page will step you through creating your own alternative backend in the form of a simple word counting program. Although it will be written in Rust, there's no reason why it couldn't be accomplished using something like Python or Ruby. - -## Setting Up - First you'll want to create a new binary program and add `mdbook` as a dependency. @@ -330,39 +324,6 @@ generation or a warning). All environment variables are passed through to the backend, allowing you to use the usual `RUST_LOG` to control logging verbosity. -## Handling missing backends - -If you enable a backend that isn't installed, the default behavior is to throw an error: - -```text -The command `mdbook-wordcount` wasn't found, is the "wordcount" backend installed? -If you want to ignore this error when the "wordcount" backend is not installed, -set `optional = true` in the `[output.wordcount]` section of the book.toml configuration file. -``` - -This behavior can be changed by marking the backend as optional. - -```diff - [book] - title = "mdBook Documentation" - description = "Create book from markdown files. Like Gitbook but implemented in Rust" - authors = ["Mathieu David", "Michael-F-Bryan"] - - [output.html] - - [output.wordcount] - command = "python /path/to/wordcount.py" -+ optional = true -``` - -This demotes the error to a warning, and it will instead look like this: - -```text -The command was not found, but was marked as optional. - Command: wordcount -``` - - ## Wrapping Up Although contrived, hopefully this example was enough to show how you'd create @@ -375,11 +336,7 @@ as a good example of how it's done in real life, so feel free to skim through the source code or ask questions. -[mdbook-linkcheck]: https://github.com/Michael-F-Bryan/mdbook-linkcheck -[mdbook-epub]: https://github.com/Michael-F-Bryan/mdbook-epub -[mdbook-test]: https://github.com/Michael-F-Bryan/mdbook-test -[mdbook-man]: https://github.com/vv9k/mdbook-man -[rust-skeptic]: https://github.com/budziq/rust-skeptic +[Third Party Plugins]: https://github.com/rust-lang/mdBook/wiki/Third-party-plugins [`RenderContext`]: https://docs.rs/mdbook/*/mdbook/renderer/struct.RenderContext.html [`RenderContext::from_json()`]: https://docs.rs/mdbook/*/mdbook/renderer/struct.RenderContext.html#method.from_json [`semver`]: https://crates.io/crates/semver diff --git a/guide/src/for_developers/preprocessors.md b/guide/src/for_developers/preprocessors.md index 074d1c3c..0054f242 100644 --- a/guide/src/for_developers/preprocessors.md +++ b/guide/src/for_developers/preprocessors.md @@ -5,35 +5,18 @@ book is loaded and before it gets rendered, allowing you to update and mutate the book. Possible use cases are: - Creating custom helpers like `\{{#include /path/to/file.md}}` -- Updating links so `[some chapter](some_chapter.md)` is automatically changed - to `[some chapter](some_chapter.html)` for the HTML renderer - Substituting in latex-style expressions (`$$ \frac{1}{3} $$`) with their mathjax equivalents +See [Configuring Preprocessors](../format/configuration/preprocessors.md) for more information about using preprocessors. ## Hooking Into MDBook MDBook uses a fairly simple mechanism for discovering third party plugins. -A new table is added to `book.toml` (e.g. `preprocessor.foo` for the `foo` +A new table is added to `book.toml` (e.g. `[preprocessor.foo]` for the `foo` preprocessor) and then `mdbook` will try to invoke the `mdbook-foo` program as part of the build process. -A preprocessor can be hard-coded to specify which backend(s) it should be run -for with the `preprocessor.foo.renderer` key. For example, it doesn't make sense for -[MathJax](../format/mathjax.md) to be used for non-HTML renderers. - -```toml -[book] -title = "My Book" -authors = ["Michael-F-Bryan"] - -[preprocessor.foo] -# The command can also be specified manually -command = "python3 /path/to/foo.py" -# Only run the `foo` preprocessor for the HTML and EPUB renderer -renderer = ["html", "epub"] -``` - Once the preprocessor has been defined and the build process starts, mdBook executes the command defined in the `preprocessor.foo.command` key twice. The first time it runs the preprocessor to determine if it supports the given renderer. mdBook passes two arguments to the process: the first argument is the string `supports` and the second argument is the renderer name. diff --git a/guide/src/format/configuration/general.md b/guide/src/format/configuration/general.md index 1c3884fb..b1fe49e4 100644 --- a/guide/src/format/configuration/general.md +++ b/guide/src/format/configuration/general.md @@ -62,6 +62,11 @@ language = "en" Options for the Rust language, relevant to running tests and playground integration. +```toml +[rust] +edition = "2015" # the default edition for code blocks +``` + - **edition**: Rust edition to use by default for the code snippets. Default is "2015". Individual code blocks can be controlled with the `edition2015`, `edition2018` or `edition2021` annotations, such as: @@ -77,8 +82,16 @@ integration. This controls the build process of your book. +```toml +[build] +build-dir = "book" # the directory where the output is placed +create-missing = true # whether or not to create missing pages +use-default-preprocessors = true # use the default preprocessors +``` + - **build-dir:** The directory to put the rendered book in. By default this is `book/` in the book's root directory. + This can overridden with the `--dest-dir` CLI option. - **create-missing:** By default, any missing files specified in `SUMMARY.md` will be created when the book is built (i.e. `create-missing = true`). If this is `false` then the build process will instead exit with an error if any files diff --git a/guide/src/format/configuration/preprocessors.md b/guide/src/format/configuration/preprocessors.md index 8d3e1dc6..f44bdd4f 100644 --- a/guide/src/format/configuration/preprocessors.md +++ b/guide/src/format/configuration/preprocessors.md @@ -1,51 +1,58 @@ # Configuring Preprocessors -The following preprocessors are available and included by default: +Preprocessors are extensions that can modify the raw Markdown source before it gets sent to the renderer. -- `links`: Expand the `{{ #playground }}`, `{{ #include }}`, and `{{ #rustdoc_include }}` handlebars +The following preprocessors are built-in and included by default: + +- `links`: Expands the `{{ #playground }}`, `{{ #include }}`, and `{{ #rustdoc_include }}` handlebars helpers in a chapter to include the contents of a file. + See [Including files] for more. - `index`: Convert all chapter files named `README.md` into `index.md`. That is to say, all `README.md` would be rendered to an index file `index.html` in the rendered book. +The built-in preprocessors can be disabled with the [`build.use-default-preprocessors`] config option. -**book.toml** -```toml -[build] -build-dir = "build" -create-missing = false +The community has developed several preprocessors. +See the [Third Party Plugins] wiki page for a list of available preprocessors. -[preprocessor.links] +For information on how to create a new preprocessor, see the [Preprocessors for Developers] chapter. -[preprocessor.index] -``` +[Including files]: ../mdbook.md#including-files +[`build.use-default-preprocessors`]: general.md#build-options +[Third Party Plugins]: https://github.com/rust-lang/mdBook/wiki/Third-party-plugins +[Preprocessors for Developers]: ../../for_developers/preprocessors.md -### Custom Preprocessor Configuration +## Custom Preprocessor Configuration -Like renderers, preprocessor will need to be given its own table (e.g. -`[preprocessor.mathjax]`). In the section, you may then pass extra -configuration to the preprocessor by adding key-value pairs to the table. - -For example +Preprocessors can be added by including a `preprocessor` table in `book.toml` with the name of the preprocessor. +For example, if you have a preprocessor called `mdbook-example`, then you can include it with: ```toml -[preprocessor.links] -# set the renderers this preprocessor will run for -renderers = ["html"] -some_extra_feature = true +[preprocessor.example] ``` -#### Locking a Preprocessor dependency to a renderer +With this table, mdBook will execute the `mdbook-example` preprocessor. + +This table can include additional key-value pairs that are specific to the preprocessor. +For example, if our example prepocessor needed some extra configuration options: + +```toml +[preprocessor.example] +some-extra-feature = true +``` + +## Locking a Preprocessor dependency to a renderer You can explicitly specify that a preprocessor should run for a renderer by binding the two together. ```toml -[preprocessor.mathjax] -renderers = ["html"] # mathjax only makes sense with the HTML renderer +[preprocessor.example] +renderers = ["html"] # example preprocessor only runs with the HTML renderer ``` -### Provide Your Own Command +## Provide Your Own Command By default when you add a `[preprocessor.foo]` table to your `book.toml` file, `mdbook` will try to invoke the `mdbook-foo` executable. If you want to use a @@ -57,7 +64,7 @@ be overridden by adding a `command` field. command = "python random.py" ``` -### Require A Certain Order +## Require A Certain Order The order in which preprocessors are run can be controlled with the `before` and `after` fields. For example, suppose you want your `linenos` preprocessor to process lines that may have been `{{#include}}`d; then you want it to run after the built-in `links` preprocessor, which you can require using either the `before` or `after` field: diff --git a/guide/src/format/configuration/renderers.md b/guide/src/format/configuration/renderers.md index df105c8d..a29265e4 100644 --- a/guide/src/format/configuration/renderers.md +++ b/guide/src/format/configuration/renderers.md @@ -1,9 +1,115 @@ # Configuring Renderers -### HTML renderer options +Renderers (also called "backends") are responsible for creating the output of the book. -The HTML renderer has a couple of options as well. All the options for the -renderer need to be specified under the TOML table `[output.html]`. +The following backends are built-in: + +* [`html`](#html-renderer-options) — This renders the book to HTML. + This is enabled by default if no other `[output]` tables are defined in `book.toml`. +* [`markdown`](#markdown-renderer) — This outputs the book as markdown after running the preprocessors. + This is useful for debugging preprocessors. + +The community has developed several backends. +See the [Third Party Plugins] wiki page for a list of available backends. + +For information on how to create a new backend, see the [Backends for Developers] chapter. + +[Third Party Plugins]: https://github.com/rust-lang/mdBook/wiki/Third-party-plugins +[Backends for Developers]: ../../for_developers/backends.md + +## Output tables + +Backends can be added by including a `output` table in `book.toml` with the name of the backend. +For example, if you have a backend called `mdbook-wordcount`, then you can include it with: + +```toml +[output.wordcount] +``` + +With this table, mdBook will execute the `mdbook-wordcount` backend. + +This table can include additional key-value pairs that are specific to the backend. +For example, if our example backend needed some extra configuration options: + +```toml +[output.wordcount] +ignores = ["Example Chapter"] +``` + +If you define any `[output]` tables, then the `html` backend is not enabled by default. +If you want to keep the `html` backend running, then just include it in the `book.toml` file. +For example: + +```toml +[book] +title = "My Awesome Book" + +[output.wordcount] + +[output.html] +``` + +If more than one `output` table is included, this changes the behavior for the layout of the output directory. +If there is only one backend, then it places its output directly in the `book` directory (see [`build.build-dir`] to override this location). +If there is more than one backend, then each backend is placed in a separate directory underneath `book`. +For example, the above would have directories `book/html` and `book/wordcount`. + +[`build.build-dir`]: general.md#build-options + +### Custom backend commands + +By default when you add an `[output.foo]` table to your `book.toml` file, +`mdbook` will try to invoke the `mdbook-foo` executable. +If you want to use a different program name or pass in command-line arguments, +this behaviour can be overridden by adding a `command` field. + +```toml +[output.random] +command = "python random.py" +``` + +### Optional backends + +If you enable a backend that isn't installed, the default behavior is to throw an error. +This behavior can be changed by marking the backend as optional: + +```toml +[output.wordcount] +optional = true +``` + +This demotes the error to a warning. + + +## HTML renderer options + +The HTML renderer has a variety of options detailed below. +They should be specified in the `[output.html]` table of the `book.toml` file. + +```toml +# Example book.toml file with all output options. +[book] +title = "Example book" +authors = ["John Doe", "Jane Doe"] +description = "The example book covers examples." + +[output.html] +theme = "my-theme" +default-theme = "light" +preferred-dark-theme = "navy" +curly-quotes = true +mathjax-support = false +copy-fonts = true +additional-css = ["custom.css", "custom2.css"] +additional-js = ["custom.js"] +no-section-label = false +git-repository-url = "https://github.com/rust-lang/mdBook" +git-repository-icon = "fa-github" +edit-url-template = "https://github.com/rust-lang/mdBook/edit/master/guide/{path}" +site-url = "/example-book/" +cname = "myproject.rs" +input-404 = "not-found.md" +``` The following configuration options are available: @@ -30,34 +136,22 @@ The following configuration options are available: - **additional-js:** If you need to add some behaviour to your book without removing the current behaviour, you can specify a set of JavaScript files that will be loaded alongside the default one. -- **print:** A subtable for configuration print settings. mdBook by default adds - support for printing out the book as a single page. This is accessed using the - print icon on the top right of the book. -- **no-section-label:** mdBook by defaults adds section label in table of +- **no-section-label:** mdBook by defaults adds numeric section labels in the table of contents column. For example, "1.", "2.1". Set this option to true to disable those labels. Defaults to `false`. -- **fold:** A subtable for configuring sidebar section-folding behavior. -- **playground:** A subtable for configuring various playground settings. -- **search:** A subtable for configuring the in-browser search functionality. - mdBook must be compiled with the `search` feature enabled (on by default). - **git-repository-url:** A url to the git repository for the book. If provided an icon link will be output in the menu bar of the book. - **git-repository-icon:** The FontAwesome icon class to use for the git - repository link. Defaults to `fa-github`. + repository link. Defaults to `fa-github` which looks like . + If you are not using GitHub, another option to consider is `fa-code-fork` which looks like . - **edit-url-template:** Edit url template, when provided shows a - "Suggest an edit" button for directly jumping to editing the currently + "Suggest an edit" button (which looks like ) for directly jumping to editing the currently viewed page. For e.g. GitHub projects set this to `https://github.com///edit/master/{path}` or for Bitbucket projects set it to `https://bitbucket.org///src/master/{path}?mode=edit` where {path} will be replaced with the full path of the file in the repository. -- **redirect:** A subtable used for generating redirects when a page is moved. - The table contains key-value pairs where the key is where the redirect file - needs to be created, as an absolute path from the build directory, (e.g. - `/appendices/bibliography.html`). The value can be any valid URI the - browser should navigate to (e.g. `https://rust-lang.org/`, - `/overview.html`, or `../bibliography.html`). - **input-404:** The name of the markdown file used for missing files. The corresponding output file will be the same, with the extension replaced with `html`. Defaults to `404.md`. @@ -71,19 +165,47 @@ The following configuration options are available: [custom domain]: https://docs.github.com/en/github/working-with-github-pages/managing-a-custom-domain-for-your-github-pages-site -Available configuration options for the `[output.html.print]` table: +### `[output.html.print]` + +The `[output.html.print]` table provides options for controlling the printable output. +By default, mdBook will include an icon on the top right of the book (which looks like ) that will print the book as a single page. + +```toml +[output.html.print] +enable = true # include support for printable output +``` - **enable:** Enable print support. When `false`, all print support will not be rendered. Defaults to `true`. -Available configuration options for the `[output.html.fold]` table: +### `[output.html.fold]` + +The `[output.html.fold]` table provides options for controlling folding of the chapter listing in the navigation sidebar. + +```toml +[output.html.fold] +enable = false # whether or not to enable section folding +level = 0 # the depth to start folding +``` - **enable:** Enable section-folding. When off, all folds are open. Defaults to `false`. - **level:** The higher the more folded regions are open. When level is 0, all folds are closed. Defaults to `0`. -Available configuration options for the `[output.html.playground]` table: +### `[output.html.playground]` + +The `[output.html.playground]` table provides options for controlling Rust sample code blocks, and their integration with the [Rust Playground]. + +[Rust Playground]: https://play.rust-lang.org/ + +```toml +[output.html.playground] +editable = false # allows editing the source code +copyable = true # include the copy button for copying code snippets +copy-js = true # includes the JavaScript for the code editor +line-numbers = false # displays line numbers for editable code +``` - **editable:** Allow editing the source code. Defaults to `false`. - **copyable:** Display the copy button on code snippets. Defaults to `true`. @@ -93,7 +215,26 @@ Available configuration options for the `[output.html.playground]` table: [Ace]: https://ace.c9.io/ -Available configuration options for the `[output.html.search]` table: +### `[output.html.search]` + +The `[output.html.search]` table provides options for controlling the built-in text [search]. +mdBook must be compiled with the `search` feature enabled (on by default). + +[search]: ../../guide/reading.md#search + +```toml +[output.html.search] +enable = true # enables the search feature +limit-results = 30 # maximum number of search results +teaser-word-count = 30 # number of words used for a search result teaser +use-boolean-and = true # multiple search terms must all match +boost-title = 2 # ranking boost factor for matches in headers +boost-hierarchy = 1 # ranking boost factor for matches in page names +boost-paragraph = 1 # ranking boost factor for matches in text +expand = true # partial words will match longer terms +heading-split-level = 3 # link results to heading levels +copy-js = true # include Javascript code for search +``` - **enable:** Enables the search feature. Defaults to `true`. - **limit-results:** The maximum number of search results. Defaults to `30`. @@ -116,61 +257,24 @@ Available configuration options for the `[output.html.search]` table: - **copy-js:** Copy JavaScript files for the search implementation to the output directory. Defaults to `true`. -This shows all available HTML output options in the **book.toml**: +### `[output.html.redirect]` + +The `[output.html.redirect]` table provides a way to add redirects. +This is useful when you move, rename, or remove a page to ensure that links to the old URL will go to the new location. ```toml -[book] -title = "Example book" -authors = ["John Doe", "Jane Doe"] -description = "The example book covers examples." - -[output.html] -theme = "my-theme" -default-theme = "light" -preferred-dark-theme = "navy" -curly-quotes = true -mathjax-support = false -copy-fonts = true -additional-css = ["custom.css", "custom2.css"] -additional-js = ["custom.js"] -no-section-label = false -git-repository-url = "https://github.com/rust-lang/mdBook" -git-repository-icon = "fa-github" -edit-url-template = "https://github.com/rust-lang/mdBook/edit/master/guide/{path}" -site-url = "/example-book/" -cname = "myproject.rs" -input-404 = "not-found.md" - -[output.html.print] -enable = true - -[output.html.fold] -enable = false -level = 0 - -[output.html.playground] -editable = false -copy-js = true -line-numbers = false - -[output.html.search] -enable = true -limit-results = 30 -teaser-word-count = 30 -use-boolean-and = true -boost-title = 2 -boost-hierarchy = 1 -boost-paragraph = 1 -expand = true -heading-split-level = 3 -copy-js = true - [output.html.redirect] "/appendices/bibliography.html" = "https://rustc-dev-guide.rust-lang.org/appendix/bibliography.html" "/other-installation-methods.html" = "../infra/other-installation-methods.html" ``` -### Markdown Renderer +The table contains key-value pairs where the key is where the redirect file needs to be created, as an absolute path from the build directory, (e.g. `/appendices/bibliography.html`). +The value can be any valid URI the browser should navigate to (e.g. `https://rust-lang.org/`, `/overview.html`, or `../bibliography.html`). + +This will generate an HTML page which will automatically redirect to the given location. +Note that the source location does not support `#` anchor redirects. + +## Markdown Renderer The Markdown renderer will run preprocessors and then output the resulting Markdown. This is mostly useful for debugging preprocessors, especially in @@ -189,20 +293,3 @@ only whether it is enabled or disabled. See [the preprocessors documentation](preprocessors.md) for how to specify which preprocessors should run before the Markdown renderer. - -### Custom Renderers - -A custom renderer can be enabled by adding a `[output.foo]` table to your -`book.toml`. Similar to [preprocessors](preprocessors.md) this will -instruct `mdbook` to pass a representation of the book to `mdbook-foo` for -rendering. See the [alternative backends] chapter for more detail. - -The custom renderer has access to all the fields within its table (i.e. -anything under `[output.foo]`). mdBook checks for two common fields: - -- **command:** The command to execute for this custom renderer. Defaults to - the name of the renderer with the `mdbook-` prefix (such as `mdbook-foo`). -- **optional:** If `true`, then the command will be ignored if it is not - installed, otherwise mdBook will fail with an error. Defaults to `false`. - -[alternative backends]: ../../for_developers/backends.md diff --git a/guide/src/format/markdown.md b/guide/src/format/markdown.md index 74ecaf56..963a1538 100644 --- a/guide/src/format/markdown.md +++ b/guide/src/format/markdown.md @@ -1,7 +1,7 @@ # Markdown -mdBook's [parser](https://github.com/raphlinus/pulldown-cmark) adheres to the [CommonMark](https://commonmark.org/) -specification. You can take a quick [tutorial](https://commonmark.org/help/tutorial/), +mdBook's [parser](https://github.com/raphlinus/pulldown-cmark) adheres to the [CommonMark](https://commonmark.org/) specification with some extensions described below. +You can take a quick [tutorial](https://commonmark.org/help/tutorial/), or [try out](https://spec.commonmark.org/dingus/) CommonMark in real time. A complete Markdown overview is out of scope for this documentation, but below is a high level overview of some of the basics. For a more in-depth experience, check out the [Markdown Guide](https://www.markdownguide.org). @@ -84,6 +84,20 @@ Read about [mdBook](mdBook.md). A bare url: . +---- + +Relative links that end with `.md` will be converted to the `.html` extension. +It is recommended to use `.md` links when possible. +This is useful when viewing the Markdown file outside of mdBook, for example on GitHub or GitLab which render Markdown automatically. + +Links to `README.md` will be converted to `index.html`. +This is done since some services like GitHub render README files automatically, but web servers typically expect the root file to be called `index.html`. + +You can link to individual headings with `#` fragments. +For example, `mdbook.md#text-and-paragraphs` would link to the [Text and Paragraphs](#text-and-paragraphs) section above. +The ID is created by transforming the heading such as converting to lowercase and replacing spaces with dashes. +You can click on any heading and look at the URL in your browser to see what the fragment looks like. + ## Images Including images is simply a matter of including a link to them, much like in the _Links_ section above. The following markdown @@ -103,5 +117,106 @@ Which, of course displays the image like so: ![The Rust Logo](images/rust-logo-blk.svg) +## Extensions -See the [Markdown Guide Basic Syntax](https://www.markdownguide.org/basic-syntax/) document for more. +mdBook has several extensions beyond the standard CommonMark specification. + +### Strikethrough + +Text may be rendered with a horizontal line through the center by wrapping the +text with two tilde characters on each side: + +```text +An example of ~~strikethrough text~~. +``` + +This example will render as: + +> An example of ~~strikethrough text~~. + +This follows the [GitHub Strikethrough extension][strikethrough]. + +### Footnotes + +A footnote generates a small numbered link in the text which when clicked +takes the reader to the footnote text at the bottom of the item. The footnote +label is written similarly to a link reference with a caret at the front. The +footnote text is written like a link reference definition, with the text +following the label. Example: + +```text +This is an example of a footnote[^note]. + +[^note]: This text is the contents of the footnote, which will be rendered + towards the bottom. +``` + +This example will render as: + +> This is an example of a footnote[^note]. +> +> [^note]: This text is the contents of the footnote, which will be rendered +> towards the bottom. + +The footnotes are automatically numbered based on the order the footnotes are +written. + +### Tables + +Tables can be written using pipes and dashes to draw the rows and columns of +the table. These will be translated to HTML table matching the shape. Example: + +```text +| Header1 | Header2 | +|---------|---------| +| abc | def | +``` + +This example will render similarly to this: + +| Header1 | Header2 | +|---------|---------| +| abc | def | + +See the specification for the [GitHub Tables extension][tables] for more +details on the exact syntax supported. + +### Task lists + +Task lists can be used as a checklist of items that have been completed. +Example: + +```md +- [x] Complete task +- [ ] Incomplete task +``` + +This will render as: + +> - [x] Complete task +> - [ ] Incomplete task + +See the specification for the [task list extension] for more details. + +### Smart punctuation + +Some ASCII punctuation sequences will be automatically turned into fancy Unicode +characters: + +| ASCII sequence | Unicode | +|----------------|---------| +| `--` | – | +| `---` | — | +| `...` | … | +| `"` | “ or ”, depending on context | +| `'` | ‘ or ’, depending on context | + +So, no need to manually enter those Unicode characters! + +This feature is disabled by default. +To enable it, see the [`output.html.curly-quotes`] config option. + +[strikethrough]: https://github.github.com/gfm/#strikethrough-extension- +[tables]: https://github.github.com/gfm/#tables-extension- +[task list extension]: https://github.github.com/gfm/#task-list-items-extension- +[`output.html.curly-quotes`]: configuration/renderers.md#html-renderer-options diff --git a/guide/src/format/mdbook.md b/guide/src/format/mdbook.md index 6c691473..e4c76f1b 100644 --- a/guide/src/format/mdbook.md +++ b/guide/src/format/mdbook.md @@ -4,6 +4,7 @@ There is a feature in mdBook that lets you hide code lines by prepending them with a `#` [like you would with Rustdoc][rustdoc-hide]. +This currently only works with Rust language code blocks. [rustdoc-hide]: https://doc.rust-lang.org/stable/rustdoc/documentation-tests.html#hiding-portions-of-the-example @@ -27,6 +28,60 @@ Will render as # } ``` +The code block has an eyeball icon () which will toggle the visibility of the hidden lines. + +## Rust Playground + +Rust language code blocks will automatically get a play button () which will execute the code and display the output just below the code block. +This works by sending the code to the [Rust Playground]. + +```rust +println!("Hello, World!"); +``` + +If there is no `main` function, then the code is automatically wrapped inside one. + +If you wish to disable the play button, you can include the `noplayground` option on the code block like this: + +~~~markdown +```rust,noplayground +let mut name = String::new(); +std::io::stdin().read_line(&mut name).expect("failed to read line"); +println!("Hello {}!", name); +``` +~~~ + +## Rust code block attributes + +Additional attributes can be included in Rust code blocks with comma, space, or tab-separated terms just after the language term. For example: + +~~~markdown +```rust,ignore +# This example won't be tested. +panic!("oops!"); +``` +~~~ + +These are particularly important when using [`mdbook test`] to test Rust examples. +These use the same attributes as [rustdoc attributes], with a few additions: + +* `editable` — Enables the [editor]. +* `noplayground` — Removes the play button, but will still be tested. +* `mdbook-runnable` — Forces the play button to be displayed. + This is intended to be combined with the `ignore` attribute for examples that should not be tested, but you want to allow the reader to run. +* `ignore` — Will not be tested and no play button is shown, but it is still highlighted as Rust syntax. +* `should_panic` — When executed, it should produce a panic. +* `no_run` — The code is compiled when tested, but it is not run. + The play button is also not shown. +* `compile_fail` — The code should fail to compile. +* `edition2015`, `edition2018`, `edition2021` — Forces the use of a specific Rust edition. + See [`rust.edition`] to set this globally. + +[`mdbook test`]: ../cli/test.md +[rustdoc attributes]: https://doc.rust-lang.org/rustdoc/documentation-tests.html#attributes +[editor]: theme/editor.md +[`rust.edition`]: configuration/general.md#rust-options + ## Including files With the following syntax, you can include files into your book: @@ -191,6 +246,17 @@ Here is what a rendered code snippet looks like: {{#playground example.rs}} +Any additional values passed after the filename will be included as attributes of the code block. +For example `\{{#playground example.rs editable}}` will create the code block like the following: + +~~~markdown +```rust,editable +# Contents of example.rs here. +``` +~~~ + +And the `editable` attribute will enable the [editor] as described at [Rust code block attributes](#rust-code-block-attributes). + [Rust Playground]: https://play.rust-lang.org/ ## Controlling page \ diff --git a/guide/src/format/theme/README.md b/guide/src/format/theme/README.md index c298272a..4a776e60 100644 --- a/guide/src/format/theme/README.md +++ b/guide/src/format/theme/README.md @@ -38,6 +38,10 @@ template and only add / modify what you need. You can copy the default theme into your source directory automatically by using `mdbook init --theme` and just remove the files you don't want to override. +`mdbook init --theme` will not create every file listed above. +Some files, such as `head.hbs`, do not have built-in equivalents. +Just create the file if you need it. + If you completely replace all built-in themes, be sure to also set [`output.html.preferred-dark-theme`] in the config, which defaults to the built-in `navy` theme. diff --git a/guide/src/format/theme/editor.md b/guide/src/format/theme/editor.md index 04f6cc91..9294dd44 100644 --- a/guide/src/format/theme/editor.md +++ b/guide/src/format/theme/editor.md @@ -12,12 +12,14 @@ editable = true To make a specific block available for editing, the attribute `editable` needs to be added to it: -
```rust,editable
+~~~markdown
+```rust,editable
 fn main() {
     let number = 5;
     print!("{}", number);
 }
-```
+``` +~~~ The above will result in this editable playground: diff --git a/guide/src/guide/README.md b/guide/src/guide/README.md new file mode 100644 index 00000000..90deb10e --- /dev/null +++ b/guide/src/guide/README.md @@ -0,0 +1,7 @@ +# User Guide + +This user guide provides an introduction to basic concepts of using mdBook. + +- [Installation](installation.md) +- [Reading Books](reading.md) +- [Creating a Book](creating.md) diff --git a/guide/src/guide/creating.md b/guide/src/guide/creating.md new file mode 100644 index 00000000..6e0df0a8 --- /dev/null +++ b/guide/src/guide/creating.md @@ -0,0 +1,109 @@ +# Creating a Book + +Once you have the `mdbook` CLI tool installed, you can use it to create and render a book. + +## Initializing a book + +The `mdbook init` command will create a new directory containing an empty book for you to get started. +Give it the name of the directory that you want to create: + +```sh +mdbook init my-first-book +``` + +It will ask a few questions before generating the book. +After answering the questions, you can change the current directory into the new book: + +```sh +cd my-first-book +``` + +There are several ways to render a book, but one of the easiest methods is to use the `serve` command, which will build your book and start a local webserver: + +```sh +mdbook serve --open +``` + +The `--open` option will open your default web browser to view your new book. +You can leave the server running even while you edit the content of the book, and `mdbook` will automatically rebuild the output *and* automatically refresh your web browser. + +Check out the [CLI Guide](../cli/index.html) for more information about other `mdbook` commands and CLI options. + +## Anatomy of a book + +A book is built from several files which define the settings and layout of the book. + +### `book.toml` + +In the root of your book, there is a `book.toml` file which contains settings for describing how to build your book. +This is written in the [TOML markup language](https://toml.io/). +The default settings are usually good enough to get you started. +When you are interested in exploring more features and options that mdBook provides, check out the [Configuration chapter](../format/configuration/index.html) for more details. + +A very basic `book.toml` can be as simple as this: + +```toml +[book] +title = "My First Book" +``` + +### `SUMMARY.md` + +The next major part of a book is the summary file located at `src/SUMMARY.md`. +This file contains a list of all the chapters in the book. +Before a chapter can be viewed, it must be added to this list. + +Here's a basic summary file with a few chapters: + +```md +# Summary + +[Introduction](README.md) + +- [My First Chapter](my-first-chapter.md) +- [Nested example](nested/README.md) + - [Sub-chapter](nested/sub-chapter.md) +``` + +Try opening up `src/SUMMARY.md` in your editor and adding a few chapters. +If any of the chapter files do not exist, `mdbook` will automatically create them for you. + +For more details on other formatting options for the summary file, check out the [Summary chapter](../format/summary.md). + +### Source files + +The content of your book is all contained in the `src` directory. +Each chapter is a separate Markdown file. +Typically, each chapter starts with a level 1 heading with the title of the chapter. + +```md +# My First Chapter + +Fill out your content here. +``` + +The precise layout of the files is up to you. +The organization of the files will correspond to the HTML files generated, so keep in mind that the file layout is part of the URL of each chapter. + +While the `mdbook serve` command is running, you can open any of the chapter files and start editing them. +Each time you save the file, `mdbook` will rebuild the book and refresh your web browser. + +Check out the [Markdown chapter](../format/markdown.md) for more information on formatting the content of your chapters. + +All other files in the `src` directory will be included in the output. +So if you have images or other static files, just include them somewhere in the `src` directory. + +## Publishing a book + +Once you've written your book, you may want to host it somewhere for others to view. +The first step is to build the output of the book. +This can be done with the `mbdook build` command in the same directory where the `book.toml` file is located: + +```sh +mdbook build +``` + +This will generate a directory named `book` which contains the HTML content of your book. +You can then place this directory on any web server to host it. + +For more information about publishing and deploying, check out the [Continuous Integration chapter](../continuous-integration.md) for more. diff --git a/guide/src/guide/installation.md b/guide/src/guide/installation.md new file mode 100644 index 00000000..b68f807a --- /dev/null +++ b/guide/src/guide/installation.md @@ -0,0 +1,50 @@ +# Installation + +There are multiple ways to install the mdBook CLI tool. +Choose any one of the methods below that best suit your needs. +If you are installing mdBook for automatic deployment, check out the [continuous integration] chapter for more examples on how to install. + +[continuous integration]: ../continuous-integration.md + +## Pre-compiled binaries + +Executable binaries are available for download on the [GitHub Releases page][releases]. +Download the binary for your platform (Windows, macOS, or Linux) and extract the archive. +The archive contains an `mdbook` executable which you can run to build your books. + +To make it easier to run, put the path to the binary into your `PATH`. + +[releases]: https://github.com/rust-lang/mdBook/releases + +## Build from source using Rust + +To build the `mdbook` executable from source, you will first need to install Rust and Cargo. +Follow the instructions on the [Rust installation page]. +mdBook currently requires at least Rust version 1.46. + +Once you have installed Rust, the following command can be used to build and install mdBook: + +```sh +cargo install mdbook +``` + +This will automatically download mdBook from [crates.io], build it, and install it in Cargo's global binary directory (`~/.cargo/bin/` by default). + +[Rust installation page]: https://www.rust-lang.org/tools/install +[crates.io]: https://crates.io/ + +### Installing the latest master version + +The version published to crates.io will ever so slightly be behind the version hosted on GitHub. +If you need the latest version you can build the git version of mdBook yourself. +Cargo makes this ***super easy***! + +```sh +cargo install --git https://github.com/rust-lang/mdBook.git mdbook +``` + +Again, make sure to add the Cargo bin directory to your `PATH`. + +If you are interested in making modifications to mdBook itself, check out the [Contributing Guide] for more information. + +[Contributing Guide]: https://github.com/rust-lang/mdBook/blob/master/CONTRIBUTING.md diff --git a/guide/src/guide/reading.md b/guide/src/guide/reading.md new file mode 100644 index 00000000..cab3a865 --- /dev/null +++ b/guide/src/guide/reading.md @@ -0,0 +1,74 @@ +# Reading Books + +This chapter gives an introduction on how to interact with a book produced by mdBook. +This assumes you are reading an HTML book. +The options and formatting will be different for other output formats such as PDF. + +A book is organized into *chapters*. +Each chapter is a separate page. +Chapters can be nested into a hierarchy of sub-chapters. +Typically, each chapter will be organized into a series of *headings* to subdivide a chapter. + +## Navigation + +There are several methods for navigating through the chapters of a book. + +The **sidebar** on the left provides a list of all chapters. +Clicking on any of the chapter titles will load that page. + +The sidebar may not automatically appear if the window is too narrow, particularly on mobile displays. +In that situation, the menu icon (three horizontal bars) at the top-left of the page can be pressed to open and close the sidebar. + +The **arrow buttons** at the bottom of the page can be used to navigate to the previous or the next chapter. + +The **left and right arrow keys** on the keyboard can be used to navigate to the previous or the next chapter. + +## Top menu bar + +The menu bar at the top of the page provides some icons for interacting with the book. +The icons displayed will depend on the settings of how the book was generated. + +| Icon | Description | +|------|-------------| +| | Opens and closes the chapter listing sidebar. | +| | Opens a picker to choose a different color theme. | +| | Opens a search bar for searching within the book. | +| | Instructs the web browser to print the entire book. | +| | Opens a link to the website that hosts the source code of the book. | +| | Opens a page to directly edit the source of the page you are currently reading. | + +Tapping the menu bar will scroll the page to the top. + +## Search + +Each book has a built-in search system. +Pressing the search icon () in the menu bar, or pressing the `S` key on the keyboard will open an input box for entering search terms. +Typing some terms will show matching chapters and sections in real time. + +Clicking any of the results will jump to that section. +The up and down arrow keys can be used to navigate the results, and enter will open the highlighted section. + +After loading a search result, the matching search terms will be highlighted in the text. +Clicking a highlighted word or pressing the `Esc` key will remove the highlighting. + +## Code blocks + +mdBook books are often used for programming projects, and thus support highlighting code blocks and samples. +Code blocks may contain several different icons for interacting with them: + +| Icon | Description | +|------|-------------| +| | Copies the code block into your local clipboard, to allow pasting into another application. | +| | For Rust code examples, this will execute the sample code and display the compiler output just below the example (see [playground]). | +| | For Rust code examples, this will toggle visibility of "hidden" lines. Sometimes, larger examples will hide lines which are not particularly relevant to what is being illustrated (see [hiding code lines]). | +| | For [editable code examples][editor], this will undo any changes you have made. | + +Here's an example: + +```rust +println!("Hello, World!"); +``` + +[editor]: ../format/theme/editor.md +[playground]: ../format/mdbook.md#rust-playground +[hiding code lines]: ../format/mdbook.md#hiding-code-lines diff --git a/guide/src/misc/introduction.md b/guide/src/misc/introduction.md deleted file mode 100644 index 36495382..00000000 --- a/guide/src/misc/introduction.md +++ /dev/null @@ -1,3 +0,0 @@ -# Introduction - -A frontmatter chapter. From ddb0d2396f303bc1314b69a2bd948c03b243ccf6 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 25 Dec 2021 13:46:27 +0100 Subject: [PATCH 02/38] Update pulldown-cmark version --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- src/book/summary.rs | 16 ++++++++-------- src/renderer/html_handlebars/search.rs | 4 ++-- src/utils/mod.rs | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ea59887b..7d45fac9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1267,9 +1267,9 @@ dependencies = [ [[package]] name = "pulldown-cmark" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffade02495f22453cd593159ea2f59827aae7f53fa8323f756799b670881dcf8" +checksum = "acd16514d1af5f7a71f909a44ef253cdb712a376d7ebc8ae4a471a9be9743548" dependencies = [ "bitflags", "getopts", diff --git a/Cargo.toml b/Cargo.toml index fc5e1b16..0d7751cd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ lazy_static = "1.0" log = "0.4" memchr = "2.0" opener = "0.5" -pulldown-cmark = "0.8.0" +pulldown-cmark = "0.9.0" regex = "1.0.0" serde = "1.0" serde_derive = "1.0" diff --git a/src/book/summary.rs b/src/book/summary.rs index 981e1079..1ade05ec 100644 --- a/src/book/summary.rs +++ b/src/book/summary.rs @@ -1,6 +1,6 @@ use crate::errors::*; use memchr::{self, Memchr}; -use pulldown_cmark::{self, Event, Tag}; +use pulldown_cmark::{self, Event, HeadingLevel, Tag}; use std::fmt::{self, Display, Formatter}; use std::iter::FromIterator; use std::ops::{Deref, DerefMut}; @@ -161,7 +161,7 @@ impl From for SummaryItem { /// > match the following regex: "[^<>\n[]]+". struct SummaryParser<'a> { src: &'a str, - stream: pulldown_cmark::OffsetIter<'a>, + stream: pulldown_cmark::OffsetIter<'a, 'a>, offset: usize, /// We can't actually put an event back into the `OffsetIter` stream, so instead we store it @@ -263,7 +263,7 @@ impl<'a> SummaryParser<'a> { loop { match self.next_event() { Some(ev @ Event::Start(Tag::List(..))) - | Some(ev @ Event::Start(Tag::Heading(1))) => { + | Some(ev @ Event::Start(Tag::Heading(HeadingLevel::H1, ..))) => { if is_prefix { // we've finished prefix chapters and are at the start // of the numbered section. @@ -302,10 +302,10 @@ impl<'a> SummaryParser<'a> { break; } - Some(Event::Start(Tag::Heading(1))) => { + Some(Event::Start(Tag::Heading(HeadingLevel::H1, ..))) => { debug!("Found a h1 in the SUMMARY"); - let tags = collect_events!(self.stream, end Tag::Heading(1)); + let tags = collect_events!(self.stream, end Tag::Heading(HeadingLevel::H1, ..)); Some(stringify_events(tags)) } @@ -375,7 +375,7 @@ impl<'a> SummaryParser<'a> { } // The expectation is that pulldown cmark will terminate a paragraph before a new // heading, so we can always count on this to return without skipping headings. - Some(ev @ Event::Start(Tag::Heading(1))) => { + Some(ev @ Event::Start(Tag::Heading(HeadingLevel::H1, ..))) => { // we're starting a new part self.back(ev); break; @@ -527,10 +527,10 @@ impl<'a> SummaryParser<'a> { fn parse_title(&mut self) -> Option { loop { match self.next_event() { - Some(Event::Start(Tag::Heading(1))) => { + Some(Event::Start(Tag::Heading(HeadingLevel::H1, ..))) => { debug!("Found a h1 in the SUMMARY"); - let tags = collect_events!(self.stream, end Tag::Heading(1)); + let tags = collect_events!(self.stream, end Tag::Heading(HeadingLevel::H1, ..)); return Some(stringify_events(tags)); } // Skip a HTML element such as a comment line. diff --git a/src/renderer/html_handlebars/search.rs b/src/renderer/html_handlebars/search.rs index 2dc717fb..39b59800 100644 --- a/src/renderer/html_handlebars/search.rs +++ b/src/renderer/html_handlebars/search.rs @@ -99,7 +99,7 @@ fn render_item( while let Some(event) = p.next() { match event { - Event::Start(Tag::Heading(i)) if i <= max_section_depth => { + Event::Start(Tag::Heading(i, ..)) if i as u32 <= max_section_depth => { if !heading.is_empty() { // Section finished, the next heading is following now // Write the data to the index, and clear it for the next section @@ -118,7 +118,7 @@ fn render_item( in_heading = true; } - Event::End(Tag::Heading(i)) if i <= max_section_depth => { + Event::End(Tag::Heading(i, ..)) if i as u32 <= max_section_depth => { in_heading = false; section_id = Some(utils::id_from_content(&heading)); breadcrumbs.push(heading.clone()); diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 3910e3dd..44494a8b 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -160,7 +160,7 @@ pub fn render_markdown(text: &str, curly_quotes: bool) -> String { render_markdown_with_path(text, curly_quotes, None) } -pub fn new_cmark_parser(text: &str, curly_quotes: bool) -> Parser<'_> { +pub fn new_cmark_parser(text: &str, curly_quotes: bool) -> Parser<'_, '_> { let mut opts = Options::empty(); opts.insert(Options::ENABLE_TABLES); opts.insert(Options::ENABLE_FOOTNOTES); From b0511f408d72113b74494f49120fcaf79262284f Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 4 Jan 2022 10:18:39 -0800 Subject: [PATCH 03/38] Update to 0.4.15 --- CHANGELOG.md | 10 ++++++++++ Cargo.lock | 2 +- Cargo.toml | 2 +- guide/src/continuous-integration.md | 2 +- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 83e7818f..9b3b6a2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## mdBook 0.4.15 +[5eb7d46...68a5c09](https://github.com/rust-lang/mdBook/compare/5eb7d46...68a5c09) + +### Changed +- Major update to expand the documentation located at . + [#1709](https://github.com/rust-lang/mdBook/pull/1709) + [#1710](https://github.com/rust-lang/mdBook/pull/1710) +- Updated the markdown parser with various fixes for common-mark compliance. + [#1712](https://github.com/rust-lang/mdBook/pull/1712) + ## mdBook 0.4.14 [ffa8284...c9b6be8](https://github.com/rust-lang/mdBook/compare/ffa8284...c9b6be8) diff --git a/Cargo.lock b/Cargo.lock index 7d45fac9..b44d152d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -839,7 +839,7 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" [[package]] name = "mdbook" -version = "0.4.14" +version = "0.4.15" dependencies = [ "ammonia", "anyhow", diff --git a/Cargo.toml b/Cargo.toml index 0d7751cd..e61f74a0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mdbook" -version = "0.4.14" +version = "0.4.15" authors = [ "Mathieu David ", "Michael-F-Bryan ", diff --git a/guide/src/continuous-integration.md b/guide/src/continuous-integration.md index baf510be..3503445f 100644 --- a/guide/src/continuous-integration.md +++ b/guide/src/continuous-integration.md @@ -21,7 +21,7 @@ A simple approach would be to use the popular `curl` CLI tool to download the ex ```sh mkdir bin -curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.14/mdbook-v0.4.14-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=bin +curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.15/mdbook-v0.4.15-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=bin bin/mdbook build ``` From 526a0394b00b9acdf371b14571086eeb1187313e Mon Sep 17 00:00:00 2001 From: klensy Date: Thu, 6 Jan 2022 20:35:13 +0300 Subject: [PATCH 04/38] don't use additional features for pulldown-cmark --- Cargo.lock | 10 ---------- Cargo.toml | 2 +- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b44d152d..b85c0ce1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -473,15 +473,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "getopts" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" -dependencies = [ - "unicode-width", -] - [[package]] name = "getrandom" version = "0.1.16" @@ -1272,7 +1263,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acd16514d1af5f7a71f909a44ef253cdb712a376d7ebc8ae4a471a9be9743548" dependencies = [ "bitflags", - "getopts", "memchr", "unicase", ] diff --git a/Cargo.toml b/Cargo.toml index e61f74a0..eef90de7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ lazy_static = "1.0" log = "0.4" memchr = "2.0" opener = "0.5" -pulldown-cmark = "0.9.0" +pulldown-cmark = { version = "0.9", default-features = false } regex = "1.0.0" serde = "1.0" serde_derive = "1.0" From a226de38b6258b570f286520878955537d28ea2f Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Thu, 13 Jan 2022 18:01:42 -0600 Subject: [PATCH 05/38] ci: use new cargo fmt option --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bd3c7558..39624230 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -48,4 +48,4 @@ jobs: - uses: actions/checkout@master - name: Install Rust run: rustup update stable && rustup default stable && rustup component add rustfmt - - run: cargo fmt -- --check + - run: cargo fmt --check From 7b1241d0f287e07a0056834020726f5a1e69f5a8 Mon Sep 17 00:00:00 2001 From: Daniel Morawetz Date: Mon, 17 Jan 2022 18:03:52 +0100 Subject: [PATCH 06/38] Revert "Make page-break not configurable" This reverts commit 0eb23efd44c96d79c96161648a6c286dbc7424c1. --- src/config.rs | 7 ++++++- src/renderer/html_handlebars/hbs_renderer.rs | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/config.rs b/src/config.rs index bf4aabbb..daeccbd0 100644 --- a/src/config.rs +++ b/src/config.rs @@ -592,11 +592,16 @@ impl HtmlConfig { pub struct Print { /// Whether print support is enabled. pub enable: bool, + /// Insert page breaks between chapters. Default: `true`. + pub page_break: bool, } impl Default for Print { fn default() -> Self { - Self { enable: true } + Self { + enable: true, + page_break: true, + } } } diff --git a/src/renderer/html_handlebars/hbs_renderer.rs b/src/renderer/html_handlebars/hbs_renderer.rs index e8da5b4a..69dc3124 100644 --- a/src/renderer/html_handlebars/hbs_renderer.rs +++ b/src/renderer/html_handlebars/hbs_renderer.rs @@ -56,7 +56,7 @@ impl HtmlHandlebars { let fixed_content = utils::render_markdown_with_path(&ch.content, ctx.html_config.curly_quotes, Some(path)); - if !ctx.is_index { + if !ctx.is_index && ctx.html_config.print.page_break { // Add page break between chapters // See https://developer.mozilla.org/en-US/docs/Web/CSS/break-before and https://developer.mozilla.org/en-US/docs/Web/CSS/page-break-before // Add both two CSS properties because of the compatibility issue From 9e6217871e8f7b7580703c4f0cd99938ee0a3e19 Mon Sep 17 00:00:00 2001 From: Daniel Morawetz Date: Mon, 17 Jan 2022 18:07:22 +0100 Subject: [PATCH 07/38] add page-break option to docs --- guide/src/format/configuration/renderers.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/guide/src/format/configuration/renderers.md b/guide/src/format/configuration/renderers.md index a29265e4..1aa1eef9 100644 --- a/guide/src/format/configuration/renderers.md +++ b/guide/src/format/configuration/renderers.md @@ -173,10 +173,12 @@ By default, mdBook will include an icon on the top right of the book (which look ```toml [output.html.print] enable = true # include support for printable output +page-break = true # insert page-break after each chapter ``` - **enable:** Enable print support. When `false`, all print support will not be rendered. Defaults to `true`. +- **page-break** Insert page breaks between chapters. Defaults to `true`. ### `[output.html.fold]` From 4206739492a3a8f2eda3d3dd6352a3392cf05643 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 18 Jan 2022 16:01:23 +0100 Subject: [PATCH 08/38] Update pulldown-cmark version --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b85c0ce1..42d6983e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1258,9 +1258,9 @@ dependencies = [ [[package]] name = "pulldown-cmark" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acd16514d1af5f7a71f909a44ef253cdb712a376d7ebc8ae4a471a9be9743548" +checksum = "34f197a544b0c9ab3ae46c359a7ec9cbbb5c7bf97054266fecb7ead794a181d6" dependencies = [ "bitflags", "memchr", diff --git a/Cargo.toml b/Cargo.toml index eef90de7..e0aef886 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ lazy_static = "1.0" log = "0.4" memchr = "2.0" opener = "0.5" -pulldown-cmark = { version = "0.9", default-features = false } +pulldown-cmark = { version = "0.9.1", default-features = false } regex = "1.0.0" serde = "1.0" serde_derive = "1.0" From c5c8f1a6d3701c7e9673cf5e70874654db40fa0a Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 23 Jan 2022 00:01:10 -0800 Subject: [PATCH 09/38] Update semver dev-dependency in nop-preprocessor example to 1.0 --- Cargo.lock | 16 ++-------------- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 42d6983e..ffec902d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1454,21 +1454,9 @@ dependencies = [ [[package]] name = "semver" -version = "0.11.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver-parser" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" -dependencies = [ - "pest", -] +checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" [[package]] name = "serde" diff --git a/Cargo.toml b/Cargo.toml index e0aef886..61b23e1d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,7 +52,7 @@ ammonia = { version = "3", optional = true } assert_cmd = "1" predicates = "2" select = "0.5" -semver = "0.11.0" +semver = "1.0" pretty_assertions = "0.6" walkdir = "2.0" From 81d661c4f193b67f69aa5698e0367c5d1386ec7b Mon Sep 17 00:00:00 2001 From: ilslv Date: Fri, 11 Feb 2022 12:33:22 +0300 Subject: [PATCH 10/38] Fix no initial title consuming events. --- src/book/summary.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/book/summary.rs b/src/book/summary.rs index 1ade05ec..2427a3a2 100644 --- a/src/book/summary.rs +++ b/src/book/summary.rs @@ -536,6 +536,10 @@ impl<'a> SummaryParser<'a> { // Skip a HTML element such as a comment line. Some(Event::Html(_)) => {} // Otherwise, no title. + Some(ev) => { + self.back(ev); + return None; + } _ => return None, } } @@ -647,6 +651,15 @@ mod tests { assert_eq!(got, should_be); } + #[test] + fn no_initial_title() { + let src = "[Link]()"; + let mut parser = SummaryParser::new(src); + + assert!(parser.parse_title().is_none()); + assert!(matches!(parser.next_event(), Some(Event::Start(Tag::Paragraph)))); + } + #[test] fn parse_title_with_styling() { let src = "# My **Awesome** Summary"; From 6c4974b5c6415c7ad6ac124af5e0a3b49de96259 Mon Sep 17 00:00:00 2001 From: ilslv Date: Fri, 11 Feb 2022 12:42:54 +0300 Subject: [PATCH 11/38] Fmt --- src/book/summary.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/book/summary.rs b/src/book/summary.rs index 2427a3a2..b5a740c2 100644 --- a/src/book/summary.rs +++ b/src/book/summary.rs @@ -657,7 +657,10 @@ mod tests { let mut parser = SummaryParser::new(src); assert!(parser.parse_title().is_none()); - assert!(matches!(parser.next_event(), Some(Event::Start(Tag::Paragraph)))); + assert!(matches!( + parser.next_event(), + Some(Event::Start(Tag::Paragraph)), + )); } #[test] From b73d02fb8c058f0f29c2b10a40906e1b8beff8b5 Mon Sep 17 00:00:00 2001 From: ilslv Date: Fri, 11 Feb 2022 12:50:22 +0300 Subject: [PATCH 12/38] Remove colon to satisfy msrv --- src/book/summary.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/book/summary.rs b/src/book/summary.rs index b5a740c2..4bb8e969 100644 --- a/src/book/summary.rs +++ b/src/book/summary.rs @@ -659,7 +659,7 @@ mod tests { assert!(parser.parse_title().is_none()); assert!(matches!( parser.next_event(), - Some(Event::Start(Tag::Paragraph)), + Some(Event::Start(Tag::Paragraph)) )); } From 972c61fa76d0bd972538a762cd62afca4c917a33 Mon Sep 17 00:00:00 2001 From: Tom Milligan Date: Fri, 18 Feb 2022 15:27:24 +0000 Subject: [PATCH 13/38] search: fix anchor ids for duplicate headers --- src/renderer/html_handlebars/hbs_renderer.rs | 11 +- src/renderer/html_handlebars/search.rs | 3 +- src/utils/mod.rs | 57 +- tests/dummy_book/src/SUMMARY.md | 1 + .../dummy_book/src/first/duplicate-headers.md | 9 + tests/rendered_output.rs | 10 +- tests/searchindex_fixture.json | 600 ++++++++++++++---- 7 files changed, 554 insertions(+), 137 deletions(-) create mode 100644 tests/dummy_book/src/first/duplicate-headers.md diff --git a/src/renderer/html_handlebars/hbs_renderer.rs b/src/renderer/html_handlebars/hbs_renderer.rs index 69dc3124..c4c2862d 100644 --- a/src/renderer/html_handlebars/hbs_renderer.rs +++ b/src/renderer/html_handlebars/hbs_renderer.rs @@ -768,16 +768,7 @@ fn insert_link_into_header( content: &str, id_counter: &mut HashMap, ) -> String { - let raw_id = utils::id_from_content(content); - - let id_count = id_counter.entry(raw_id.clone()).or_insert(0); - - let id = match *id_count { - 0 => raw_id, - other => format!("{}-{}", raw_id, other), - }; - - *id_count += 1; + let id = utils::unique_id_from_content(content, id_counter); format!( r##"{text}"##, diff --git a/src/renderer/html_handlebars/search.rs b/src/renderer/html_handlebars/search.rs index 39b59800..5dd063da 100644 --- a/src/renderer/html_handlebars/search.rs +++ b/src/renderer/html_handlebars/search.rs @@ -97,6 +97,7 @@ fn render_item( breadcrumbs.push(chapter.name.clone()); + let mut id_counter = HashMap::new(); while let Some(event) = p.next() { match event { Event::Start(Tag::Heading(i, ..)) if i as u32 <= max_section_depth => { @@ -120,7 +121,7 @@ fn render_item( } Event::End(Tag::Heading(i, ..)) if i as u32 <= max_section_depth => { in_heading = false; - section_id = Some(utils::id_from_content(&heading)); + section_id = Some(utils::unique_id_from_content(&heading, &mut id_counter)); breadcrumbs.push(heading.clone()); } Event::Start(Tag::FootnoteDefinition(name)) => { diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 44494a8b..cf213264 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -9,6 +9,7 @@ use regex::Regex; use pulldown_cmark::{html, CodeBlockKind, CowStr, Event, Options, Parser, Tag}; use std::borrow::Cow; +use std::collections::HashMap; use std::fmt::Write; use std::path::Path; @@ -44,6 +45,8 @@ pub fn normalize_id(content: &str) -> String { /// Generate an ID for use with anchors which is derived from a "normalised" /// string. +// This function should be made private when the deprecation expires. +#[deprecated(since = "0.4.16", note = "use unique_id_from_content instead")] pub fn id_from_content(content: &str) -> String { let mut content = content.to_string(); @@ -59,10 +62,30 @@ pub fn id_from_content(content: &str) -> String { // Remove spaces and hashes indicating a header let trimmed = content.trim().trim_start_matches('#').trim(); - normalize_id(trimmed) } +/// Generate an ID for use with anchors which is derived from a "normalised" +/// string. +/// +/// Each ID returned will be unique, if the same `id_counter` is provided on +/// each call. +pub fn unique_id_from_content(content: &str, id_counter: &mut HashMap) -> String { + let id = { + #[allow(deprecated)] + id_from_content(content) + }; + + // If we have headers with the same normalized id, append an incrementing counter + let id_count = id_counter.entry(id.clone()).or_insert(0); + let unique_id = match *id_count { + 0 => id, + id_count => format!("{}-{}", id, id_count), + }; + *id_count += 1; + unique_id +} + /// Fix links to the correct location. /// /// This adjusts links, such as turning `.md` extensions to `.html`. @@ -332,8 +355,9 @@ more text with spaces } } - mod html_munging { - use super::super::{id_from_content, normalize_id}; + #[allow(deprecated)] + mod id_from_content { + use super::super::id_from_content; #[test] fn it_generates_anchors() { @@ -361,6 +385,10 @@ more text with spaces ); assert_eq!(id_from_content("## Über"), "Über"); } + } + + mod html_munging { + use super::super::{normalize_id, unique_id_from_content}; #[test] fn it_normalizes_ids() { @@ -379,5 +407,28 @@ more text with spaces assert_eq!(normalize_id("한국어"), "한국어"); assert_eq!(normalize_id(""), ""); } + + #[test] + fn it_generates_unique_ids_from_content() { + // Same id if not given shared state + assert_eq!( + unique_id_from_content("## 中文標題 CJK title", &mut Default::default()), + "中文標題-cjk-title" + ); + assert_eq!( + unique_id_from_content("## 中文標題 CJK title", &mut Default::default()), + "中文標題-cjk-title" + ); + + // Different id if given shared state + let mut id_counter = Default::default(); + assert_eq!(unique_id_from_content("## Über", &mut id_counter), "Über"); + assert_eq!( + unique_id_from_content("## 中文標題 CJK title", &mut id_counter), + "中文標題-cjk-title" + ); + assert_eq!(unique_id_from_content("## Über", &mut id_counter), "Über-1"); + assert_eq!(unique_id_from_content("## Über", &mut id_counter), "Über-2"); + } } } diff --git a/tests/dummy_book/src/SUMMARY.md b/tests/dummy_book/src/SUMMARY.md index e12e1254..49b64a54 100644 --- a/tests/dummy_book/src/SUMMARY.md +++ b/tests/dummy_book/src/SUMMARY.md @@ -13,6 +13,7 @@ - [Markdown](first/markdown.md) - [Unicode](first/unicode.md) - [No Headers](first/no-headers.md) + - [Duplicate Headers](first/duplicate-headers.md) - [Second Chapter](second.md) - [Nested Chapter](second/nested.md) diff --git a/tests/dummy_book/src/first/duplicate-headers.md b/tests/dummy_book/src/first/duplicate-headers.md new file mode 100644 index 00000000..83522b44 --- /dev/null +++ b/tests/dummy_book/src/first/duplicate-headers.md @@ -0,0 +1,9 @@ +# Duplicate headers + +This page validates behaviour of duplicate headers. + +# Header Text + +# Header Text + +# header-text diff --git a/tests/rendered_output.rs b/tests/rendered_output.rs index 5ec6e64b..f3d11d53 100644 --- a/tests/rendered_output.rs +++ b/tests/rendered_output.rs @@ -35,6 +35,7 @@ const TOC_SECOND_LEVEL: &[&str] = &[ "1.4. Markdown", "1.5. Unicode", "1.6. No Headers", + "1.7. Duplicate Headers", "2.1. Nested Chapter", ]; @@ -633,11 +634,12 @@ mod search { let some_section = get_doc_ref("first/index.html#some-section"); let summary = get_doc_ref("first/includes.html#summary"); let no_headers = get_doc_ref("first/no-headers.html"); + let duplicate_headers_1 = get_doc_ref("first/duplicate-headers.html#header-text-1"); let conclusion = get_doc_ref("conclusion.html#conclusion"); let bodyidx = &index["index"]["index"]["body"]["root"]; let textidx = &bodyidx["t"]["e"]["x"]["t"]; - assert_eq!(textidx["df"], 2); + assert_eq!(textidx["df"], 5); assert_eq!(textidx["docs"][&first_chapter]["tf"], 1.0); assert_eq!(textidx["docs"][&introduction]["tf"], 1.0); @@ -646,7 +648,7 @@ mod search { assert_eq!(docs[&some_section]["body"], ""); assert_eq!( docs[&summary]["body"], - "Dummy Book Introduction First Chapter Nested Chapter Includes Recursive Markdown Unicode No Headers Second Chapter Nested Chapter Conclusion" + "Dummy Book Introduction First Chapter Nested Chapter Includes Recursive Markdown Unicode No Headers Duplicate Headers Second Chapter Nested Chapter Conclusion" ); assert_eq!( docs[&summary]["breadcrumbs"], @@ -657,6 +659,10 @@ mod search { docs[&no_headers]["breadcrumbs"], "First Chapter » No Headers" ); + assert_eq!( + docs[&duplicate_headers_1]["breadcrumbs"], + "First Chapter » Duplicate Headers » Header Text" + ); assert_eq!( docs[&no_headers]["body"], "Capybara capybara capybara. Capybara capybara capybara." diff --git a/tests/searchindex_fixture.json b/tests/searchindex_fixture.json index 32c44a1b..9c349b6b 100644 --- a/tests/searchindex_fixture.json +++ b/tests/searchindex_fixture.json @@ -19,6 +19,10 @@ "first/markdown.html#tasklisks", "first/unicode.html#unicode-stress-tests", "first/no-headers.html", + "first/duplicate-headers.html#duplicate-headers", + "first/duplicate-headers.html#header-text", + "first/duplicate-headers.html#header-text-1", + "first/duplicate-headers.html#header-text-2", "second.html#second-chapter", "second/nested.html#testing-relative-links-for-the-print-page", "second/nested.html#some-section", @@ -38,7 +42,7 @@ "title": 1 }, "10": { - "body": 17, + "body": 19, "breadcrumbs": 4, "title": 1 }, @@ -83,8 +87,8 @@ "title": 2 }, "19": { - "body": 20, - "breadcrumbs": 4, + "body": 5, + "breadcrumbs": 6, "title": 2 }, "2": { @@ -93,16 +97,36 @@ "title": 2 }, "20": { + "body": 0, + "breadcrumbs": 6, + "title": 2 + }, + "21": { + "body": 0, + "breadcrumbs": 6, + "title": 2 + }, + "22": { + "body": 0, + "breadcrumbs": 6, + "title": 2 + }, + "23": { + "body": 20, + "breadcrumbs": 4, + "title": 2 + }, + "24": { "body": 18, "breadcrumbs": 9, "title": 5 }, - "21": { + "25": { "body": 0, "breadcrumbs": 5, "title": 1 }, - "22": { + "26": { "body": 3, "breadcrumbs": 2, "title": 1 @@ -157,7 +181,7 @@ "title": "Introduction" }, "10": { - "body": "Dummy Book Introduction First Chapter Nested Chapter Includes Recursive Markdown Unicode No Headers Second Chapter Nested Chapter Conclusion", + "body": "Dummy Book Introduction First Chapter Nested Chapter Includes Recursive Markdown Unicode No Headers Duplicate Headers Second Chapter Nested Chapter Conclusion", "breadcrumbs": "First Chapter » Includes » Summary", "id": "10", "title": "Summary" @@ -211,10 +235,10 @@ "title": "First Chapter" }, "19": { - "body": "This makes sure you can insert runnable Rust files. fn main() { println!(\"Hello World!\");\n#\n# // You can even hide lines! :D\n# println!(\"I am hidden! Expand the code snippet to see me\");\n}", - "breadcrumbs": "Second Chapter » Second Chapter", + "body": "This page validates behaviour of duplicate headers.", + "breadcrumbs": "First Chapter » Duplicate Headers » Duplicate headers", "id": "19", - "title": "Second Chapter" + "title": "Duplicate headers" }, "2": { "body": "more text.", @@ -223,21 +247,45 @@ "title": "First Chapter" }, "20": { - "body": "When we link to the first section , it should work on both the print page and the non-print page. A fragment link should work. Link outside . Some image HTML Link", - "breadcrumbs": "Second Chapter » Nested Chapter » Testing relative links for the print page", + "body": "", + "breadcrumbs": "First Chapter » Duplicate Headers » Header Text", "id": "20", - "title": "Testing relative links for the print page" + "title": "Header Text" }, "21": { "body": "", - "breadcrumbs": "Second Chapter » Nested Chapter » Some section", + "breadcrumbs": "First Chapter » Duplicate Headers » Header Text", "id": "21", - "title": "Some section" + "title": "Header Text" }, "22": { + "body": "", + "breadcrumbs": "First Chapter » Duplicate Headers » header-text", + "id": "22", + "title": "header-text" + }, + "23": { + "body": "This makes sure you can insert runnable Rust files. fn main() { println!(\"Hello World!\");\n#\n# // You can even hide lines! :D\n# println!(\"I am hidden! Expand the code snippet to see me\");\n}", + "breadcrumbs": "Second Chapter » Second Chapter", + "id": "23", + "title": "Second Chapter" + }, + "24": { + "body": "When we link to the first section , it should work on both the print page and the non-print page. A fragment link should work. Link outside . Some image HTML Link", + "breadcrumbs": "Second Chapter » Nested Chapter » Testing relative links for the print page", + "id": "24", + "title": "Testing relative links for the print page" + }, + "25": { + "body": "", + "breadcrumbs": "Second Chapter » Nested Chapter » Some section", + "id": "25", + "title": "Some section" + }, + "26": { "body": "I put <HTML> in here!", "breadcrumbs": "Conclusion » Conclusion", - "id": "22", + "id": "26", "title": "Conclusion" }, "3": { @@ -283,7 +331,7 @@ "title": "Includes" } }, - "length": 23, + "length": 27, "save": true }, "fields": [ @@ -478,6 +526,38 @@ "e": { "df": 0, "docs": {}, + "h": { + "a": { + "df": 0, + "docs": {}, + "v": { + "df": 0, + "docs": {}, + "i": { + "df": 0, + "docs": {}, + "o": { + "df": 0, + "docs": {}, + "u": { + "df": 0, + "docs": {}, + "r": { + "df": 1, + "docs": { + "19": { + "tf": 1.0 + } + } + } + } + } + } + } + }, + "df": 0, + "docs": {} + }, "t": { "df": 0, "docs": {}, @@ -539,7 +619,7 @@ "h": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -738,10 +818,10 @@ "18": { "tf": 1.0 }, - "19": { + "2": { "tf": 1.0 }, - "2": { + "23": { "tf": 1.0 }, "4": { @@ -783,7 +863,7 @@ "e": { "df": 2, "docs": { - "19": { + "23": { "tf": 1.0 }, "4": { @@ -850,7 +930,7 @@ "10": { "tf": 1.0 }, - "22": { + "26": { "tf": 1.0 } } @@ -922,7 +1002,7 @@ "d": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } }, @@ -947,6 +1027,29 @@ } } } + }, + "p": { + "df": 0, + "docs": {}, + "l": { + "df": 0, + "docs": {}, + "i": { + "c": { + "df": 2, + "docs": { + "10": { + "tf": 1.0 + }, + "19": { + "tf": 1.4142135623730951 + } + } + }, + "df": 0, + "docs": {} + } + } } } }, @@ -1012,7 +1115,7 @@ "n": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -1053,7 +1156,7 @@ "d": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -1122,7 +1225,7 @@ "0": { "tf": 1.0 }, - "19": { + "23": { "tf": 1.0 }, "4": { @@ -1158,7 +1261,7 @@ "2": { "tf": 1.0 }, - "20": { + "24": { "tf": 1.0 } } @@ -1169,7 +1272,7 @@ "n": { "df": 3, "docs": { - "19": { + "23": { "tf": 1.0 }, "7": { @@ -1243,7 +1346,7 @@ "t": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -1289,9 +1392,21 @@ "df": 0, "docs": {}, "r": { - "df": 1, + "df": 5, "docs": { "10": { + "tf": 1.4142135623730951 + }, + "19": { + "tf": 1.4142135623730951 + }, + "20": { + "tf": 1.0 + }, + "21": { + "tf": 1.0 + }, + "22": { "tf": 1.0 } } @@ -1336,7 +1451,7 @@ "0": { "tf": 1.0 }, - "22": { + "26": { "tf": 1.0 } } @@ -1354,7 +1469,7 @@ "n": { "df": 2, "docs": { - "19": { + "23": { "tf": 1.0 }, "7": { @@ -1369,7 +1484,7 @@ "e": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -1387,7 +1502,7 @@ "l": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -1405,7 +1520,7 @@ "g": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -1477,7 +1592,7 @@ "t": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -1613,7 +1728,7 @@ "14": { "tf": 1.4142135623730951 }, - "19": { + "23": { "tf": 1.0 }, "6": { @@ -1624,7 +1739,7 @@ "k": { "df": 1, "docs": { - "20": { + "24": { "tf": 2.23606797749979 } } @@ -1678,7 +1793,7 @@ "t": { "df": 1, "docs": { - "22": { + "26": { "tf": 1.0 } } @@ -1706,7 +1821,7 @@ "n": { "df": 3, "docs": { - "19": { + "23": { "tf": 1.0 }, "7": { @@ -1724,7 +1839,7 @@ "e": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -1853,7 +1968,7 @@ "n": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -1892,7 +2007,7 @@ "d": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -1912,9 +2027,12 @@ "df": 0, "docs": {}, "e": { - "df": 1, + "df": 2, "docs": { - "20": { + "19": { + "tf": 1.0 + }, + "24": { "tf": 1.7320508075688772 } } @@ -2027,7 +2145,7 @@ "t": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.7320508075688772 } }, @@ -2055,7 +2173,7 @@ "o": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -2067,7 +2185,7 @@ "i": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -2093,7 +2211,7 @@ "t": { "df": 1, "docs": { - "22": { + "26": { "tf": 1.0 } } @@ -2129,7 +2247,7 @@ "l": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -2241,7 +2359,7 @@ "l": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -2279,7 +2397,7 @@ }, "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -2304,7 +2422,7 @@ "10": { "tf": 1.0 }, - "19": { + "23": { "tf": 1.0 } } @@ -2325,10 +2443,10 @@ "n": { "df": 4, "docs": { - "20": { + "24": { "tf": 1.0 }, - "21": { + "25": { "tf": 1.0 }, "3": { @@ -2348,7 +2466,7 @@ "e": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -2372,7 +2490,7 @@ "t": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -2663,7 +2781,7 @@ "e": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -2749,7 +2867,7 @@ "17": { "tf": 1.0 }, - "20": { + "24": { "tf": 1.0 }, "6": { @@ -2762,13 +2880,22 @@ "df": 0, "docs": {}, "t": { - "df": 2, + "df": 5, "docs": { "1": { "tf": 1.0 }, "2": { "tf": 1.0 + }, + "20": { + "tf": 1.0 + }, + "21": { + "tf": 1.0 + }, + "22": { + "tf": 1.0 } } } @@ -2866,6 +2993,30 @@ } } }, + "v": { + "a": { + "df": 0, + "docs": {}, + "l": { + "df": 0, + "docs": {}, + "i": { + "d": { + "df": 1, + "docs": { + "19": { + "tf": 1.0 + } + } + }, + "df": 0, + "docs": {} + } + } + }, + "df": 0, + "docs": {} + }, "w": { "a": { "df": 0, @@ -2898,7 +3049,7 @@ "k": { "df": 2, "docs": { - "20": { + "24": { "tf": 1.4142135623730951 }, "8": { @@ -2913,7 +3064,7 @@ "11": { "tf": 4.69041575982343 }, - "19": { + "23": { "tf": 1.0 } } @@ -3136,6 +3287,38 @@ "e": { "df": 0, "docs": {}, + "h": { + "a": { + "df": 0, + "docs": {}, + "v": { + "df": 0, + "docs": {}, + "i": { + "df": 0, + "docs": {}, + "o": { + "df": 0, + "docs": {}, + "u": { + "df": 0, + "docs": {}, + "r": { + "df": 1, + "docs": { + "19": { + "tf": 1.0 + } + } + } + } + } + } + } + }, + "df": 0, + "docs": {} + }, "t": { "df": 0, "docs": {}, @@ -3197,7 +3380,7 @@ "h": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -3385,7 +3568,7 @@ "df": 0, "docs": {}, "r": { - "df": 20, + "df": 24, "docs": { "10": { "tf": 2.23606797749979 @@ -3415,15 +3598,27 @@ "tf": 1.4142135623730951 }, "19": { - "tf": 1.7320508075688772 + "tf": 1.0 }, "2": { "tf": 1.7320508075688772 }, "20": { - "tf": 1.4142135623730951 + "tf": 1.0 }, "21": { + "tf": 1.0 + }, + "22": { + "tf": 1.0 + }, + "23": { + "tf": 1.7320508075688772 + }, + "24": { + "tf": 1.4142135623730951 + }, + "25": { "tf": 1.4142135623730951 }, "3": { @@ -3483,7 +3678,7 @@ "e": { "df": 2, "docs": { - "19": { + "23": { "tf": 1.0 }, "4": { @@ -3550,7 +3745,7 @@ "10": { "tf": 1.0 }, - "22": { + "26": { "tf": 1.7320508075688772 } } @@ -3622,7 +3817,7 @@ "d": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } }, @@ -3647,6 +3842,38 @@ } } } + }, + "p": { + "df": 0, + "docs": {}, + "l": { + "df": 0, + "docs": {}, + "i": { + "c": { + "df": 5, + "docs": { + "10": { + "tf": 1.0 + }, + "19": { + "tf": 2.0 + }, + "20": { + "tf": 1.0 + }, + "21": { + "tf": 1.0 + }, + "22": { + "tf": 1.0 + } + } + }, + "df": 0, + "docs": {} + } + } } } }, @@ -3712,7 +3939,7 @@ "n": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -3753,7 +3980,7 @@ "d": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -3822,7 +4049,7 @@ "0": { "tf": 1.0 }, - "19": { + "23": { "tf": 1.0 }, "4": { @@ -3844,7 +4071,7 @@ "df": 0, "docs": {}, "t": { - "df": 18, + "df": 22, "docs": { "10": { "tf": 1.4142135623730951 @@ -3873,12 +4100,24 @@ "18": { "tf": 1.4142135623730951 }, + "19": { + "tf": 1.0 + }, "2": { "tf": 1.7320508075688772 }, "20": { "tf": 1.0 }, + "21": { + "tf": 1.0 + }, + "22": { + "tf": 1.0 + }, + "24": { + "tf": 1.0 + }, "3": { "tf": 1.0 }, @@ -3908,7 +4147,7 @@ "n": { "df": 3, "docs": { - "19": { + "23": { "tf": 1.0 }, "7": { @@ -3982,7 +4221,7 @@ "t": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -4028,13 +4267,25 @@ "df": 0, "docs": {}, "r": { - "df": 2, + "df": 6, "docs": { "10": { - "tf": 1.0 + "tf": 1.4142135623730951 }, "18": { "tf": 1.0 + }, + "19": { + "tf": 2.0 + }, + "20": { + "tf": 1.7320508075688772 + }, + "21": { + "tf": 1.7320508075688772 + }, + "22": { + "tf": 1.7320508075688772 } } } @@ -4078,7 +4329,7 @@ "0": { "tf": 1.0 }, - "22": { + "26": { "tf": 1.0 } } @@ -4096,7 +4347,7 @@ "n": { "df": 2, "docs": { - "19": { + "23": { "tf": 1.0 }, "7": { @@ -4111,7 +4362,7 @@ "e": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -4129,7 +4380,7 @@ "l": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -4147,7 +4398,7 @@ "g": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -4219,7 +4470,7 @@ "t": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -4355,7 +4606,7 @@ "14": { "tf": 1.4142135623730951 }, - "19": { + "23": { "tf": 1.0 }, "6": { @@ -4366,7 +4617,7 @@ "k": { "df": 1, "docs": { - "20": { + "24": { "tf": 2.449489742783178 } } @@ -4420,7 +4671,7 @@ "t": { "df": 1, "docs": { - "22": { + "26": { "tf": 1.0 } } @@ -4448,7 +4699,7 @@ "n": { "df": 3, "docs": { - "19": { + "23": { "tf": 1.0 }, "7": { @@ -4466,7 +4717,7 @@ "e": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -4582,10 +4833,10 @@ "10": { "tf": 1.4142135623730951 }, - "20": { + "24": { "tf": 1.0 }, - "21": { + "25": { "tf": 1.0 }, "4": { @@ -4625,7 +4876,7 @@ "n": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -4664,7 +4915,7 @@ "d": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -4684,9 +4935,12 @@ "df": 0, "docs": {}, "e": { - "df": 1, + "df": 2, "docs": { - "20": { + "19": { + "tf": 1.0 + }, + "24": { "tf": 2.0 } } @@ -4799,7 +5053,7 @@ "t": { "df": 1, "docs": { - "20": { + "24": { "tf": 2.0 } }, @@ -4827,7 +5081,7 @@ "o": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -4839,7 +5093,7 @@ "i": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -4865,7 +5119,7 @@ "t": { "df": 1, "docs": { - "22": { + "26": { "tf": 1.0 } } @@ -4904,7 +5158,7 @@ "l": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.4142135623730951 } } @@ -5016,7 +5270,7 @@ "l": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -5054,7 +5308,7 @@ }, "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -5079,13 +5333,13 @@ "10": { "tf": 1.0 }, - "19": { + "23": { "tf": 1.7320508075688772 }, - "20": { + "24": { "tf": 1.0 }, - "21": { + "25": { "tf": 1.0 } } @@ -5106,10 +5360,10 @@ "n": { "df": 4, "docs": { - "20": { + "24": { "tf": 1.0 }, - "21": { + "25": { "tf": 1.4142135623730951 }, "3": { @@ -5129,7 +5383,7 @@ "e": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -5153,7 +5407,7 @@ "t": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -5444,7 +5698,7 @@ "e": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -5530,7 +5784,7 @@ "17": { "tf": 1.4142135623730951 }, - "20": { + "24": { "tf": 1.4142135623730951 }, "6": { @@ -5543,13 +5797,22 @@ "df": 0, "docs": {}, "t": { - "df": 2, + "df": 5, "docs": { "1": { "tf": 1.0 }, "2": { "tf": 1.0 + }, + "20": { + "tf": 1.4142135623730951 + }, + "21": { + "tf": 1.4142135623730951 + }, + "22": { + "tf": 1.4142135623730951 } } } @@ -5647,6 +5910,30 @@ } } }, + "v": { + "a": { + "df": 0, + "docs": {}, + "l": { + "df": 0, + "docs": {}, + "i": { + "d": { + "df": 1, + "docs": { + "19": { + "tf": 1.0 + } + } + }, + "df": 0, + "docs": {} + } + } + }, + "df": 0, + "docs": {} + }, "w": { "a": { "df": 0, @@ -5679,7 +5966,7 @@ "k": { "df": 2, "docs": { - "20": { + "24": { "tf": 1.4142135623730951 }, "8": { @@ -5694,7 +5981,7 @@ "11": { "tf": 4.69041575982343 }, - "19": { + "23": { "tf": 1.0 } } @@ -5849,10 +6136,10 @@ "18": { "tf": 1.0 }, - "19": { + "2": { "tf": 1.0 }, - "2": { + "23": { "tf": 1.0 }, "4": { @@ -5907,7 +6194,7 @@ "s": { "df": 1, "docs": { - "22": { + "26": { "tf": 1.0 } } @@ -5941,6 +6228,26 @@ } } } + }, + "p": { + "df": 0, + "docs": {}, + "l": { + "df": 0, + "docs": {}, + "i": { + "c": { + "df": 1, + "docs": { + "19": { + "tf": 1.0 + } + } + }, + "df": 0, + "docs": {} + } + } } } }, @@ -6022,6 +6329,39 @@ "h": { "df": 0, "docs": {}, + "e": { + "a": { + "d": { + "df": 0, + "docs": {}, + "e": { + "df": 0, + "docs": {}, + "r": { + "df": 4, + "docs": { + "19": { + "tf": 1.0 + }, + "20": { + "tf": 1.0 + }, + "21": { + "tf": 1.0 + }, + "22": { + "tf": 1.0 + } + } + } + } + }, + "df": 0, + "docs": {} + }, + "df": 0, + "docs": {} + }, "i": { "d": { "d": { @@ -6128,7 +6468,7 @@ "k": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -6202,7 +6542,7 @@ "e": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -6235,7 +6575,7 @@ "t": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -6253,7 +6593,7 @@ "l": { "df": 1, "docs": { - "20": { + "24": { "tf": 1.0 } } @@ -6317,7 +6657,7 @@ "d": { "df": 1, "docs": { - "19": { + "23": { "tf": 1.0 } } @@ -6338,7 +6678,7 @@ "n": { "df": 3, "docs": { - "21": { + "25": { "tf": 1.0 }, "3": { @@ -6543,8 +6883,26 @@ "17": { "tf": 1.0 }, + "24": { + "tf": 1.0 + } + } + } + }, + "x": { + "df": 0, + "docs": {}, + "t": { + "df": 3, + "docs": { "20": { "tf": 1.0 + }, + "21": { + "tf": 1.0 + }, + "22": { + "tf": 1.0 } } } From 50bad7f9838740ac8619d552136d11f6411f8800 Mon Sep 17 00:00:00 2001 From: Pi Delport Date: Tue, 22 Feb 2022 18:00:41 +0200 Subject: [PATCH 14/38] style: add missing word --- guide/src/for_developers/preprocessors.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guide/src/for_developers/preprocessors.md b/guide/src/for_developers/preprocessors.md index 0054f242..1ac46256 100644 --- a/guide/src/for_developers/preprocessors.md +++ b/guide/src/for_developers/preprocessors.md @@ -61,7 +61,7 @@ The `chapter.content` is just a string which happens to be markdown. While it's entirely possible to use regular expressions or do a manual find & replace, you'll probably want to process the input into something more computer-friendly. The [`pulldown-cmark`][pc] crate implements a production-quality event-based -Markdown parser, with the [`pulldown-cmark-to-cmark`][pctc] allowing you to +Markdown parser, with the [`pulldown-cmark-to-cmark`][pctc] crate allowing you to translate events back into markdown text. The following code block shows how to remove all emphasis from markdown, From 917df6e97d79bc3f4c6250cfd1b6b6160a7127de Mon Sep 17 00:00:00 2001 From: Dylan DPC Date: Wed, 9 Mar 2022 08:04:50 +0100 Subject: [PATCH 15/38] update regex --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ffec902d..bf6c881d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1390,9 +1390,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.5.4" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" dependencies = [ "aho-corasick", "memchr", diff --git a/Cargo.toml b/Cargo.toml index 61b23e1d..6e225ea6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ log = "0.4" memchr = "2.0" opener = "0.5" pulldown-cmark = { version = "0.9.1", default-features = false } -regex = "1.0.0" +regex = "1.5.5" serde = "1.0" serde_derive = "1.0" serde_json = "1.0" From 6899d9402725e411c696e0c1942e3230ab4e0e01 Mon Sep 17 00:00:00 2001 From: Clark Date: Sat, 19 Mar 2022 04:38:16 +0800 Subject: [PATCH 16/38] livereload uses host&port of current page; livereload works with a HTTPS site --- src/cmd/serve.rs | 5 ++--- src/config.rs | 14 +++++++------- src/renderer/html_handlebars/hbs_renderer.rs | 7 +++++-- src/theme/index.hbs | 6 ++++-- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/cmd/serve.rs b/src/cmd/serve.rs index c5394f8a..b4782575 100644 --- a/src/cmd/serve.rs +++ b/src/cmd/serve.rs @@ -62,11 +62,10 @@ pub fn execute(args: &ArgMatches) -> Result<()> { let address = format!("{}:{}", hostname, port); - let livereload_url = format!("ws://{}/{}", address, LIVE_RELOAD_ENDPOINT); let update_config = |book: &mut MDBook| { book.config - .set("output.html.livereload-url", &livereload_url) - .expect("livereload-url update failed"); + .set("output.html.live-reload-endpoint", &LIVE_RELOAD_ENDPOINT) + .expect("live-reload-endpoint update failed"); if let Some(dest_dir) = args.value_of("dest-dir") { book.config.build.build_dir = dest_dir.into(); } diff --git a/src/config.rs b/src/config.rs index daeccbd0..6423100e 100644 --- a/src/config.rs +++ b/src/config.rs @@ -531,16 +531,16 @@ pub struct HtmlConfig { pub cname: Option, /// Edit url template, when set shows a "Suggest an edit" button for /// directly jumping to editing the currently viewed page. - /// Contains {path} that is replaced with chapter source file path + /// Contains {path} that is replaced with chapter source file path[[[[ pub edit_url_template: Option, - /// This is used as a bit of a workaround for the `mdbook serve` command. - /// Basically, because you set the websocket port from the command line, the - /// `mdbook serve` command needs a way to let the HTML renderer know where - /// to point livereloading at, if it has been enabled. + /// Endpoint of websocket, for livereload usage. Value loaded from .toml file + /// is ignored, because our code overrides this field with the value [`LIVE_RELOAD_ENDPOINT`] + /// + /// [`LIVE_RELOAD_ENDPOINT`]: cmd::serve::LIVE_RELOAD_ENDPOINT /// /// This config item *should not be edited* by the end user. #[doc(hidden)] - pub livereload_url: Option, + pub live_reload_endpoint: Option, /// The mapping from old pages to new pages/URLs to use when generating /// redirects. pub redirect: HashMap, @@ -569,7 +569,7 @@ impl Default for HtmlConfig { input_404: None, site_url: None, cname: None, - livereload_url: None, + live_reload_endpoint: None, redirect: HashMap::new(), } } diff --git a/src/renderer/html_handlebars/hbs_renderer.rs b/src/renderer/html_handlebars/hbs_renderer.rs index 69dc3124..f9f19a46 100644 --- a/src/renderer/html_handlebars/hbs_renderer.rs +++ b/src/renderer/html_handlebars/hbs_renderer.rs @@ -606,8 +606,11 @@ fn make_data( if theme.favicon_svg.is_some() { data.insert("favicon_svg".to_owned(), json!("favicon.svg")); } - if let Some(ref livereload) = html_config.livereload_url { - data.insert("livereload".to_owned(), json!(livereload)); + if let Some(ref live_reload_endpoint) = html_config.live_reload_endpoint { + data.insert( + "live_reload_endpoint".to_owned(), + json!(live_reload_endpoint), + ); } let default_theme = match html_config.default_theme { diff --git a/src/theme/index.hbs b/src/theme/index.hbs index 966eedbc..18d984a2 100644 --- a/src/theme/index.hbs +++ b/src/theme/index.hbs @@ -219,10 +219,12 @@ - {{#if livereload}} + {{#if live_reload_endpoint}}