diff options
author | Benedikt Werner <1benediktwerner@gmail.com> | 2019-11-07 02:20:10 +0100 |
---|---|---|
committer | Benedikt Werner <1benediktwerner@gmail.com> | 2019-11-07 02:20:10 +0100 |
commit | 8fffb2a704c0124e314bab34db0dadea22fc3613 (patch) | |
tree | f10c0d5e215ac2b3c56044613ea6b767b1740842 | |
parent | f5549f2267447d046add45c5a032d3b6ccc652f9 (diff) |
Hide lines in ignored code blocks
-rw-r--r-- | src/renderer/html_handlebars/hbs_renderer.rs | 109 |
1 files 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)<code[^>]?class="([^"]+)".*?>(.*?)</code>)"##).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!( - "<pre class=\"playpen\"><code class=\"{}\">{}</code></pre>", - 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!( + "<pre class=\"playpen\"><code class=\"{}\">{}</code></pre>", + 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 += "<span class=\"boring\">"; - 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 += "</span>"; - 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!("<code class=\"{}\">{}</code>", 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 += "<span class=\"boring\">"; + prev_line_hidden = true; + } + result += &caps[1]; + if &caps[2] != " " { + result += &caps[2]; + } + result += &caps[3]; + } else { + if prev_line_hidden { + result += "</span>"; + 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 { "<pre class=\"playpen\"><code class=\"language-rust editable\">let s = \"foo\n # bar\n\";\n</code></pre>"), ("<code class=\"language-rust editable\">let s = \"foo\n # bar\n#\n\";</code>", "<pre class=\"playpen\"><code class=\"language-rust editable\">let s = \"foo\n<span class=\"boring\"> bar\n\n</span>\";\n</code></pre>"), + ("<code class=\"language-rust ignore\">let s = \"foo\n # bar\n#\n\";</code>", + "<code class=\"language-rust ignore\">let s = \"foo\n<span class=\"boring\"> bar\n\n</span>\";\n</code>"), ]; for (src, should_be) in &inputs { let got = add_playpen_pre( |