", before = before, classes = classes, after = after)
})
.into_owned()
}
fn add_playpen_pre(html: String) -> String {
let regex = Regex::new(r##"((?s)]?class="([^"]+)".*?>(.*?)
)"##).unwrap();
regex
.replace_all(&html, |caps: &Captures| {
let text = &caps[1];
let classes = &caps[2];
let code = &caps[3];
if classes.contains("language-rust") && !classes.contains("ignore") {
// wrap the contents in an external pre block
if text.contains("fn main") || text.contains("quick_main!") {
format!("{}
", text)
} else {
// we need to inject our own main
let (attrs, code) = partition_source(code);
format!(
"# #![allow(unused_variables)]
{}#fn main() {{
\
{}
#}}
",
classes,
attrs,
code
)
}
} else {
// not language-rust, so no-op
format!("{}", text)
}
})
.into_owned()
}
fn partition_source(s: &str) -> (String, String) {
let mut after_header = false;
let mut before = String::new();
let mut after = String::new();
for line in s.lines() {
let trimline = line.trim();
let header = trimline.chars().all(|c| c.is_whitespace()) || trimline.starts_with("#![");
if !header || after_header {
after_header = true;
after.push_str(line);
after.push_str("\n");
} else {
before.push_str(line);
before.push_str("\n");
}
}
(before, after)
}
struct RenderItemContext<'a> {
handlebars: &'a Handlebars,
book: &'a MDBook,
destination: PathBuf,
data: serde_json::Map,
is_index: bool,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn original_build_header_links() {
let inputs = vec![
("blah blah Foo
", r#"blah blah "#),
("Foo
", r#""#),
("Foo^bar
", r#""#),
("", r#""#),
("Hï
", r#""#),
("Foo
Foo
", r#""#),
];
for (src, should_be) in inputs {
let got = build_header_links(src.to_string(), "bar.rs");
assert_eq!(got, should_be);
}
}
}