diff --git a/guide/src/format/configuration/renderers.md b/guide/src/format/configuration/renderers.md index 1aa1eef9..f1d5ee15 100644 --- a/guide/src/format/configuration/renderers.md +++ b/guide/src/format/configuration/renderers.md @@ -207,6 +207,7 @@ 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`. @@ -214,6 +215,7 @@ line-numbers = false # displays line numbers for editable code - **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/ diff --git a/guide/src/format/mdbook.md b/guide/src/format/mdbook.md index e4c76f1b..62e89843 100644 --- a/guide/src/format/mdbook.md +++ b/guide/src/format/mdbook.md @@ -41,7 +41,7 @@ println!("Hello, World!"); If there is no `main` function, then the code is automatically wrapped inside one. -If you wish to disable the play button, you can include the `noplayground` option on the code block like this: +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 @@ -51,6 +51,13 @@ 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: diff --git a/src/config.rs b/src/config.rs index daeccbd0..6ed1e895 100644 --- a/src/config.rs +++ b/src/config.rs @@ -630,6 +630,8 @@ pub struct Playground { pub copy_js: bool, /// Display line numbers on playground snippets. Default: `false`. pub line_numbers: bool, + /// Display the run button. Default: `true` + pub runnable: bool, } impl Default for Playground { @@ -639,6 +641,7 @@ impl Default for Playground { copyable: true, copy_js: true, line_numbers: false, + runnable: true, } } } @@ -781,6 +784,7 @@ mod tests { copyable: true, copy_js: true, line_numbers: false, + runnable: true, }; let html_should_be = HtmlConfig { curly_quotes: true, @@ -811,6 +815,22 @@ mod tests { assert_eq!(got.html_config().unwrap(), html_should_be); } + #[test] + fn disable_runnable() { + let src = r#" + [book] + title = "Some Book" + description = "book book book" + authors = ["Shogo Takata"] + + [output.html.playground] + runnable = false + "#; + + let got = Config::from_str(src).unwrap(); + assert_eq!(got.html_config().unwrap().playground.runnable, false); + } + #[test] fn edition_2015() { let src = r#" diff --git a/src/renderer/html_handlebars/hbs_renderer.rs b/src/renderer/html_handlebars/hbs_renderer.rs index 69dc3124..045d536e 100644 --- a/src/renderer/html_handlebars/hbs_renderer.rs +++ b/src/renderer/html_handlebars/hbs_renderer.rs @@ -828,7 +828,8 @@ fn add_playground_pre( if classes.contains("language-rust") { if (!classes.contains("ignore") && !classes.contains("noplayground") - && !classes.contains("noplaypen")) + && !classes.contains("noplaypen") + && playground_config.runnable) || classes.contains("mdbook-runnable") { let contains_e2015 = classes.contains("edition2015"); diff --git a/tests/rendered_output.rs b/tests/rendered_output.rs index 5ec6e64b..cd511ccf 100644 --- a/tests/rendered_output.rs +++ b/tests/rendered_output.rs @@ -17,6 +17,7 @@ use std::ffi::OsStr; use std::fs; use std::io::Write; use std::path::{Component, Path, PathBuf}; +use std::str::FromStr; use tempfile::Builder as TempFileBuilder; use walkdir::{DirEntry, WalkDir}; @@ -150,6 +151,25 @@ fn rendered_code_has_playground_stuff() { assert_contains_strings(book_js, &[".playground"]); } +#[test] +fn rendered_code_does_not_have_playground_stuff_in_html_when_disabled_in_config() { + let temp = DummyBook::new().build().unwrap(); + let config = Config::from_str( + " + [output.html.playground] + runnable = false + ", + ) + .unwrap(); + let md = MDBook::load_with_config(temp.path(), config).unwrap(); + md.build().unwrap(); + + let nested = temp.path().join("book/first/nested.html"); + let playground_class = vec![r#"class="playground""#]; + + assert_doesnt_contain_strings(nested, &playground_class); +} + #[test] fn anchors_include_text_between_but_not_anchor_comments() { let temp = DummyBook::new().build().unwrap();