From 8fffb2a704c0124e314bab34db0dadea22fc3613 Mon Sep 17 00:00:00 2001 From: Benedikt Werner <1benediktwerner@gmail.com> Date: Thu, 7 Nov 2019 02:20:10 +0100 Subject: [PATCH] Hide lines in ignored code blocks --- src/renderer/html_handlebars/hbs_renderer.rs | 109 ++++++++++--------- 1 file changed, 60 insertions(+), 49 deletions(-) diff --git a/src/renderer/html_handlebars/hbs_renderer.rs b/src/renderer/html_handlebars/hbs_renderer.rs index 041acbf2..de7c5125 100644 --- a/src/renderer/html_handlebars/hbs_renderer.rs +++ b/src/renderer/html_handlebars/hbs_renderer.rs @@ -601,7 +601,6 @@ fn fix_code_blocks(html: &str) -> String { } fn add_playpen_pre(html: &str, playpen_config: &Playpen) -> String { - let boring_line_regex = Regex::new(r"^(\s*)#(.?)(.*)$").unwrap(); let regex = Regex::new(r##"((?s)]?class="([^"]+)".*?>(.*?))"##).unwrap(); regex .replace_all(html, |caps: &Captures<'_>| { @@ -609,57 +608,37 @@ fn add_playpen_pre(html: &str, playpen_config: &Playpen) -> String { let classes = &caps[2]; let code = &caps[3]; - if (classes.contains("language-rust") - && !classes.contains("ignore") - && !classes.contains("noplaypen")) - || classes.contains("mdbook-runnable") - { - // wrap the contents in an external pre block - format!( - "
{}
", - classes, - { - let content: Cow<'_, str> = if playpen_config.editable - && classes.contains("editable") - || text.contains("fn main") - || text.contains("quick_main!") + if classes.contains("language-rust") { + if (!classes.contains("ignore") && !classes.contains("noplaypen")) + || classes.contains("mdbook-runnable") + { + // wrap the contents in an external pre block + format!( + "
{}
", + classes, { - code.into() - } else { - // we need to inject our own main - let (attrs, code) = partition_source(code); - - format!( - "\n# #![allow(unused_variables)]\n{}#fn main() {{\n{}#}}", - attrs, code - ) - .into() - }; - let mut prev_line_hidden = false; - let mut result = String::with_capacity(content.len()); - for line in content.lines() { - if let Some(caps) = boring_line_regex.captures(line) { - if !prev_line_hidden && &caps[2] != "#" { - result += ""; - prev_line_hidden = true; - } - result += &caps[1]; - if &caps[2] != " " { - result += &caps[2]; - } - result += &caps[3]; + let content: Cow<'_, str> = if playpen_config.editable + && classes.contains("editable") + || text.contains("fn main") + || text.contains("quick_main!") + { + code.into() } else { - if prev_line_hidden { - result += ""; - prev_line_hidden = false; - } - result += line; - } - result += "\n"; + // we need to inject our own main + let (attrs, code) = partition_source(code); + + format!( + "\n# #![allow(unused_variables)]\n{}#fn main() {{\n{}#}}", + attrs, code + ) + .into() + }; + hide_lines(&content) } - result - } - ) + ) + } else { + format!("{}", classes, hide_lines(code)) + } } else { // not language-rust, so no-op text.to_owned() @@ -668,6 +647,36 @@ fn add_playpen_pre(html: &str, playpen_config: &Playpen) -> String { .into_owned() } +lazy_static! { + static ref BORING_LINES_REGEX: Regex = Regex::new(r"^(\s*)#(.?)(.*)$").unwrap(); +} + +fn hide_lines(content: &str) -> String { + let mut prev_line_hidden = false; + let mut result = String::with_capacity(content.len()); + for line in content.lines() { + if let Some(caps) = BORING_LINES_REGEX.captures(line) { + if !prev_line_hidden && &caps[2] != "#" { + result += ""; + prev_line_hidden = true; + } + result += &caps[1]; + if &caps[2] != " " { + result += &caps[2]; + } + result += &caps[3]; + } else { + if prev_line_hidden { + result += ""; + prev_line_hidden = false; + } + result += line; + } + result += "\n"; + } + result +} + fn partition_source(s: &str) -> (String, String) { let mut after_header = false; let mut before = String::new(); @@ -749,6 +758,8 @@ mod tests { "
let s = \"foo\n # bar\n\";\n
"), ("let s = \"foo\n # bar\n#\n\";", "
let s = \"foo\n bar\n\n\";\n
"), + ("let s = \"foo\n # bar\n#\n\";", + "let s = \"foo\n bar\n\n\";\n"), ]; for (src, should_be) in &inputs { let got = add_playpen_pre(