mirror of
https://github.com/rust-lang/mdBook.git
synced 2025-12-28 10:16:33 -05:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f66df09324 | ||
|
|
648c9ae772 | ||
|
|
eaa6914205 | ||
|
|
a76557a678 | ||
|
|
01836ba5d4 | ||
|
|
46ce077de6 | ||
|
|
f7c9180d80 | ||
|
|
4c951d530d | ||
|
|
b77942d3c8 | ||
|
|
d0deee90b0 | ||
|
|
e6ac8ecdd9 | ||
|
|
d1f5ecc103 | ||
|
|
e0b247e9d6 | ||
|
|
db8a2821ea | ||
|
|
39d7130019 | ||
|
|
2eccb457d2 | ||
|
|
d1682d27fb | ||
|
|
b349e8abc9 | ||
|
|
e225586953 |
6
.github/workflows/deploy.yml
vendored
6
.github/workflows/deploy.yml
vendored
@@ -31,12 +31,12 @@ jobs:
|
||||
- name: Install Rust (rustup)
|
||||
run: rustup update stable --no-self-update && rustup default stable
|
||||
- name: Build book
|
||||
run: cargo run -- build book-example
|
||||
run: cargo run -- build guide
|
||||
- name: Deploy to GitHub
|
||||
env:
|
||||
GITHUB_DEPLOY_KEY: ${{ secrets.GITHUB_DEPLOY_KEY }}
|
||||
run: |
|
||||
touch book-example/book/.nojekyll
|
||||
touch guide/book/.nojekyll
|
||||
curl -LsSf https://raw.githubusercontent.com/rust-lang/simpleinfra/master/setup-deploy-keys/src/deploy.rs | rustc - -o /tmp/deploy
|
||||
cd book-example/book
|
||||
cd guide/book
|
||||
/tmp/deploy
|
||||
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -4,10 +4,14 @@ target
|
||||
.DS_Store
|
||||
|
||||
book-test
|
||||
book-example/book
|
||||
guide/book
|
||||
|
||||
.vscode
|
||||
tests/dummy_book/book/
|
||||
|
||||
# Ignore Jetbrains specific files.
|
||||
.idea/
|
||||
|
||||
# Ignore Vim temporary and swap files.
|
||||
*.sw?
|
||||
*~
|
||||
|
||||
17
CHANGELOG.md
17
CHANGELOG.md
@@ -1,7 +1,22 @@
|
||||
# Changelog
|
||||
|
||||
## mdBook 0.4.4
|
||||
[4df9ec9...01836ba](https://github.com/rust-lang/mdBook/compare/4df9ec9...01836ba)
|
||||
|
||||
### Added
|
||||
- Added the `output.html.print.enable` configuration value to disable the
|
||||
"print" page.
|
||||
[#1169](https://github.com/rust-lang/mdBook/pull/1169)
|
||||
- Added a list of supported languages for syntax-highlighting to the
|
||||
documentation.
|
||||
[#1345](https://github.com/rust-lang/mdBook/pull/1345)
|
||||
|
||||
### Fixed
|
||||
- Now supports symbolic links for files in the `src` directory.
|
||||
[#1323](https://github.com/rust-lang/mdBook/pull/1323)
|
||||
|
||||
## mdBook 0.4.3
|
||||
[9278b83...9278b83](https://github.com/rust-lang/mdBook/compare/9278b83...4df9ec9)
|
||||
[9278b83...4df9ec9](https://github.com/rust-lang/mdBook/compare/9278b83...4df9ec9)
|
||||
|
||||
### Added
|
||||
- Added `output.html.cname` option to emit a `CNAME` file which is used by
|
||||
|
||||
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -723,7 +723,7 @@ checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
|
||||
|
||||
[[package]]
|
||||
name = "mdbook"
|
||||
version = "0.4.3"
|
||||
version = "0.4.5"
|
||||
dependencies = [
|
||||
"ammonia",
|
||||
"anyhow",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "mdbook"
|
||||
version = "0.4.3"
|
||||
version = "0.4.5"
|
||||
authors = [
|
||||
"Mathieu David <mathieudavid@mathieudavid.org>",
|
||||
"Michael-F-Bryan <michaelfbryan@gmail.com>",
|
||||
@@ -8,7 +8,7 @@ authors = [
|
||||
]
|
||||
documentation = "http://rust-lang.github.io/mdBook/index.html"
|
||||
edition = "2018"
|
||||
exclude = ["/book-example/*"]
|
||||
exclude = ["/guide/*"]
|
||||
keywords = ["book", "gitbook", "rustbook", "markdown"]
|
||||
license = "MPL-2.0"
|
||||
readme = "README.md"
|
||||
|
||||
@@ -85,7 +85,7 @@ There are multiple ways to install mdBook.
|
||||
|
||||
## Usage
|
||||
|
||||
mdBook will primarily be used as a command line tool, even though it exposes
|
||||
mdBook is primarily used as a command line tool, even though it exposes
|
||||
all its functionality as a Rust crate for integration in other projects.
|
||||
|
||||
Here are the main commands you will want to run. For a more exhaustive
|
||||
|
||||
@@ -21,4 +21,4 @@ case $1 in
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "##[add-path]$PWD/hub/bin"
|
||||
echo "$PWD/hub/bin" >> $GITHUB_PATH
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
- [Syntax highlighting](format/theme/syntax-highlighting.md)
|
||||
- [Editor](format/theme/editor.md)
|
||||
- [MathJax Support](format/mathjax.md)
|
||||
- [mdBook specific features](format/mdbook.md)
|
||||
- [mdBook-specific features](format/mdbook.md)
|
||||
- [Continuous Integration](continuous-integration.md)
|
||||
- [For Developers](for_developers/README.md)
|
||||
- [Preprocessors](for_developers/preprocessors.md)
|
||||
@@ -187,6 +187,9 @@ The following configuration options are available:
|
||||
- **additional-js:** If you need to add some behaviour to your book without
|
||||
removing the current behaviour, you can specify a set of JavaScript files that
|
||||
will be loaded alongside the default one.
|
||||
- **print:** A subtable for configuration print settings. mdBook by default adds
|
||||
support for printing out the book as a single page. This is accessed using the
|
||||
print icon on the top right of the book.
|
||||
- **no-section-label:** mdBook by defaults adds section label in table of
|
||||
contents column. For example, "1.", "2.1". Set this option to true to disable
|
||||
those labels. Defaults to `false`.
|
||||
@@ -217,6 +220,11 @@ The following configuration options are available:
|
||||
|
||||
[custom domain]: https://docs.github.com/en/github/working-with-github-pages/managing-a-custom-domain-for-your-github-pages-site
|
||||
|
||||
Available configuration options for the `[output.html.print]` table:
|
||||
|
||||
- **enable:** Enable print support. When `false`, all print support will not be
|
||||
rendered. Defaults to `true`.
|
||||
|
||||
Available configuration options for the `[output.html.fold]` table:
|
||||
|
||||
- **enable:** Enable section-folding. When off, all folds are open.
|
||||
@@ -282,6 +290,9 @@ site-url = "/example-book/"
|
||||
cname = "myproject.rs"
|
||||
input-404 = "not-found.md"
|
||||
|
||||
[output.html.print]
|
||||
enable = true
|
||||
|
||||
[output.html.fold]
|
||||
enable = false
|
||||
level = 0
|
||||
@@ -1,9 +1,9 @@
|
||||
# mdBook-specific markdown
|
||||
# mdBook-specific features
|
||||
|
||||
## Hiding code lines
|
||||
|
||||
There is a feature in mdBook that lets you hide code lines by prepending them
|
||||
with a `#` [in the same way that Rustdoc does][rustdoc-hide].
|
||||
with a `#` [like you would with Rustdoc][rustdoc-hide].
|
||||
|
||||
[rustdoc-hide]: https://doc.rust-lang.org/stable/rustdoc/documentation-tests.html#hiding-portions-of-the-example
|
||||
|
||||
@@ -37,7 +37,7 @@ With the following syntax, you can include files into your book:
|
||||
|
||||
The path to the file has to be relative from the current source file.
|
||||
|
||||
mdBook will interpret included files as markdown. Since the include command
|
||||
mdBook will interpret included files as Markdown. Since the include command
|
||||
is usually used for inserting code snippets and examples, you will often
|
||||
wrap the command with ```` ``` ```` to display the file contents without
|
||||
interpretting them.
|
||||
@@ -1,16 +1,67 @@
|
||||
# Syntax Highlighting
|
||||
|
||||
For syntax highlighting I use [Highlight.js](https://highlightjs.org) with a
|
||||
custom theme.
|
||||
mdBook uses [Highlight.js](https://highlightjs.org) with a custom theme
|
||||
for syntax highlighting.
|
||||
|
||||
Automatic language detection has been turned off, so you will probably want to
|
||||
specify the programming language you use like this
|
||||
specify the programming language you use like this:
|
||||
|
||||
<pre><code class="language-markdown">```rust
|
||||
~~~markdown
|
||||
```rust
|
||||
fn main() {
|
||||
// Some code
|
||||
}
|
||||
```</code></pre>
|
||||
```
|
||||
~~~
|
||||
|
||||
## Supported languages
|
||||
|
||||
These languages are supported by default, but you can add more by supplying
|
||||
your own `highlight.js` file:
|
||||
|
||||
- apache
|
||||
- armasm
|
||||
- bash
|
||||
- c
|
||||
- coffeescript
|
||||
- cpp
|
||||
- csharp
|
||||
- css
|
||||
- d
|
||||
- diff
|
||||
- go
|
||||
- handlebars
|
||||
- haskell
|
||||
- http
|
||||
- ini
|
||||
- java
|
||||
- javascript
|
||||
- json
|
||||
- julia
|
||||
- kotlin
|
||||
- less
|
||||
- lua
|
||||
- makefile
|
||||
- markdown
|
||||
- nginx
|
||||
- objectivec
|
||||
- perl
|
||||
- php
|
||||
- plaintext
|
||||
- properties
|
||||
- python
|
||||
- r
|
||||
- ruby
|
||||
- rust
|
||||
- scala
|
||||
- scss
|
||||
- shell
|
||||
- sql
|
||||
- swift
|
||||
- typescript
|
||||
- x86asm
|
||||
- xml
|
||||
- yaml
|
||||
|
||||
## Custom theme
|
||||
Like the rest of the theme, the files used for syntax highlighting can be
|
||||
@@ -109,10 +109,9 @@ impl BookBuilder {
|
||||
fn copy_across_theme(&self) -> Result<()> {
|
||||
debug!("Copying theme");
|
||||
|
||||
let themedir = self
|
||||
.config
|
||||
.html_config()
|
||||
.and_then(|html| html.theme)
|
||||
let html_config = self.config.html_config().unwrap_or_default();
|
||||
let themedir = html_config
|
||||
.theme
|
||||
.unwrap_or_else(|| self.config.book.src.join("theme"));
|
||||
let themedir = self.root.join(themedir);
|
||||
|
||||
@@ -136,8 +135,10 @@ impl BookBuilder {
|
||||
let mut chrome_css = File::create(cssdir.join("chrome.css"))?;
|
||||
chrome_css.write_all(theme::CHROME_CSS)?;
|
||||
|
||||
let mut print_css = File::create(cssdir.join("print.css"))?;
|
||||
print_css.write_all(theme::PRINT_CSS)?;
|
||||
if html_config.print.enable {
|
||||
let mut print_css = File::create(cssdir.join("print.css"))?;
|
||||
print_css.write_all(theme::PRINT_CSS)?;
|
||||
}
|
||||
|
||||
let mut variables_css = File::create(cssdir.join("variables.css"))?;
|
||||
variables_css.write_all(theme::VARIABLES_CSS)?;
|
||||
|
||||
@@ -495,6 +495,8 @@ pub struct HtmlConfig {
|
||||
/// Playground settings.
|
||||
#[serde(alias = "playpen")]
|
||||
pub playground: Playground,
|
||||
/// Print settings.
|
||||
pub print: Print,
|
||||
/// Don't render section labels.
|
||||
pub no_section_label: bool,
|
||||
/// Search settings. If `None`, the default will be used.
|
||||
@@ -542,6 +544,7 @@ impl Default for HtmlConfig {
|
||||
additional_js: Vec::new(),
|
||||
fold: Fold::default(),
|
||||
playground: Playground::default(),
|
||||
print: Print::default(),
|
||||
no_section_label: false,
|
||||
search: None,
|
||||
git_repository_url: None,
|
||||
@@ -566,6 +569,20 @@ impl HtmlConfig {
|
||||
}
|
||||
}
|
||||
|
||||
/// Configuration for how to render the print icon, print.html, and print.css.
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct Print {
|
||||
/// Whether print support is enabled.
|
||||
pub enable: bool,
|
||||
}
|
||||
|
||||
impl Default for Print {
|
||||
fn default() -> Self {
|
||||
Self { enable: true }
|
||||
}
|
||||
}
|
||||
|
||||
/// Configuration for how to fold chapters of sidebar.
|
||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(default, rename_all = "kebab-case")]
|
||||
|
||||
@@ -171,15 +171,15 @@ mod tests {
|
||||
use crate::MDBook;
|
||||
use std::path::Path;
|
||||
|
||||
fn book_example() -> MDBook {
|
||||
let example = Path::new(env!("CARGO_MANIFEST_DIR")).join("book-example");
|
||||
fn guide() -> MDBook {
|
||||
let example = Path::new(env!("CARGO_MANIFEST_DIR")).join("guide");
|
||||
MDBook::load(example).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn round_trip_write_and_parse_input() {
|
||||
let cmd = CmdPreprocessor::new("test".to_string(), "test".to_string());
|
||||
let md = book_example();
|
||||
let md = guide();
|
||||
let ctx = PreprocessorContext::new(
|
||||
md.root.clone(),
|
||||
md.config.clone(),
|
||||
|
||||
@@ -194,7 +194,9 @@ impl HtmlHandlebars {
|
||||
write_file(destination, "book.js", &theme.js)?;
|
||||
write_file(destination, "css/general.css", &theme.general_css)?;
|
||||
write_file(destination, "css/chrome.css", &theme.chrome_css)?;
|
||||
write_file(destination, "css/print.css", &theme.print_css)?;
|
||||
if html_config.print.enable {
|
||||
write_file(destination, "css/print.css", &theme.print_css)?;
|
||||
}
|
||||
write_file(destination, "css/variables.css", &theme.variables_css)?;
|
||||
if let Some(contents) = &theme.favicon_png {
|
||||
write_file(destination, "favicon.png", &contents)?;
|
||||
@@ -516,14 +518,16 @@ impl Renderer for HtmlHandlebars {
|
||||
}
|
||||
|
||||
// Render the handlebars template with the data
|
||||
debug!("Render template");
|
||||
let rendered = handlebars.render("index", &data)?;
|
||||
if html_config.print.enable {
|
||||
debug!("Render template");
|
||||
let rendered = handlebars.render("index", &data)?;
|
||||
|
||||
let rendered =
|
||||
self.post_process(rendered, &html_config.playground, ctx.config.rust.edition);
|
||||
let rendered =
|
||||
self.post_process(rendered, &html_config.playground, ctx.config.rust.edition);
|
||||
|
||||
utils::fs::write_file(&destination, "print.html", rendered.as_bytes())?;
|
||||
debug!("Creating print.html ✓");
|
||||
utils::fs::write_file(&destination, "print.html", rendered.as_bytes())?;
|
||||
debug!("Creating print.html ✓");
|
||||
}
|
||||
|
||||
debug!("Copy static files");
|
||||
self.copy_static_files(&destination, &theme, &html_config)
|
||||
@@ -644,8 +648,9 @@ fn make_data(
|
||||
data.insert("playground_copyable".to_owned(), json!(true));
|
||||
}
|
||||
|
||||
data.insert("fold_enable".to_owned(), json!((html_config.fold.enable)));
|
||||
data.insert("fold_level".to_owned(), json!((html_config.fold.level)));
|
||||
data.insert("print_enable".to_owned(), json!(html_config.print.enable));
|
||||
data.insert("fold_enable".to_owned(), json!(html_config.fold.enable));
|
||||
data.insert("fold_level".to_owned(), json!(html_config.fold.level));
|
||||
|
||||
let search = html_config.search.clone();
|
||||
if cfg!(feature = "search") {
|
||||
|
||||
@@ -29,7 +29,9 @@
|
||||
<link rel="stylesheet" href="{{ path_to_root }}css/variables.css">
|
||||
<link rel="stylesheet" href="{{ path_to_root }}css/general.css">
|
||||
<link rel="stylesheet" href="{{ path_to_root }}css/chrome.css">
|
||||
{{#if print_enable}}
|
||||
<link rel="stylesheet" href="{{ path_to_root }}css/print.css" media="print">
|
||||
{{/if}}
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="{{ path_to_root }}FontAwesome/css/font-awesome.css">
|
||||
@@ -136,9 +138,11 @@
|
||||
<h1 class="menu-title">{{ book_title }}</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
{{#if print_enable}}
|
||||
<a href="{{ path_to_root }}print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
{{/if}}
|
||||
{{#if git_repository_url}}
|
||||
<a href="{{git_repository_url}}" title="Git repository" aria-label="Git repository">
|
||||
<i id="git-repository-button" class="fa {{git_repository_icon}}"></i>
|
||||
|
||||
@@ -145,6 +145,11 @@ window.search = window.search || {};
|
||||
url.push("");
|
||||
}
|
||||
|
||||
// encodeURIComponent escapes all chars that could allow an XSS except
|
||||
// for '. Due to that we also manually replace ' with its url-encoded
|
||||
// representation (%27).
|
||||
var searchterms = encodeURIComponent(searchterms.join(" ")).replace(/\'/g, "%27");
|
||||
|
||||
return '<a href="' + path_to_root + url[0] + '?' + URL_MARK_PARAM + '=' + searchterms + '#' + url[1]
|
||||
+ '" aria-details="teaser_' + teaser_count + '">' + result.doc.breadcrumbs + '</a>'
|
||||
+ '<span class="teaser" id="teaser_' + teaser_count + '" aria-label="Search Result Teaser">'
|
||||
|
||||
@@ -110,7 +110,7 @@ pub fn copy_files_except_ext(
|
||||
|
||||
for entry in fs::read_dir(from)? {
|
||||
let entry = entry?;
|
||||
let metadata = entry.metadata()?;
|
||||
let metadata = entry.path().metadata()?;
|
||||
|
||||
// If the entry is a dir and the recursive option is enabled, call itself
|
||||
if metadata.is_dir() && recursive {
|
||||
@@ -187,7 +187,17 @@ pub fn get_404_output_file(input_404: &Option<String>) -> String {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::copy_files_except_ext;
|
||||
use std::fs;
|
||||
use std::{fs, io::Result, path::Path};
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> Result<()> {
|
||||
std::os::windows::fs::symlink_file(src, dst)
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> Result<()> {
|
||||
std::os::unix::fs::symlink(src, dst)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn copy_files_except_ext_test() {
|
||||
@@ -218,6 +228,12 @@ mod tests {
|
||||
if let Err(err) = fs::File::create(&tmp.path().join("sub_dir_exists/file.txt")) {
|
||||
panic!("Could not create sub_dir_exists/file.txt: {}", err);
|
||||
}
|
||||
if let Err(err) = symlink(
|
||||
&tmp.path().join("file.png"),
|
||||
&tmp.path().join("symlink.png"),
|
||||
) {
|
||||
panic!("Could not symlink file.png: {}", err);
|
||||
}
|
||||
|
||||
// Create output dir
|
||||
if let Err(err) = fs::create_dir(&tmp.path().join("output")) {
|
||||
@@ -249,5 +265,8 @@ mod tests {
|
||||
if !(&tmp.path().join("output/sub_dir_exists/file.txt")).exists() {
|
||||
panic!("output/sub_dir/file.png should exist")
|
||||
}
|
||||
if !(&tmp.path().join("output/symlink.png")).exists() {
|
||||
panic!("output/symlink.png should exist")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,11 +135,11 @@ fn recursive_copy<A: AsRef<Path>, B: AsRef<Path>>(from: A, to: B) -> Result<()>
|
||||
}
|
||||
|
||||
pub fn new_copy_of_example_book() -> Result<TempDir> {
|
||||
let temp = TempFileBuilder::new().prefix("book-example").tempdir()?;
|
||||
let temp = TempFileBuilder::new().prefix("guide").tempdir()?;
|
||||
|
||||
let book_example = Path::new(env!("CARGO_MANIFEST_DIR")).join("book-example");
|
||||
let guide = Path::new(env!("CARGO_MANIFEST_DIR")).join("guide");
|
||||
|
||||
recursive_copy(book_example, temp.path())?;
|
||||
recursive_copy(guide, temp.path())?;
|
||||
|
||||
Ok(temp)
|
||||
}
|
||||
|
||||
@@ -345,7 +345,7 @@ fn create_missing_file_with_config() {
|
||||
}
|
||||
|
||||
/// This makes sure you can include a Rust file with `{{#playground example.rs}}`.
|
||||
/// Specification is in `book-example/src/format/rust.md`
|
||||
/// Specification is in `guide/src/format/rust.md`
|
||||
#[test]
|
||||
fn able_to_include_playground_files_in_chapters() {
|
||||
let temp = DummyBook::new().build().unwrap();
|
||||
|
||||
Reference in New Issue
Block a user