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(