summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenedikt Werner <1benediktwerner@gmail.com>2019-11-07 02:20:10 +0100
committerBenedikt Werner <1benediktwerner@gmail.com>2019-11-07 02:20:10 +0100
commit8fffb2a704c0124e314bab34db0dadea22fc3613 (patch)
treef10c0d5e215ac2b3c56044613ea6b767b1740842
parentf5549f2267447d046add45c5a032d3b6ccc652f9 (diff)
Hide lines in ignored code blocks
-rw-r--r--src/renderer/html_handlebars/hbs_renderer.rs109
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(