Generate a SUMMARY.md
for your mdBook based on your folder structure!
Warning
The implementation is hacky and has several limitations, see below for more info.
src
├── bar
│ ├── chapter_5.md
│ ├── chapter_6.md
│ └── index.md
├── chapter_1.md
├── chapter_2.md
├── foo
│ ├── baz
│ │ ├── chapter_7.md
│ │ └── index.md
│ ├── chapter_3.md
│ ├── chapter_4.md
│ └── index.md
├── index.md
└── SUMMARY.md
is turned into
<!-- Generated by mdbook-autosummary v0.1.0 - do not edit manually! -->
[Home](index.md)
[Chapter 1](chapter_1.md)
[Chapter 2](chapter_2.md)
- [Section Bar](bar/index.md)
- [Chapter 5](bar/chapter_5.md)
- [Chapter 6](bar/chapter_6.md)
- [Section Foo](foo/index.md)
- [Chapter 3](foo/chapter_3.md)
- [Chapter 4](foo/chapter_4.md)
- [Section Baz](foo/baz/index.md)
- [Chapter 7](foo/baz/chapter_7.md)
The binaries are available in the GitHub releases section for all major platforms.
To install from source, you need a working installation of the Rust toolchain
After installing the toolchain, run:
cargo install mdbook-autosummary
To use the preprocessor, add the following to your book.toml
file:
[preprocessor.autosummary]
# This is so that mdBook doesn't start regenerating
# deleted folders before autosummary can remove them from SUMMARY.md
[build]
create-missing = false
It is additionally recommended to add SUMMARY.md
to .gitignore
.
- All folders that you want to be included in the
SUMMARY.md
must have anindex.md
(or equivalent) file in them. This is the file that will be linked to in theSUMMARY.md
.- Folders that do not have
index.md
(or equivalent) in them will be ignored.
- Folders that do not have
- All files should begin with an h1 (
#
) heading that will be used as the title of the page in theSUMMARY.md
.- The file/folder's name will be used as fallback if no h1 heading is found.
Warning
This must be the first preprocessor to run, otherwise the outputs of other preprocessors may be ignored!
To ensure this, add the following to the other preprocessors in your book.toml
file:
[preprocessor.foo]
after = ["autosummary"]
All configuration options are optional and go under the preprocessor.autosummary
table in book.toml
.
[preprocessor.autosummary]
# Controls the name of the index.md file that is looked for in each folder.
index-name = "index.md"
# If true, files that start with . or _ are ignored.
ignore-hidden = true
If a SUMMARY.md
doesn't exist when mdbook build
is run or is invalid, mdBook by default fails the build before calling any preprocessors.
This has the following implications:
- When deleting files or folders that were in
SUMMARY.md
before,SUMMARY.md
has to be emptied/truncated manually to force regeneration. - A
SUMMARY.md
must exist, even if it is empty, before runningmdbook build
.
Therefore it is recommended to not commit SUMMARY.md
to source control and adding it to .gitignore
. In addition, in CI/CD, an empty SUMMARY.md
must be created before running mdbook build
,
even with this preprocessor active.
The way it works internally is a bit hacky due to the fact that preprocessors are not supposed to modify SUMMARY.md
directly.
When the preprocessor is invoked, it generates a new SUMMARY.md
in memory & compares it to the existing one. If they do not match, the generated one overwrites to existing one, and the book is reloaded from disk entirely. If they do match, the preprocessor does nothing. To my knowledge this is the only way to force mdBook
to reparse the SUMMARY.md
file, short of parsing & building a Book
object yourself from scratch.
The side-effects of this approach are that mdBook is forced to reload the entire book when SUMMARY.md
changes, and possibly invoke some preprocessors multiple times as well. (If they are defined before mdbook-autosummary
) Also since this is a preprocessor, it is invoked for every backend that is built, although filehash comparisons are used to avoid unnecessary work.
The function to do that exists in mdBook
but is unfortunately private. Given the hacky nature of this preprocessor, I don't think it's worth the effort to make a PR to mdBook
to make it public, instead, alternative approaches to this problem should be explored. (For example adding the ability to specify the source of a summary to be an extension/preprocessor rather than a file)
Contributions are welcome! Please open an issue or a PR if you have any suggestions or improvements.
- Update the version in
Cargo.toml
- Update
CHANGELOG.md
- Push a new tag with the version number, prefixed with
v
(e.g.v0.1.0
) - CD will automatically build & publish the new version to crates.io & github