From e2b06cb6e7187714e4f24d5594093648cb51014c Mon Sep 17 00:00:00 2001 From: Vance Palacio Date: Sat, 26 Feb 2022 20:59:57 +0000 Subject: [PATCH] Add support for playground language choice We add a config option under the `Playground` type to allow setting which language should work with playground. Any language outside of rust doesn't get any preferential treatment in terms of code hiding, but atleast we get support at all. Looks like other languages being able to *use* the playground comes down to creating their own code in `book.js` after that --- src/config.rs | 6 + src/renderer/html_handlebars/hbs_renderer.rs | 110 +++++++++++-------- 2 files changed, 68 insertions(+), 48 deletions(-) diff --git a/src/config.rs b/src/config.rs index daeccbd0..318e0c86 100644 --- a/src/config.rs +++ b/src/config.rs @@ -630,6 +630,9 @@ pub struct Playground { pub copy_js: bool, /// Display line numbers on playground snippets. Default: `false`. pub line_numbers: bool, + /// Set's the language the playground will work with + /// TODO: Turn this into an array when there's support for multiple languages + pub language: String, } impl Default for Playground { @@ -639,6 +642,7 @@ impl Default for Playground { copyable: true, copy_js: true, line_numbers: false, + language: "rust".to_string(), } } } @@ -748,6 +752,7 @@ mod tests { [output.html.playground] editable = true editor = "ace" + language = "rust" [output.html.redirect] "index.html" = "overview.html" @@ -781,6 +786,7 @@ mod tests { copyable: true, copy_js: true, line_numbers: false, + language: "rust".to_string(), }; let html_should_be = HtmlConfig { curly_quotes: true, diff --git a/src/renderer/html_handlebars/hbs_renderer.rs b/src/renderer/html_handlebars/hbs_renderer.rs index 69dc3124..41bdac8e 100644 --- a/src/renderer/html_handlebars/hbs_renderer.rs +++ b/src/renderer/html_handlebars/hbs_renderer.rs @@ -824,64 +824,78 @@ fn add_playground_pre( let text = &caps[1]; let classes = &caps[2]; let code = &caps[3]; + let lang_class = format!("language-{}", playground_config.language); - if classes.contains("language-rust") { - if (!classes.contains("ignore") - && !classes.contains("noplayground") - && !classes.contains("noplaypen")) - || classes.contains("mdbook-runnable") - { - let contains_e2015 = classes.contains("edition2015"); - let contains_e2018 = classes.contains("edition2018"); - let contains_e2021 = classes.contains("edition2021"); - let edition_class = if contains_e2015 || contains_e2018 || contains_e2021 { - // the user forced edition, we should not overwrite it - "" - } else { - match edition { - Some(RustEdition::E2015) => " edition2015", - Some(RustEdition::E2018) => " edition2018", - Some(RustEdition::E2021) => " edition2021", - None => "", - } - }; - - // wrap the contents in an external pre block - format!( - "
{}
", - classes, - edition_class, - { - let content: Cow<'_, str> = if playground_config.editable - && classes.contains("editable") - || text.contains("fn main") - || text.contains("quick_main!") - { - code.into() - } else { - // we need to inject our own main - let (attrs, code) = partition_source(code); - - format!( - "\n# #![allow(unused)]\n{}#fn main() {{\n{}#}}", - attrs, code - ) - .into() - }; - hide_lines(&content) - } - ) + if classes.contains(lang_class.as_str()) { + if playground_config.language == "rust" { + add_playground_pre_rust(playground_config, edition, classes, text, code) } else { - format!("{}", classes, hide_lines(code)) + format!( + "
{}
", + classes, code + ) } } else { - // not language-rust, so no-op + // Language doens't match playground config, so no-op text.to_owned() } }) .into_owned() } +fn add_playground_pre_rust( + playground_config: &Playground, + edition: Option, + classes: &str, + text: &str, + code: &str, +) -> String { + if (!classes.contains("ignore") + && !classes.contains("noplayground") + && !classes.contains("noplaypen")) + || classes.contains("mdbook-runnable") + { + let contains_e2015 = classes.contains("edition2015"); + let contains_e2018 = classes.contains("edition2018"); + let contains_e2021 = classes.contains("edition2021"); + let edition_class = if contains_e2015 || contains_e2018 || contains_e2021 { + // the user forced edition, we should not overwrite it + "" + } else { + match edition { + Some(RustEdition::E2015) => " edition2015", + Some(RustEdition::E2018) => " edition2018", + Some(RustEdition::E2021) => " edition2021", + None => "", + } + }; + let all_classes = format!("{}{}", classes, edition_class); + + // wrap the contents in an external pre block + format!( + "
{}
", + all_classes, + { + let content: Cow<'_, str> = if playground_config.editable + && classes.contains("editable") + || text.contains("fn main") + || text.contains("quick_main!") + { + code.into() + } else { + // we need to inject our own main + let (attrs, code) = partition_source(code); + + format!("\n# #![allow(unused)]\n{}#fn main() {{\n{}#}}", attrs, code).into() + }; + hide_lines(&content) + } + ) + } else { + format!("{}", classes, hide_lines(code)) + } +} + lazy_static! { static ref BORING_LINES_REGEX: Regex = Regex::new(r"^(\s*)#(.?)(.*)$").unwrap(); }