This config setting provides the ability to disable search indexing on a
per-chapter (or sub-path) basis.
This is structured to possibly add additional settings, such as perhaps
a score multiplier or other settings.
Uses an iframe instead. The downside of iframes comes from them
not necessarily being same-origin as the main page (particularly
with `file:///` URLs), which can cause themes to fall out of sync,
but that's not a problem here since themes don't work without JS
anyway.
Before this change, the Rust `unstable-book` is 88MiB.
With this change, it becomes 15MiB. Other pages might not be
as extreme, but it's expected to help any book like this.
This change is so drastic because, if every chapter has a link to
every other chapter, the result is *O*(n<sup>2</sup>) text output.
Above mentioned function copies files (recursively) from a source to a
destination directory. For that, file/directory paths have to be created
repeatedly. This allocates as directory and file names are concatenated
into an owning path structure.
The number of allocations can be reduced by creating file/directory
paths only once and borrowing them instead of cloning/recreating them.
In bigger projects, this reduces execution time noticeably. Please note
that file system operations are dominant from performance POV.
on rust reference book this reduces total allocs from 490mb to 474mb:
==23272== Total: 490,538,699 bytes in 1,760,117 blocks
==23272== At t-gmax: 13,872,954 bytes in 4,655 blocks
==23272== At t-end: 488,516 bytes in 884 blocks
==23272== Reads: 830,509,060 bytes
==23272== Writes: 522,290,614 bytes
to
==40876== Total: 474,156,323 bytes in 1,521,025 blocks
==40876== At t-gmax: 13,872,954 bytes in 4,655 blocks
==40876== At t-end: 488,516 bytes in 884 blocks
==40876== Reads: 820,933,434 bytes
==40876== Writes: 514,838,350 bytes
Currently, the output from `rustdoc --test` is not colored because
`rustdoc`'s stdout is not a tty. The output of a failed `rustdoc` run is
sent to `mdbook`'s stderr via the `error!()` macro. This commit checks
if stderr is a tty using the standard `.is_terminal()` and if so, passes
`--color always` to `rustdoc`.
The test output from `rustdoc` includes the full path that `rustdoc` was
called with. This obscures the path of the file with the error. E.g.,
```
---- /var/folders/9v/90bm7kb10fx3_bprxltb3t1r0000gn/T/mdbook-tnGJxp/lab0/index.md - Lab_0__Getting_Started (line 3) stdout ----
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `code`
--> /var/folders/9v/90bm7kb10fx3_bprxltb3t1r0000gn/T/mdbook-tnGJxp/lab0/index.md:4:6
|
3 | this code has a bug
| ^^^^ expected one of 8 possible tokens
error: aborting due to previous error
```
This commit runs `rustdoc` in the temp directory and replaces any
relative library paths with absolute library paths. This leads to
simpler error messages. The one above becomes
```
---- lab0/index.md - Lab_0__Getting_Started (line 3) stdout ----
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `code`
--> lab0/index.md:4:6
|
3 | this code has a bug
| ^^^^ expected one of 8 possible tokens
error: aborting due to previous error
```
(with colors, of course).
Nim is a systems programming language (included in the highlight.js
`system` group), and we're quite happily using `mdBook` in several of
our documentation projects starting with our [style
guide](https://status-im.github.io/nim-style-guide/).
While we can maintain our own highlight.js, including `Nim` in the
default distribution would allow us to promote more mdBook usage in the
Nim community at the cost of a ~2kb increase in the `highlight.js` size.
Replace phyiscal properties (top/bottom/left/right) with logical
properties (start/end) that can be used in non-LTR contexts (e.g.,
content in Arabic or Hebrew).
Based on the CSS Logical Properties and Values Level 1 specification,
currently an Editor's Draft [1].
Referencing MDN, all major browsers except Internet Explorer support the
margin, padding, and border properties.
[1]: https://drafts.csswg.org/css-logical/
Signed-off-by: Tim Crawford <crawfxrd@gmail.com>
The `.hljs` class added by highlight.js adds a `display: block` rule
which makes `padding` apply correctly (left padding on all lines,
not just the first one).
Make sure that rule is applied even if highlight.js isn't run.
Fix paths specified in extra-watch-dirs being relative to the current working directory rather than the book root
If there is an error canonicalising paths in extra-watch-dirs, log the error and exit rather than panicking
This switches to `gh` which is the more modern CLI, and also
available by default which removes the old installer script.
This also tightens the scope where GITHUB_TOKEN is exposed to just
the step where `gh` is executed.
Finally, it tightens the permissions on the GITHUB_TOKEN (though
`contents: write` is extremely permissive, since that allows writing to
almost anything in the repo).
Previously, sidebar scroll was set in an external script which caused a
flicker as the sidebar is initially rendered without any scroll before
being scrolled to the desired location.
Switching to an inline script right after the HTML tags for the sidebar
seems to avoid the flicker in most cases. In addition, logic is added to
avoid scrolling jumps when navigating via links within the sidebar.
The code here leads me to believe that the intention is for the sidebar
to be default visible on large screens (where `clientWidth` > 1080) and
hidden otherwise.
However, as previously written, if the `localStorage.getItem` call fails
(for example, if the user agent is not accepting cookies), then we fall
back to `sidebar = sidebar || 'visible';` — but `sidebar` is already set
to `hidden`, so the `|| 'visible'` never happens.
This results in the sidebar hiding itself on every navigation through an
mdBook, meaning if you're just switching between sections trying to find
something that you keep needing to re-open the sidebar.
It is preferable to remove WebKit-specific styling and use the browser
and OS default scrollbars.
Thanks to comments from @julianfortune, @arniu, and @ehuss.
Closes#1483.
While adding support for translations[1] to Comprehensive Rust 🦀, I
noticed that `mdbook test` doesn’t execute preprocessors the same way
as `mdbook build`.
This PR makes the two commands use the same code to find and execute
preprocessors.
[1]: https://github.com/google/comprehensive-rust/pull/130
Currently, the documentation link is specified in Cargo.toml as:
documentation = "http://rust-lang.github.io/mdBook/index.html"
which propagates to crates.io and if users click on the docs link there they get the non-TLS version. Not likely to cause major issues, but still best practice to use the HTTPS version since it's there
Quoting from the HTML specification[1]:
A document must not contain both a meta element with an http-equiv attribute
in the Encoding declaration state and a meta element with the charset
attribute present.
So we remove the <meta> with the http-equiv attribute from our template.
[1]: https://html.spec.whatwg.org/multipage/semantics.html#attr-meta-http-equiv-content-type
Allows for special styles to call them out since they're different than
normal text and different than code. They can make use of styles they
inherit for font style and weight.
Notes on changes:
- Added new CSS variables for reused elements
- The font-* rules are separate for each aspect so that they can inherit
bold/italic/etc
Closes https://github.com/rust-lang/mdBook/issues/1813
Before, a code block would always end with a final newline. The
newline was added unconditionally by `hide_lines`.
When the code block is syntax highlighted by highlight.js, this is not
a problem, no empty line is added for a final trailing `\n` character.
However, when the code block is editable and thus handled by the ACE
editor, a trailing newline _is_ significant. I believe this issue is
most closely described by https://github.com/ajaxorg/ace/issues/2083
in the upstream repository.
The effect of the way ACE handles newlines is that a code block like
<pre>
Some code
</pre>
will create an editor with _two_ lines, not just one.
By trimming trailing whitespace, we ensure that we don’t accidentally
create more lines in the ACE editor than necessary.
Surprisingly, this fixes the error filed at #1860!
This seems suspicious, perhaps indicative of a bug in Rust's non-lexical
lifetime handling?
The lifetimes in the `handlebars::Renderable::render` method signature
are quite complicated, and its unclear to me whether or not Rust is
catching some new safety edge-case that wasn't previously handled
correctly...
Possibly related to `drop` order, which I *think* is related to the
order of binding statements?
nixpkgs build system sets `RUST_LOG=` (empty value) by default.
This switches `mdBook` into warnings+ mode (instead of info+).
This causes the following tests to fail:
$ RUST_LOG= cargo test --test cli_tests
...
cli::test::mdbook_cli_can_correctly_test_a_passing_book
cli::test::mdbook_cli_detects_book_with_failing_tests
cli::build::mdbook_cli_dummy_book_generates_index_html
The change drops RUST_LOG= entry.
By default, `opener` launches the subprocess without waiting for its
completion, compared to `open` which waits for its completion.
This is helpful in case the `watch` feature is enabled and one of the
following commands `watch | serve --open` is used. If this command would
open the browser, listening for changes would be blocked by the browser.
Inputting paths are not necessary and will break ci, we can just leave paths out. We also changed 'master' to main since anyone reading this is probably going to be making mains
restructure guide configuration section
restructure guide configuration section
redirect to new config top level
fix broken links
use a relative path for redirect
Co-authored-by: Eric Huss <eric@huss.org>
remove extra heading
The `IndexPreprocessor` rewrites the path for files
named `README.md` to be `index.md`. This breaks the edit link
in some circumstances.
To address this issues, the `Chapter` struct has now a new attribute
called `source_path`. This is initialized with the same value as
`path`, but is never ever changed.
Finally, the edit link is built by using the `source_path` rather
than the `path`.
The existing light theme has relatively low contrast between the text
(and other UI elements) and background (especially within code blocks).
This presents difficulties for people with reduced visual contrast
perception (common in older adults).
This patch makes changes to the default `light` theme to meet the
minimum contrast requirement of the v2.1 W3C WCAG (Web Content
Accessibility Guidelines)
https://www.w3.org/WAI/WCAG21/quickref/#contrast-minimum
The small size, and slender font used for the title text makes it hard
to read, even with the increased contrast colour scheme, so this patch
also increases the size of the title text font by 20%.
Closes#1442
Provides better feedback if user executes in a different folder than what is expected by mdbook
After the changes `mdbook build`
```
2020-12-19 14:27:35 [ERROR] (mdbook::utils): Error: Couldn't open SUMMARY.md in "/Users/vicky/rust/source_codes/mdbook_testing/src/src" directory
2020-12-19 14:27:35 [ERROR] (mdbook::utils): Caused By: No such file or directory (os error 2)
```
Previously: `mdbook build`
```
2020-12-19 14:28:46 [ERROR] (mdbook::utils): Error: Couldn't open SUMMARY.md
2020-12-19 14:28:46 [ERROR] (mdbook::utils): Caused By: No such file or directory (os error 2)
```
With the current description of the command, I was expecting to get a directory named with the project name, but the files were created in the current directory.
I Think a more precise description would help first-time users.
Currently, the `copy_files` function doesn't support symlink files due to
its use of `DirEntry::metadata` - To avoid this issue, this patch
resolves the file path first before checking for metadata.
Fixes#1157
It's unlikely that the bundled version wouldn't load, and it's
especially unlikely that the page would load but the bundled version
would not.
Also, if it doesn't load, it should fall back to another monospace font,
which is fine.
Before:
/path/to$ cat book/.nojekyll
This file makes sure that Github Pages doesn't process mdBook's output./path/to$ ▎
After:
/path/to$ cat book/.nojekyll
This file makes sure that Github Pages doesn't process mdBook's output.
/path/to$ ▎
Summary items that had their name split into two lines ended up with the
last word of one line and the first word of the next line glued
together, since a space wasn't added.
Added test case for it.
Fixes#1218
In a recent discussion in the amethyst docs discord channel,
it was suggested that using an "eye" icon might make the show hidden
lines feature of mdbook's code sample rendering more discoverable.
I myself overlooked the arrows that are in use now.
Fixes#663 at least in part.
Updates to 10.1.1, with support for new languages added to the common set.
Built with:
common languages + D, handlebars, haskell, julia, scala, x86asm, armasm, yaml
Size difference:
New highlight.js: 132KiB
Old highlight.js: 84KiB
--
New highlight.js compressed: 48KiB
Old highlight.js compressed: 36KiB
- removed config output_404
- ensure serve overrides the site url, and hosts the correct 404 file
- refactor 404 rendering into separate fn
- formatting
* Removed the itertools dependency
* Removed an unused feature flag
* Stubbed out a toml_query replacement
* Update dependencies.
* Bump env_logger.
* Use warp instead of iron for http server.
Iron does not appear to be maintained anymore. warp/hyper seems to be
reasonably maintained. Unfortunately this takes a few seconds more
to compile, but shouldn't be too bad.
One benefit is that there is no longer a need for a separate websocket
port, which makes it easier to run multiple servers at once.
* Update pulldown-cmark to 0.7
* Switch from error-chain to anyhow.
* Bump MSRV to 1.39.
* Update elasticlunr-rs.
Co-authored-by: Michael Bryan <michaelfbryan@gmail.com>
At present, code listings without a main function will be wrapped in one and
annotated with an allow lint check attribute provided by the following [code][]:
```
format!(
"\n# #![allow(unused_variables)]\n{}#fn main() {{\n{}#}}",
attrs, code
)
```
A broader lint check attribute such as `#![allow(unused)]` seems like it might
better fit the apparent intent of this code.
Addresses: https://github.com/rust-lang/mdBook/issues/1192
[code]: 769cc0a7c1/src/renderer/html_handlebars/hbs_renderer.rs (L635-L638)
The serve and watch commands use .gitignore file in book root directory
to read exclude patterns used when watching for changed files. A
.gitignore from parent directory or user home is not used though.
Add documentation of this behaviour to both commands.
* Fix: Scroll sidebar to current active section (#1067)
* Clean: Some code related to PR #1052
* Change `scrollIntoViewIfNeeded` with `scrollIntoView`
* Don't use onload event for sidebar scroll to reduce flickering.
Co-authored-by: 李鸿章 <poodll@163.com>
I noticed that the CI badge was failing and it seems to be caused by the fact that it reflects the latest build including PRs. This change filters the events to only "push events on the master branch" so the badge stays green even if a PR fails.
* ui: improve menu folding
Fold/unfold the menu bar just by the amount of scroll, not by its
full width
* refactor: use a variable for the menu bar height
* Fix menu scroll jittering, remove hover folding smoothness
Rewrite it to use `position:` `sticky` and `relative` instead
of continuous programmatic position changes
On-hover folding-unfolding transition removal is a side-effect
This prevents recursive copy-loops when the destination directory
is contained in the source directory.
Now it bails out with a descriptive error message.
Html page title for every chapter in the book is created by the following code:
```rust
let title: String;
{
let book_title = ctx
.data
.get("book_title")
.and_then(serde_json::Value::as_str)
.unwrap_or("");
title = ch.name.clone() + " - " + book_title;
}
```
If the `book.toml` file is missing, and `book_title` parameter is empty, there's an awkward ` - ` string hanging at the end of each chapter's title.
This PR adds a `match` case to handle that kind of situation.
* Using .to_lowercase() on the theme matching to avoid needed exact capitolization in the book.toml
* Changed the default-dark-theme from .to_string() to .to_lowercase() to match theme
Doing what it says results in:
```
2019-11-04 16:13:15 [WARN] (mdbook::renderer::html_handlebars::hbs_renderer): Previous versions of mdBook erroneously accepted `./src/theme` as an automatic theme directory
2019-11-04 16:13:15 [WARN] (mdbook::renderer::html_handlebars::hbs_renderer): Please move your theme files to `./theme` for them to continue being used
```
This replaces the only use of px for font-sizes by setting up a base
rem size on the root element in a way that is easy to calculate (1 rem =
10px) and scaling up according to browser settings.
* Option to display copy buttons.
- Added field to playpen data structure
- Communicate through window.playpen_copyable
- Javascript updated to check before displaying copy buttons.
* html -> html_config
Also:
- update description of copyable in source code.
- update description of line_numbers (my last PR to this repository)
* Allow underscores in the link type name
* Add some tests for include anchors
* Include parts of Rust files and hide the rest
Fixes#618.
* Increase min supported Rust version to 1.35
* Add a test for a behavior of rustdoc_include I want to depend on
At first I thought this was a bug, but then I looked at some use cases
we have in TRPL and decided this was a feature that I'd like to use.
* Added support for gitignore files.
The watch command will now ignore files based on gitignore. This can be useful for when your editor creates cache or swap files.
* Ran cargo fmt.
* Made the code a bit tidier based on input from other Rust programmers.
Changed the type of the closure back to use PathBuf, not &PathBuf.
Reduced nesting.
- Added line numbers to config struct
- Added playpen_line_numbers field to hbs renderer.
- Added section to set `window.playpen_line_numbers = true` in page template
- Use line number global variable to show line numbers when required.
Use case: when trying to `mdbook test` a file that has many `include`
directives, and a test fails, the line numbers in the `rustdoc` output
don't match the line numbers in the original markdown file.
Turning on the markdown renderer implemented here lets you see what is
being passed to `rustdoc` by saving the markdown after the preprocessors
have run.
This renderer could be helpful for debugging many preprocessors, but
it's probably not useful in the general case, so it's turned off by
default.
* Extract the concept of a link having a range or anchor specified
So that other kinds of links can use this concept too.
* Extract a function for parsing range or anchor
This eliminates some duplication and will enable different kinds of
LinkTypes to have line number ranges.
Implement `From` for the std `Range` types to enable easier
construction.
The new code reaaalllly makes me wish for a delegation mechanism though
:(
Changing `cargo install` to `cargo install --path .` prevents the following error:
<span style="color: red;">error:</span> Using `cargo install` to install the binaries for the package in current working directory is no longer supported, use `cargo install --path .` instead. Use `cargo build` if you want to simply build the package.
* Rename a variable from playpen to link
Links can now be more than only playpen links
* Rename a field to match the enum type it holds
Also so that link.link.stuff doesn't happen when a variable link holds a
Link instance
* Update to pulldown-cmark 0.4.1.
* Update to pulldown-cmark 0.5.2.
* Remove pulldown-cmark-to-cmark dependency.
Since it is not compatible with the new pulldown-cmark. This example isn't
directly usable, anyways, and I think the no-op example sufficiently shows how
to make a preprocessor.
* cargo fmt
* Fix example link.
Updates to v9.15.8.
My main motivation is to fix a minor issue with TOML highlighting.
This keeps the same language list as before with the addition of a new "common"
language `properties` and added `julia` because someone asked for it and I like
julia. The full list from building:
:common armasm d go handlebars haskell julia rust scala swift x86asm yaml
- apache
- armasm
- bash
- coffeescript
- cpp
- cs
- css
- d
- diff
- go
- xml
- handlebars
- haskell
- http
- ini
- java
- javascript
- json
- julia
- makefile
- markdown
- nginx
- objectivec
- perl
- php
- properties
- python
- ruby
- rust
- scala
- shell
- sql
- swift
- x86asm
- yaml
This should fix deploying release artifacts and gh-pages for the documentation.
Secrets should now be configured in the UI for travis and appveyor.
This also removes some of the appveyor jobs, since they aren't really
necessary, and there are limited jobs on rust-lang-libs.
* Add if around stub summary creation
Check if an existing SUMMARY.md is present to prevent overwriting it
with the stub SUMMARY.md.
[#832]
* Add test for existing SUMMARY.md
Change overflow-x from auto to initial.
This resolves weird rendering behavior in Chrome and Safari on macOS.
With help from @bash
Co-authored-by: Ruben Schmidmeister <ruben.schmidmeister@icloud.com>
This is useful for situations where you'd like to
supplement or replace the existing Summary parsing with
custom filesystem traversal code or other similar changes.
The deploy scripts require TARGET env var to be set, but it wasn't set anywhere, causing it to fail: https://travis-ci.com/rust-lang-nursery/mdBook/builds/97850452.
This also reduces the number of mac builders, since they aren't necessary, and capacity is limited.
The api key will likely need to be updated, too, since the transition to travis.com.
Appveyor also seems to be broken, but I suspect it is also a key issue.
The livereload url was using an unknown property "websocket-address" instead of "websocket-hostname", hence it was always fallback onto the hostname (which can be different).
Previously, additional JavaScript files inside a directory were
correctly copied (with their parent created), but the link to it was
stripped of that parent.
There's no need for that (and it was not done for CSS)
* The preprocessor trait now returns a modified book instead of editing in place
* A preprocessor is told which render it's running for
* Made sure preprocessors get their renderer's name
* Users can now manually specify whether a preprocessor should run for a renderer
* You can normally use default preprocessors by default
* Got my logic around the wrong way
* Fixed the `build.use-default-preprocessors` flag
This class will supress the "play" button in the html backend (which you
can also do with the "ignore" class), but it will still let the code be
tested via `mdbook test` (which is not possible with the "ignore" class).
This is useful for code examples that don't really do much (and so the
user doesn't gain much from running them), but as an author you still
want to test them to guard against syntax errors and typos and the like.
This allows the search index to be loaded asynchronously, and should
use fewer resources as it doesn't have to execute the JS.
JS loading is kept as a fallback for CORS issues with file:// URIs in Chrome.
This adds instructions for building and testing books in CI on every PR and
push, as well as instructions for how to automatically deploy to gh-pages on
successful CI runs on `master`.
Fixes#714
* Add index preprocessor
README.md is a de facto index file in markdown-based documentation.
Hence, we respect to README.md and convert it into index.html.
* Fix warning for unused variables
* Update tests for config
* Match file stem case-insensitively for IndexPreprocessor
* Add tests for IndexPreprocessor
* Update book example to fit index preprocessor
* Update print styles for new sidebar behavior
* Hide copy icons in print output
* Wait for mathjax rendering to complete before printing
* Remove old wrapping css
Browsers this old are already hilariously broken, so we don't need these fallbacks.
* Change mathjax script type
Chrome won't execute this if it's not marked as js
* Ensure page has rendered before printing
In certain situations Chrome willl fire window.onLoad before it's
done rendering. Add a 100ms delay to work around this.
The reader should not be assumed male; I'm a developer and user,
I'm not male. Makes documentation's language gender neutral to
make it more welcoming to people that do not use he/him pronouns.
* Don't hide page content when displaying search
* Decrease sidebar animation time
* Fix search key event handler
which wasn't completely de-jqueryified.
* Avoid reflowing page content on small screens
This reduces jank caused by reflowing the page text while animating the
sidebar, and it looks nicer.
* Don't use HTMLParentNode.prepend()
since edge doesn't support it yet
* Don't animate menu border bottom color
since it's the same color as the background, which isn't animated.
* Small CSS improvments
- Remove invalid `pointer: cursor` style
- Disable transitions for noscript to stop page from spazzing on every load
- Add `cursor: pointer` to mark
- Disable `cursor: pointer` on noscript menu-title
* JS fixes
- Load MathJax async
- Always use local fontawesome and clipboard.js
- Move js class to html element to make theme switching easier
* Give the print button a bit more margin
* Use `git config` to get author name in `mdbook init`
* Return `None` if `git` command fails
* Use `.ok()?` to convert from Result to Option and return early if `None`
* Add search with elasticlunr.js
This commit adds search functionality to mdBook, based on work done by @phaiax. The in-browser search code uses elasticlunr.js to execute the search, using an index generated at book build time by elasticlunr-rs.
* Add generator comment
Someone on Reddit was wondering how the rust book was generated and said they checked the source. Thought I'd put this here. Might be a good idea to have a little footer "made with mdBook", but this'll do for now.
* Remove search/editor file override behavior
* Use for loop for book iterator
* Improve HTML regex
* Fix search CORS in file URIs
* Use ammonia to sanitize HTML
* Filter html5ever log messages
* First version of preprocessor example, with quicli
It seems it's not worth it right now.
* Remove quicli, just to simplify everything
* Finish de-emphasise example
* Finish preprocessor example in book
* Rename preprocessor type
* Apply changes requested in review
* Update preprocessor docs with latest code
[skip CI]
* feat(theme/index): Assume the sidebar is initially visible
In case the inline script does not execute, the fallback is to show the sidebar.
* feat(theme/index): Hide sidebar toggle and theme selector buttons when JavaScript is disabled
Makes no sense to show them in this case since they do not work.
* update documentation
Update README.md and User Guide to reflect addition of `clean`
subcommand. Do minor spelling fixes too.
* fix grammar in `clean` documentation
* fix(theme/book/themes): Check for control keys in event listener
* fix(theme/index): Menu role for theme selector
* fix(theme/book/themes): Handle focus when toggling theme list
* feat(theme/book/themes): Handle ArrowUp, ArrowDown, Home and End
> A position fixed left navigation bar does not want to hand off scrolling to the document because a scroll gesture performed on the navigation bar is almost never meant to scroll the document. In this case, the author can use contain on the sidebar to prevent scrolling from being chained to the parent document element.
https://wicg.github.io/overscroll-behavior/#motivating-examples
* Add docs for mdBook specific include feature.
Also:
* Fix bug in take_lines taking `end`-many lines instead of
`end-start` many.
* Handle special case `include:number` as including a single line.
* Start counting lines at 1 and not 0.
* Merge mdBook and rust specific features into one chapter.
* Handle input path with regards to custom css
Before, when someone like the Reference set their extra css as
"theme/reference.css" in their book.toml, this path would be treated as
relative to the invocation of mdbook, and not respect the input path. This
PR modifies these relative paths to do so.
Fixes the build of https://github.com/rust-lang/rust/pull/47753 which
blocks updating rustc to mdbook 0.1
* don't use file-name
the style name is theme/reference.css, this results in a Err(StripPrefixError(())), which means that we push only the file_name, losing the theme bit
Tested this on macOS with VoiceOver, and it does not pick up the title as the text of the button. Kind of makes sense, since title and aria-label are not the same. This will make sure that the buttons and links are labeled properly.
Advantages:
- Easier to reason about
- Can easily disable some modules when debugging
- Shared dependencies are explicit (playpen_text)
- Enables some fancier things later one (e.g. run `codeSnippets` slightly later, to avoid blocking the page)
I'm aware that `codeSnippets` should be split into the highlighter and the editor, but I'm not sure I understand exactly how they interact so I've left it as it is for now.
* Added documentation to the `config` module
* Added an example to the `config` module
* Updated the docs in lib.rs regarding implementing backends
* Started writing an alternate backends walkthrough
* Mentioned the output.foo.command key
* Added example output
* Added a config section to the backends tutorial
* Finished off the backends tutorial
* Made sure travis checks mdbook-wordcount
* Fixed the broken link at in the user guide
* Changed how travis builds the project
* Added a conclusion
* Went through and documented a lot of stuff
* Added a preprocessors chapter and updated For Developers
* Added a windows-specific `tee` equivalent
* Changed how the windows "tee" command gets quoted
* Temporarily disabled the backends_receive_render_context_via_stdin test
* feat(theme/stylus/menu): Make sticky
* feat(theme/stylus/menu): Faint bottom border
* feat(theme/book): Auto hide menu when scrolling down
* feat(theme/stylus/menu): Don't hide title
* feat(theme/stylus/menu): Only show bottom border when sticky
* fix(theme/stylus/menu): Don't hide when sidebar is expanded
* feat(theme/book): Show menu bar on hover
* fix(theme/index): Use nav element for Table of Content
* fix(renderer/html_handlebars/helpers/toc): Use ol instead of ul
Chapters and sections are ordered, so we should use the appropriate HTML tag.
* fix(renderer/html_handlebars/helpers/toc): Hide section number from screen readers
Screen readers have this functionality build-in, no need to present this. Ideally, this should not even be in the DOM tree, since the numbers can be shown by using CSS.
* fix(theme/index): Remove tabIndex="-1" from .page
Divs are not focusable by default
* fix(theme): Make sidebar accessible
Using aria-hidden (together with tabIndex) takes the links out of the tab order.
http://heydonworks.com/practical_aria_examples/#progressive-collapsibles
* fix(theme/index): Wrap content inside main tag
The main tag helps users skip additional content on the page.
* fix(theme/book): Don't focus .page on page load
The main content is identified by the main tag, not by auto-focusing it on page load.
* fix(theme/index): Make page controls accessible
* fix: Make theme selector accessible
- Use ul and li (since it is a list)
- Add aria-expanded and aria-haspopup to the toggle button
- Use button instead of div (buttons are accessible by default)
- Handle Esc key (close popup)
- Adjust CSS to keep same visual style
* fix(theme/stylus/sidebar): Make link clickable area wider
Links now expand to fill the entire row.
* fix(theme): Wrap header buttons and improve animation performance
Previously, the header had a fixed height, which meant that sometimes the print button was not visible. Animating the left property is expensive, which lead to laggy animations - transform is much cheaper and has the same effect.
* fix(theme/stylus/theme-popup): Theme button inherits color
Bug introduced while making the popup accessible
* fix(theme/book): Handle edge case when toggling sidebar
Bug introduced when switching from animating left to using transform.
* Added the ability to update config settings from env vars
* Added tests
* Documented that you can override configuration with environment
variables
* Refactored the config get() methods to use toml-query
* Made the `Updateable` trait more generic
* Added a mechanism for creating alternate backends
* Added a CmdRenderer and the ability to have multiple renderers
* Made MDBook::load() autodetect renderers
* Added a couple methods to RenderContext
* Converted RenderContext.version to a String
* Made sure all alternate renderers are invoked as `mdbook-*`
* Factored out the logic for determining which renderer to use
* Added tests for renderer detection
* Made it so `mdbook test` works on the book-example again
* Updated the "For Developers" docs
* Removed `[output.epub]` from the example book's book.toml
* Added a bit more info on how backends should work
* Added a `destination` key to the RenderContext
* Altered how we wait for an alternate backend to finish
* Refactored the Renderer trait to not use MDBook and moved livereload to the template
* Moved info for developers out of the book.toml format chapter
* MOAR docs
* MDBook::build() no longer takes &mut self
* Replaced a bunch of println!()'s with proper log macros
* Cleaned up the build() method and backend discovery
* Added a couple notes and doc-comments
* Found a race condition when backends exit really quickly
* Added support for backends with arguments
* Fixed a funny doc-comment
* Prohibit 'print.md' files
Fix#258 by emmiting an error whenever an mdBook contains a
"print.md" file in its root.
* Apply suggested changes
* Add tests
* Implement partial include of source files.
The macro `{{include some_file}}` accepts now optional line number
arguments, s.t. the specified line range is included. The following
forms are supported:
* `{{include some_file::}}` is equivalent to `{{include some_file}}`
* `{{include some_file:from:}}` includes lines [from, infinity)
* `{{include some_file::to}}` includes lines [0, to]
* `{{include some_file:from:to}}` includes lines [from, to]
* Remove the special case IncludeFull which is IncludeFrom(0).
* Use Range, RangeFrom, RangeTo and RangeFull to represent include-ranges.
Also:
* Move out introduced methods as free functions.
* Introduce RangeArgument trait as long it is unstable in stdlib.
* Use itertools for joining of lines on the fly.
* Split tests.
* Simplify include file argument parsing.
* Make utils::string private and link collections_range feature issue.
* Use japaric/trust for travis configuration
* Moved the github pages logic (not running the script breaks the build)
* Removed the x86 linux musl build
This rolls all "create missing" handling into BuildConfig, and moves the
build-dir option from the "book" table to the "build" table. Some
documentation cleanup surrounding the build table is also updated.
* Refactor navigation helpers
* Target::find: take previous_item by reference
This makes more sense for find as an interface, though it causes a
second clone in some cases. Maybe rustc is smart here?
* Test next and previous navigation helpers
* Add more next/previous tests
* Created regression tests for the table of contents
* Refactoring to make the test more readable
* Fixed some bitrot and removed the (now redundant) tests/helper module
* Removed the include_str!() stuff and use just the dummy book for testing
* Regression tests now pass again!
* Pinned a `*` dependency to use a particular version
* Made sure test mocks return errors instead of panicking
* Addressed the rest of @budziq's review
* Replaced a file open/read with file_to_string
This commit changes the url used to call the playground, and the
request parameter format to go with it. The older evaluate is
available in the playground as a form of backwards compatibility
and swithcing now opens way for using newer features.
On the web, the normalized path separator is forward-slash (`/`), so we
use the built-in `is_separator()` method to replace any path separator
with the forward-slash, to ensure consistent output on unix and windows
machines.
Move non-test test module files into their own directories to prevent
cargo from running them as tests. Then suppress the left-over warnings.
Move *dummy book* code and data into a shared folder, and leave the rest
of helper utilities (one function) in the original module.
IIUC, the existing exclude rule has meant to do what it will do in the
future (gitignore-like matching, not glob-only matching). This fix makes
the rule to do what it was expected to do, and is forward-compatible,
therefore fixing the warning messages.
- list of available crates is dynamically loaded from play.rust-lang.org
- play button is enabled only if crates used in snippet are available on playground
- ACE editor's play button is dynamically updated on each text change
- `no_run` is honored by always disabling the play button
- minor cleanups
To only ignore the output destination (default: `book`) and no other
file/directory with the same name under the mdbook root, we should
prefix the gitignore rule with a leading slash (default: `/book`).
The toml crate removed its serde dependency in 0.3, but in 0.4, it
went away. Cargo didn't warn on this, but now it does. As such, we
need a release so that rust's build doesn't warn constantly.
- Replaced link parser with a Regex
- Implemented {{#include}} links
- Will display relatively nice error when cannot open {{#}} linked file
- Escaped links no longer render with escape char
- utils::fs::file_to_path no takes AsRef<Path>
- sorted export/mod in lib.rs
`HtmlConfig` was both guaranteed to exist within `BookConfig`
and `expect`ed in few places.
This simplifies the API a little by representing the fact that
`HtmlConfig` is currently mandatory for proper mdBook binary operation.
On `x86_64-unknown-linux-musl` it looks like travis can't compile
the `backtrace-sys` crate because the `./configure` step fails.
The error message `./configure` gives is:
configure: error: in `/home/travis/build/azerupi/mdBook/target/x86_64-unknown-linux-musl/debug/build/backtrace-sys-204dc57c91e9a514/out':
configure: error: C compiler cannot create executables
* This is a built-in function of iOS Safari that didn't work because the
page content was inside absolutely-positioned, scrollable divs.
* The fix is to stop using absolute positioning on `.page-wrapper` and
`.page`, so that the content uses static positioning and flows
naturally down the page.
* Consequently, `.sidebar` and `.nav-chapter` now have to use `position:
fixed` in order to be positioned relative to the viewport.
* This fix also enables Safari's built-in behavior of automatically
hiding the top and bottom toolbars when scrolling down the page.
- removing need to explicitly use `Path::new` all over the place
- removed warnings from doctests (normally invisible unless `cargo test -- --nocapture`)
- no doctests are norun/ignore now
- updated docs both in book-example and in docs not to refer to nonexisting API's
Fixes a lot of browser incompatibilities in localStorage/cookie handling
Including but not limited to:
- loss of styling and functionality on chromium private mode
- loss of styling and functionality on safari and safari private mode
- awaiting verification if problems in mobile safari are solved.
As `theme` dir is no longer under `src`. Updates to "theme" did not
trigger book rebuild.
Also fixed misleading docs about `theme` dir being located in `src`
List of system fonts (R, I, B means roman, italic and bold. Ubuntu probably comes with more fonts, but I couldn't find a list to confirm.):
```txt
Windows
----------
Consolas R RI B BI
Courier R
Courier New R RI B BI
Lucida Console R
Mac
----------
Andale Mono R
Courier R RI B BI
Courier New R RI B BI
Menlo R RI B BI
Monaco R
Ubuntu
----------
Ubuntu Mono R RI B BI
DejaVu Sans Mono R RI B BI
```
```css
font-family: Consolas, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace, monospace;
```
Consolas and Ubuntu are professionally designed fonts ([Lucas de Groot][1] and [Dalton Maag][2]), with true, calligraphic italic, so they go at the top of the stack.
Menlo is [based on DejaVu Sans Mono][3], the only difference being a few tweaked glyphs, so DejaVu serves as a fallback for it.
As for Courier New, other than being unreadably spindly, it's the default monospaced font in all browsers, so there's no need to include it in the stack.
The `monospace, monospace;` declaration is, by now, [a standard hack][4] that overrides some browsers' behaviour of defaulting the `monospace` elements to smaller font size. Without it, any relative font size you apply to them will be calculated from that reduced size (seems to be 13 px in all browsers).
[1]: https://en.wikipedia.org/wiki/Luc(as)_de_Groot
[2]: https://en.wikipedia.org/wiki/Dalton_Maag
[3]: http://www.leancrew.com/all-this/2009/10/the-compleat-menlovera-sans-comparison/
[4]: https://stackoverflow.com/questions/38781089/font-family-monospace-monospace
Hidden code blocks are no longer indented with
one additional space (required for doctests to compile in some cases)
Now the behavior is similar to the rustdoc's
This commit:
- Adds an Option<String> field to the BookConfig which should
contain your google analytics ID
- Allows the google analytics ID to be extracted from the config
file (key is google_analytics_id)
- Adds a test to make sure the field is populated from a config
file correctly
Header fragment links now use "id" attribute instead of the depreciated
"name" attribute.
Similar headers are given numbered ids to avoid id collisions.
For instance, if there are three headers named "Example", their ids
would be "#example", "#example-1", and "#example-2" respectively.
This project already had a transitive dependency on regex; let's use it.
This isn't the most efficient solution, but it should be fine. It ends
up doing five full scans of the text. There's probably an easier way but
I'm mostly just trying to get this to work for now.
This also implements the same algorithm that rustdoc does for generating
the name for the link.
Fixes#204
This fixes a broken link on http://azerupi.github.io/mdBook/cli/init.html
The `..` is redundant because the document's base URI is set to
`path_to_root`. It breaks if the base URI is not at the server root.
Fixes#179.
Highlight.js does not apply syntax highlighting to code blocks marked
no-highlight, nohighlight, plain, or text. When it finds blocks of those
languages, it does not add the `hljs` class to those code blocks either.
highlight.css and tomorrow-night.css use the `hljs` class to give code
blocks their backrgound color and text color, and we want that to apply
even if the code doesn't get syntax highlighting markup.
This is a somewhat hacky solution to get just that behavior! After this
commit, code blocks with no-highlight, nohighlight, plain, or text
language set on them will indeed get the hljs colors.
The current section headers are url encoded. Because of that they
have some funny characters like %20. We can clean that up by removing
all of the non-word characters before placing them in the anchor.
mdBook is setting theme (by adding a class attribute to body tag) with javascript.
Page is not using any theme by default and page is not using any styling unless
javascript is enabled.
This patch is adding class attribute to body tag and making mdBook to use `light`
theme when javascript is disabled.
Fixes: #144
MDBook now stores the necessary information, BookConfig is not used as a field anymore. It is only used for parsing the configuration file. This allows to more easily replace the book.json config with the new tomlbased config
If you have come here to learn how to contribute to mdBook, we have some tips for you!
First of all, don't hesitate to ask questions!
Use the [issue tracker](https://github.com/rust-lang/mdBook/issues), no question is too simple.
### Issue assignment
**:warning: Important :warning:**
Before working on pull request, please ping us on the corresponding issue.
The current PR backlog is beyond what we can process at this time.
Only issues that have an [`E-Help-wanted`](https://github.com/rust-lang/mdBook/labels/E-Help-wanted) or [`Feature accepted`](https://github.com/rust-lang/mdBook/labels/Feature%20accepted) label will likely receive reviews.
If there isn't already an open issue for what you want to work on, please open one first to see if it is something we would be available to review.
### Issues to work on
If you are starting out, you might be interested in the
When you decide you want to work on a specific issue, and it isn't already assigned to someone else, assign the issue to yourself by leaving a comment with the text `@rustbot claim`.
Again, do not hesitate to ask questions. We will gladly mentor anyone that want to tackle an issue.
Issues on the issue tracker are categorized with the following labels:
- **A**-prefixed labels state which area of the project an issue relates to.
- **E**-prefixed labels show an estimate of the experience necessary to fix the issue.
- **M**-prefixed labels are meta-issues regarding the management of the mdBook project itself
- **S**-prefixed labels show the status of the issue
- **C**-prefixed labels show the category of issue
### Building mdBook
mdBook builds on stable Rust, if you want to build mdBook from source, here are the steps to follow:
1. Navigate to the directory of your choice
0. Clone this repository with git.
```
git clone https://github.com/rust-lang/mdBook.git
```
0. Navigate into the newly created `mdBook` directory
0. Run `cargo build`
The resulting binary can be found in `mdBook/target/debug/` under the name `mdbook` or `mdbook.exe`.
### Code Quality
We love code quality and Rust has some excellent tools to assist you with contributions.
#### Formatting Code with rustfmt
Before you make your Pull Request to the project, please run it through the `rustfmt` utility.
This will ensure we have good quality source code that is better for us all to maintain.
[rustfmt](https://github.com/rust-lang/rustfmt) has a lot more information on the project.
The quick guide is
1. Install it (`rustfmt` is usually installed by default via [rustup](https://rustup.rs/)):
```
rustup component add rustfmt
```
1. You can now run `rustfmt` on a single file simply by...
```
rustfmt src/path/to/your/file.rs
```
... or you can format the entire project with
```
cargo fmt
```
When run through `cargo` it will format all bin and lib files in the current package.
For more information, such as running it from your favourite editor, please see the `rustfmt` project. [rustfmt](https://github.com/rust-lang/rustfmt)
#### Finding Issues with Clippy
[Clippy](https://doc.rust-lang.org/clippy/) is a code analyser/linter detecting mistakes, and therefore helps to improve your code.
Like formatting your code with `rustfmt`, running clippy regularly and before your Pull Request will help us maintain awesome code.
1. To install
```
rustup component add clippy
```
2. Running clippy
```
cargo clippy
```
### Change requirements
Please consider the following when making a change:
* Almost all changes that modify the Rust code must be accompanied with a test.
* Almost all features and changes must update the documentation.
mdBook has the [mdBook Guide](https://rust-lang.github.io/mdBook/) whose source is at <https://github.com/rust-lang/mdBook/tree/master/guide>.
* Almost all Rust items should be documented with doc comments.
See the [Rustdoc Book](https://doc.rust-lang.org/rustdoc/) for more information on writing doc comments.
* Breaking the API can only be done in major SemVer releases.
These are done very infrequently, so it is preferred to avoid these when possible.
See [SemVer Compatibility](https://doc.rust-lang.org/cargo/reference/semver.html) for more information on what a SemVer breaking change is.
(Note: At this time, some SemVer breaking changes are inevitable due to the current code structure.
An example is adding new fields to the config structures.
These are intended to be fixed in the next major release.)
* Similarly, the CLI interface is considered to be stable.
Care should be taken to avoid breaking existing workflows.
* Check out the [Rust API Guidelines](https://rust-lang.github.io/api-guidelines/) for guidelines on designing the API.
### Making a pull-request
When you feel comfortable that your changes could be integrated into mdBook, you can create a pull-request on GitHub.
One of the core maintainers will then approve the changes or request some changes before it gets merged.
The following are instructions for updating [highlight.js](https://highlightjs.org/).
1. Clone the repository at <https://github.com/highlightjs/highlight.js>
1. Check out a tagged release (like `10.1.1`).
1. Run `npm install`
1. Run `node tools/build.js :common apache armasm coffeescript d handlebars haskell http julia nginx nim nix properties r scala x86asm yaml`
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. The [test_book](https://github.com/rust-lang/mdBook/tree/master/test_book) contains a chapter with many languages to examine.
## Publishing new releases
Instructions for mdBook maintainers to publish a new release:
1. Create a PR to update the version and update the CHANGELOG:
1. Update the version in `Cargo.toml`
2. Run `cargo test` to verify that everything is passing, and to update `Cargo.lock`.
3. Double-check for any SemVer breaking changes.
Try [`cargo-semver-checks`](https://crates.io/crates/cargo-semver-checks), though beware that the current version of mdBook isn't properly adhering to SemVer due to the lack of `#[non_exhaustive]` and other issues. See https://github.com/rust-lang/mdBook/issues/1835.
4. Update `CHANGELOG.md` with any changes that users may be interested in.
5. Update `continuous-integration.md` to update the version number for the installation instructions.
6. Commit the changes, and open a PR.
2. After the PR has been merged, create a release in GitHub. This can either be done in the GitHub web UI, or on the command-line:
For more information about what is left on my to-do list, check the issue tracker
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 [**Documentation**](http://azerupi.github.io/mdBook/) 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 2 ways to install mdBook but both require [Rust and Cargo](https://www.rust-lang.org/) to be installed.
##### Install from Crates.io
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 you that will be left to do is add the Cargo bin directory to your path.
##### Install 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***!
The executable will be in `./target/release/mdbook`.
## Usage
mdBook will primaraly be 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 [documentation](http://azerupi.github.io/mdBook/).
-`mdbook init`
The init command will create a directory with the minimal boilerplate to start with.
```
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 ouput to the `book` directory.
Please, take a look at the [**Documentation**](http://azerupi.github.io/mdBook/cli/init.html) 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.
### 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 and easy to use API and more!
See the [Documentation](http://azerupi.github.io/mdBook/lib/lib.html) and the [API docs](http://azerupi.github.io/mdBook/mdbook/index.html) 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.
People who are not familiar with the code can look at [issues that are tagged **easy**](https://github.com/azerupi/mdBook/labels/Easy). A lot of issues are also related to web development, so people that are not comfortable with Rust can also participate! :wink:
You can pick any issue you want to work on. Usually it's a good idea to ask if someone is already working on it and if not to claim the issue.
If you are interested in contributing to the development of mdBook, check out the [Contribution Guide].
## License
All the code is released under the ***Mozilla Public License v2.0***, for more information take a look at the [LICENSE](LICENSE) file
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.
**mdBook** is a command line tool and Rust crate to create books using Markdown files. It's very similar to Gitbook but written in [Rust](http://www.rust-lang.org).
What you are reading serves as an example of the output of mdBook and at the same time as high-level docs.
mdBook is free and open source, you can find the source code on [Github](https://github.com/azerupi/mdBook). Issues and feature requests can be posted on the [Github Issue tracker](https://github.com/azerupi/mdBook/issues).
## API docs
Alongside this book you can also read the [API docs](mdbook/index.html) generated by Rustdoc if you would like
to use mdBook as a crate or write a new renderer and need a more low-level overview.
## License
mdBook, all the source code, is released under the [Mozilla Public License v2.0](https://www.mozilla.org/MPL/2.0/)
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.
## Install
### Pre-requisite
mdBook is written in **[Rust](https://www.rust-lang.org/)** and therefore needs to be compiled with **Cargo**, because we don't yet offer ready-to-go binaries. If you haven't already installed Rust, please go ahead and [install it](https://www.rust-lang.org/downloads.html) 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 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/azerupi/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.
There is some minimal boilerplate that is the same for every new book. It's for this purpose that mdBook includes an `init` command.
The `init` command is used like this:
```bash
mdbook init
```
When using the `init` command for the first time, a couple of files will be set up for you:
```bash
book-test/
├── book
└── src
├── chapter_1.md
└── SUMMARY.md
```
- The `src` directory is were you write your book in markdown. It contains all the source files,
configuration files, etc.
- The `book` directory is where your book is rendered. All the output is ready to be uploaded
to a server to be seen by your audience.
- The `SUMMARY.md` file is the most important file, it's the skeleton of your book and is discussed in more detail in another [chapter](../format/summary.html).
#### Tip & Trick: Hidden Feature
When a `SUMMARY.md` file already exists, the `init` command will first parse it and generate the missing files according to the paths used in the `SUMMARY.md`. This allows you to think and create the whole structure of your book and then let mdBook generate it for you.
#### Specify a directory
When using the `init` command, you can also specify a directory, instead of using the current working directory,
by appending a path to the command:
```bash
mdbook init path/to/book
```
## --theme
When you use the `--theme` argument, the default theme will be copied into a directory
called `theme` in your source directory so that you can modify it.
The theme is selectively overwritten, this means that if you don't want to overwrite a
specific file, just delete it and the default file will be used.
When writing a book, you sometimes need to automate some tests. For example, [The Rust Programming Book](https://doc.rust-lang.org/stable/book/) uses a lot of code examples that could get outdated.
Therefore it is very important for them to be able to automatically test these code examples.
mdBook supports a `test` command that will run all available tests in mdBook. At the moment, only one test is available:
*"Test Rust code examples using Rustdoc"*, but I hope this will be expanded in the future to include more tests like:
- checking for broken links
- checking for unused files
- ...
In the future I would like the user to be able to enable / disable test from the `book.json` configuration file and support custom tests.
The `watch` command is useful when you want your book to be rendered on every file change.
You could repeatedly issue `mdbook build` every time a file is changed. But using `mdbook watch` once will watch your files and will trigger a build automatically whenever you modify a file.
#### Specify a directory
Like `init` and `build`, `watch` can take a directory as argument to use instead of the
current working directory.
```bash
mdbook watch path/to/book
```
-----
***note:*** *the `watch` command has not gotten a lot of testing yet, there could be some rough edges. If you discover a problem, please report it [on Github](https://github.com/azerupi/mdBook/issues)*
You can configure the parameters for your book in the ***book.json*** file.
Here is an example of what a ***book.json*** file might look like:
```json
{
"title":"Example book",
"author":"Name",
"dest":"output/my-book"
}
```
#### Supported variables
- **title:** title of the book
- **author:** author of the book
- **dest:** path to the directory where you want your book to be rendered. If a relative path is given it will be relative to the parent directory of the source directory
***note:*** *the supported configurable parameters are scarce at the moment, but more will be added in the future*
There is a feature in mdBook that let's you hide code lines by prepending them with a `#`.
```bash
#fn main() {
letx= 5;
lety= 6;
println!("{}", x + y);
#}
```
Will render as
```rust
#fnmain(){
letx=5;
lety=7;
println!("{}",x+y);
#}
```
## Inserting runnable Rust files
With the following syntax, you can insert runnable Rust files into your book:
```hbs
\{{#playpenfile.rs}}
```
The path to the Rust file has to be relative from the current source file.
When play is clicked, the code snippet will be send to the [Rust Playpen]() to be compiled and run. The result is send back and displayed directly underneath the code.
The summary file is used by mdBook to know what chapters to include,
in what order they should appear, what their hierarchy is and where the source files are.
Without this file, there is no book.
Even though `SUMMARY.md` is a markdown file, the formatting is very strict to
allow for easy parsing. Let's see how you should format your `SUMMARY.md` file.
#### Allowed elements
1.***Title*** It's common practice to begin with a title, generally
<codeclass="language-markdown"># Summary</code>.
But it is not mandatory, the parser just ignores it. So you can too
if you feel like it.
2.***Prefix Chapter*** Before the main numbered chapters you can add a couple of elements that will not be numbered. This is useful for
forewords, introductions, etc. There are however some constraints. You can not nest prefix chapters, they should all be on the root level. And you can not add prefix chapters once you have added numbered chapters.
```markdown
[Title of prefix element](relative/path/to/markdown.md)
```
3. ***Numbered Chapter*** Numbered chapters are the main content of the book, they will be numbered and can be nested,
resulting in a nice hierarchy (chapters, sub-chapters, etc.)
```markdown
- [Title of the Chapter](relative/path/to/markdown.md)
```
You can either use `-` or `*` to indicate a numbered chapter.
4.***Sufix Chapter*** After the numbered chapters you can add a couple of non-numbered chapters. They are the same as prefix chapters but come after the numbered chapters instead of before.
All other elements are unsupported and will be ignored at best or result in an error.
For syntax highlighting I use [Highlight.js](https://highlightjs.org) with a custom theme.
Automatic language detection has been turned off, so you will probably want to
specify the programming language you use like this
<pre><codeclass="language-markdown">```rust
fn main() {
// Some code
}
```</code></pre>
## Custom theme
Like the rest of the theme, the files used for syntax highlighting can be overridden with your own.
- ***highlight.js*** normally you shouldn't have to overwrite this file, unless you want to use a more recent version.
- ***highlight.css*** theme used by highlight.js for syntax highlighting.
If you want to use another theme for `highlight.js` download it from their website, or make it yourself,
rename it to `highlight.css` and put it in `src/theme` (or the equivalent if you changed your source folder)
Now your theme will be used instead of the default theme.
## Hiding code lines
There is a feature in mdBook that let's you hide code lines by prepending them with a `#`.
```bash
#fn main() {
let x = 5;
let y = 6;
println!("{}", x + y);
#}
```
Will render as
```rust
#fn main() {
let x = 5;
let y = 7;
println!("{}", x + y);
#}
```
**At the moment, this only works for code examples that are annotated with `rust`. Because it would collide with semantics of some programming languages. In the future, we want to make this configurable through the `book.json` so that everyone can benefit from it.**
## Improve default theme
If you think the default theme doesn't look quite right for a specific language, or could be improved.
Feel free to [submit a new issue](https://github.com/azerupi/mdBook/issues) explaining what you have in mind and I will take a look at it.
You could also create a pull-request with the proposed improvements.
Overall the theme should be light and sober, without to many flashy colors.
The default renderer uses a [handlebars](http://handlebarsjs.com/) template to render your markdown files and comes with a default theme
included in the mdBook binary.
The theme is totally customizable, you can selectively replace every file from the theme by your own by adding a
`theme` directory in your source folder. Create a new file with the name of the file you want to override
and now that file will be used instead of the default file.
Here are the files you can override:
- ***index.hbs*** is the handlebars template.
- ***book.css*** is the style used in the output. If you want to change the design of your book, this is probably the file you want to modify. Sometimes in conjunction with `index.hbs` when you want to radically change the layout.
- ***book.js*** is mostly used to add client side functionality, like hiding / un-hiding the sidebar, changing the theme, ...
- ***highlight.js*** is the JavaScript that is used to highlight code snippets, you should not need to modify this.
- ***highlight.css*** is the theme used for the code highlighting
- ***favicon.png*** the favicon that will be used
Generally, when you want to tweak the theme, you don't need to override all the files. If you only need changes in the stylesheet,
there is no point in overriding all the other files. Because custom files take precedence over built-in ones, they will not get updated with new fixes / features.
**Note:** When you override a file, it is possible that you break some functionality. Therefore I recommend to use the file from the default theme as template and only add / modify what you need. You can copy the default theme into your source directory automatically by using `mdbook init --theme` just remove the files you don't want to override.
Here is a list of the contributors who have helped improving mdBook. Big shout-out to them!
If you have contributed to mdBook and I forgot to add you, don't hesitate to add yourself to the list. If you are in the list, feel free to add your real name & contact information if you wish.
- [mdinger](https://github.com/mdinger)
- Kevin ([kbknapp](https://github.com/kbknapp))
- Steve Klabnik ([steveklabnik](https://github.com/steveklabnik))
- Adam Solove ([asolove](https://github.com/asolove))
- Wayne Nilsen ([waynenilsen](https://github.com/waynenilsen))
- [funnkill](https://github.com/funkill)
- Fu Gangqiang ([FuGangqiang](https://github.com/FuGangqiang))
There are different backends used to determine when a file has changed.
*`poll` (default) --- Checks for file modifications by scanning the filesystem every second.
*`native` --- Uses the native operating system facilities to receive notifications when files change.
This can have less constant overhead, but may not be as reliable as the `poll` based watcher. See these issues for more information: [#383](https://github.com/rust-lang/mdBook/issues/383) [#1441](https://github.com/rust-lang/mdBook/issues/1441) [#1707](https://github.com/rust-lang/mdBook/issues/1707) [#2035](https://github.com/rust-lang/mdBook/issues/2035) [#2102](https://github.com/rust-lang/mdBook/issues/2102)
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:
When writing a book, you sometimes need to automate some tests. For example,
[The Rust Programming Book](https://doc.rust-lang.org/stable/book/) uses a lot
of code examples that could get outdated. Therefore it is very important for
them to be able to automatically test these code examples.
mdBook supports a `test` command that will run all available tests in a book. At
the moment, only Rust tests are supported.
#### Disable tests on a code block
rustdoc doesn't test code blocks which contain the `ignore` attribute:
```rust,ignore
fn main() {}
```
rustdoc also doesn't test code blocks which specify a language other than Rust:
```markdown
**Foo**: _bar_
```
rustdoc *does* test code blocks which have no language specified:
```
This is going to cause an error!
```
#### Specify a directory
The `test` command can take a directory as an argument to use as the book's root
instead of the current working directory.
```bash
mdbook test path/to/book
```
#### `--library-path`
The `--library-path` (`-L`) option allows you to add directories to the library
search path used by `rustdoc` when it builds and tests the examples. Multiple
directories can be specified with multiple options (`-L foo -L bar`) or with a
comma-delimited list (`-L foo,bar`). The path should point to the Cargo
[build cache](https://doc.rust-lang.org/cargo/guide/build-cache.html) `deps` directory that
contains the build output of your project. For example, if your Rust project's book is in a directory
named `my-book`, the following command would include the crate's dependencies when running `test`:
```shell
mdbook test my-book -L target/debug/deps/
```
See the `rustdoc` command-line [documentation](https://doc.rust-lang.org/rustdoc/command-line-arguments.html#-l--library-path-where-to-look-for-dependencies)
for more information.
#### `--dest-dir`
The `--dest-dir` (`-d`) option allows you to change the output directory for the
book. Relative paths are interpreted relative to the book's root directory. If
not specified it will default to the value of the `build.build-dir` key in
`book.toml`, or to `./book`.
#### `--chapter`
The `--chapter` (`-c`) option allows you to test a specific chapter of the
book using the chapter name or the relative path to the chapter.
*`--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.
You will likely want to investigate caching options, as building mdBook can be somewhat slow.
[search]: guide/reading.md#search
## Running tests
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.
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.
Some may want to do this 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 <https://rust-lang.github.io/mdBook/>, and the `site-url` setting is configured like this:
```toml
# book.toml
[output.html]
site-url="/mdBook/"
```
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.
A *preprocessor* is simply a bit of code which gets run immediately after the
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}}`
- 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`
preprocessor) and then `mdbook` will try to invoke the `mdbook-foo` program as
part of the build process.
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.
The preprocessor should exit with a status code 0 if it supports the given renderer, or return a non-zero exit code if it does not.
If the preprocessor supports the renderer, then mdbook runs it a second time, passing JSON data into stdin.
The JSON consists of an array of `[context, book]` where `context` is the serialized object [`PreprocessorContext`] and `book` is a [`Book`] object containing the content of the book.
The preprocessor should return the JSON format of the [`Book`] object to stdout, with any modifications it wishes to perform.
The easiest way to get started is by creating your own implementation of the
`Preprocessor` trait (e.g. in `lib.rs`) and then creating a shell binary which
translates inputs to the correct `Preprocessor` method. For convenience, there
is [an example no-op preprocessor] in the `examples/` directory which can easily
be adapted for other preprocessors.
<details>
<summary>Example no-op preprocessor</summary>
```rust
// nop-preprocessors.rs
{{#include../../../examples/nop-preprocessor.rs}}
```
</details>
## Hints For Implementing A Preprocessor
By pulling in `mdbook` as a library, preprocessors can have access to the
existing infrastructure for dealing with books.
For example, a custom preprocessor could use the
[`CmdPreprocessor::parse_input()`] function to deserialize the JSON written to
`stdin`. Then each chapter of the `Book` can be mutated in-place via
[`Book::for_each_mut()`], and then written to `stdout` with the `serde_json`
crate.
Chapters can be accessed either directly (by recursively iterating over
chapters) or via the `Book::for_each_mut()` convenience method.
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] crate allowing you to
translate events back into markdown text.
The following code block shows how to remove all emphasis from markdown,
[Third Party Plugins]: https://github.com/rust-lang/mdBook/wiki/Third-party-plugins
[Preprocessors for Developers]: ../../for_developers/preprocessors.md
## Custom Preprocessor Configuration
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.example]
```
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 preprocessor 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.example]
renderers=["html"]# example preprocessor only runs with the HTML renderer
```
## 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
different program name or pass in command-line arguments, this behaviour can
be overridden by adding a `command` field.
```toml
[preprocessor.random]
command="python random.py"
```
## 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:
```toml
[preprocessor.linenos]
after=["links"]
```
or
```toml
[preprocessor.links]
before=["linenos"]
```
It would also be possible, though redundant, to specify both of the above in the same config file.
Preprocessors having the same priority specified through `before` and `after` are sorted by name.
Any infinite loops will be detected and produce an error.
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 <iclass="fa fa-print"></i>) that will print the book as a single page.
```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]`
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`.
### `[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
runnable=true# displays a run button for rust code
```
- **editable:** Allow editing the source code. Defaults to `false`.
- **copyable:** Display the copy button on code snippets. Defaults to `true`.
- **copy-js:** Copy JavaScript files for the editor to the output directory.
Defaults to `true`.
- **line-numbers:** Display line numbers on editable sections of code. Requires both `editable` and `copy-js` to be `true`. Defaults to `false`.
- **runnable:** Displays a run button for rust code snippets. Changing this to `false` will disable the run in playground feature globally. Defaults to `true`.
[Ace]: https://ace.c9.io/
### `[output.html.code]`
The `[output.html.code]` table provides options for controlling code blocks.
```toml
[output.html.code]
# A prefix string per language (one or more chars).
# Any line starting with whitespace+prefix is hidden.
hidelines={python="~"}
```
- **hidelines:** A table that defines how [hidden code lines](../mdbook.md#hiding-code-lines) work for each language.
The key is the language and the value is a string that will cause code lines starting with that prefix to be hidden.
### `[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`.
- **teaser-word-count:** The number of words used for a search result teaser.
Defaults to `30`.
- **use-boolean-and:** Define the logical link between multiple search words. If
true, all search words must appear in each result. Defaults to `false`.
- **boost-title:** Boost factor for the search result score if a search word
appears in the header. Defaults to `2`.
- **boost-hierarchy:** Boost factor for the search result score if a search word
appears in the hierarchy. The hierarchy contains all titles of the parent
documents and all parent headings. Defaults to `1`.
- **boost-paragraph:** Boost factor for the search result score if a search word
appears in the text. Defaults to `1`.
- **expand:** True if search should match longer results e.g. search `micro`
should match `microwave`. Defaults to `true`.
- **heading-split-level:** Search results will link to a section of the document
which contains the result. Documents are split into sections by headings this
level or less. Defaults to `3`. (`### This is a level 3 heading`)
- **copy-js:** Copy JavaScript files for the search implementation to the output
directory. Defaults to `true`.
#### `[output.html.search.chapter]`
The [`output.html.search.chapter`] table provides the ability to modify search settings per chapter or directory. Each key is the path to the chapter source file or directory, and the value is a table of settings to apply to that path. This will merge recursively, with more specific paths taking precedence.
```toml
[output.html.search.chapter]
# Disables search indexing for all chapters in the `appendix` directory.
"appendix"={enable=false}
# Enables search indexing for just this one appendix chapter.
"appendix/glossary.md"={enable=true}
```
- **enable:** Enables or disables search indexing for the given chapters. Defaults to `true`. This does not override the overall `output.html.search.enable` setting; that must be `true` for any search functionality to be enabled. Be cautious when disabling indexing for chapters because that can potentially lead to user confusion when they search for terms and expect them to be found. This should only be used in exceptional circumstances where keeping the chapter in the index will cause issues with the quality of the search results.
### `[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.
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
conjunction with `mdbook test` to see the Markdown that `mdbook` is passing
to `rustdoc`.
The Markdown renderer is included with `mdbook` but disabled by default.
Enable it by adding an empty table to your `book.toml` as follows:
```toml
[output.markdown]
```
There are no configuration options for the Markdown renderer at this time;
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.
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).
## Text and Paragraphs
Text is rendered relatively predictably:
```markdown
Here is a line of text.
This is a new line.
```
Will look like you might expect:
Here is a line of text.
This is a new line.
## Headings
Headings use the `#` marker and should be on a line by themselves. More `#` mean smaller headings:
```markdown
### A heading
Some text.
#### A smaller heading
More text.
```
### A heading
Some text.
#### A smaller heading
More text.
## Lists
Lists can be unordered or ordered. Ordered lists will order automatically:
```markdown
* milk
* eggs
* butter
1. carrots
1. celery
1. radishes
```
* milk
* eggs
* butter
1. carrots
1. celery
1. radishes
## Links
Linking to a URL or local file is easy:
```markdown
Use [mdBook](https://github.com/rust-lang/mdBook).
Read about [mdBook](mdbook.md).
A bare url: <https://www.rust-lang.org>.
```
Use [mdBook](https://github.com/rust-lang/mdBook).
Read about [mdBook](mdbook.md).
A bare url: <https://www.rust-lang.org>.
----
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
includes the Rust logo SVG image found in the `images` directory at the same level as this file:
```markdown

```
Produces the following HTML when built with mdBook:
Headings can have a custom HTML ID and classes. This lets you maintain the same ID even if you change the heading's text, it also lets you add multiple classes in the heading.
Example:
```md
# Example heading { #first .class1 .class2 }
```
This makes the level 1 heading with the content `Example heading`, ID `first`, and classes `class1` and `class2`. Note that the attributes should be space-separated.
More information can be found in the [heading attrs spec page](https://github.com/raphlinus/pulldown-cmark/blob/master/pulldown-cmark/specs/heading_attrs.txt).
There is a feature in mdBook that lets you hide code lines by prepending them with a specific prefix.
For the Rust language, you can prefix lines with `# ` (`#` followed by a space) to hide them [like you would with Rustdoc][rustdoc-hide].
This prefix can be escaped with `##` to prevent the hiding of a line that should begin with the literal string `# ` (see [Rustdoc's docs][rustdoc-hide] for more details)
When you tap or hover the mouse over the code block, there will be an eyeball icon (<iclass="fa fa-eye"></i>) which will toggle the visibility of the hidden lines.
By default, this only works for code examples that are annotated with `rust`.
However, you can define custom prefixes for other languages by adding a new line-hiding prefix in your `book.toml` with the language name and prefix character(s):
```toml
[output.html.code.hidelines]
python="~"
```
The prefix will hide any lines that begin with the given prefix. With the python prefix shown above, this:
```bash
~hidden()
nothidden():
~ hidden()
~hidden()
nothidden()
```
will render as
```python
~hidden()
nothidden():
~hidden()
~hidden()
nothidden()
```
This behavior can be overridden locally with a different prefix. This has the same effect as above:
~~~markdown
```python,hidelines=!!!
!!!hidden()
nothidden():
!!! hidden()
!!!hidden()
nothidden()
```
~~~
## Rust Playground
Rust language code blocks will automatically get a play button (<i class="fa fa-play"></i>) 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 for a code block, 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);
```
~~~
Or, if you wish to disable the play button for all code blocks in your book, you can write the config to the `book.toml` like this.
```toml
[output.html.playground]
runnable = false
```
## 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.
`index.hbs` is the handlebars template that is used to render the book. The
markdown files are processed to html and then injected in that template.
If you want to change the layout or style of your book, chances are that you
will have to modify this template a little bit. Here is what you need to know.
## Data
A lot of data is exposed to the handlebars template with the "context". In the
handlebars template you can access this information by using
```handlebars
{{name_of_property}}
```
Here is a list of the properties that are exposed:
- ***language*** Language of the book in the form `en`, as specified in `book.toml` (if not specified, defaults to `en`). To use in <code
class="language-html">\<html lang=\"{{ language }}\"></code> for example.
- ***title*** Title used for the current page. This is identical to `{{ chapter_title }} - {{ book_title }}` unless `book_title` is not set in which case it just defaults to the `chapter_title`.
- ***book_title*** Title of the book, as specified in `book.toml`
- ***chapter_title*** Title of the current chapter, as listed in `SUMMARY.md`
- ***path*** Relative path to the original markdown file from the source
directory
- ***content*** This is the rendered markdown.
- ***path_to_root*** This is a path containing exclusively `../`'s that points
to the root of the book from the current file. Since the original directory
structure is maintained, it is useful to prepend relative links with this
`path_to_root`.
- ***chapters*** Is an array of dictionaries of the form
```json
{"section": "1.2.1", "name": "name of this chapter", "path": "dir/markdown.md"}
```
containing all the chapters of the book. It is used for example to construct
the table of contents (sidebar).
## Handlebars Helpers
In addition to the properties you can access, there are some handlebars helpers
at your disposal.
### 1. toc
The toc helper is used like this
```handlebars
{{#toc}}{{/toc}}
```
and outputs something that looks like this, depending on the structure of your
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 `mdbook 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.
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 |
|------|-------------|
| <iclass="fa fa-bars"></i> | Opens and closes the chapter listing sidebar. |
| <iclass="fa fa-paint-brush"></i> | Opens a picker to choose a different color theme. |
| <iclass="fa fa-search"></i> | Opens a search bar for searching within the book. |
| <iclass="fa fa-print"></i> | Instructs the web browser to print the entire book. |
| <iclass="fa fa-github"></i> | Opens a link to the website that hosts the source code of the book. |
| <iclass="fa fa-edit"></i> | 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 (<iclass="fa fa-search"></i>) 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 |
|------|-------------|
| <iclass="fa fa-copy"></i> | Copies the code block into your local clipboard, to allow pasting into another application. |
| <iclass="fa fa-play"></i> | For Rust code examples, this will execute the sample code and display the compiler output just below the example (see [playground]). |
| <iclass="fa fa-eye"></i> | 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]). |
| <iclass="fa fa-history"></i> | For [editable code examples][editor], this will undo any changes you have made. |
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.