Skip to content

Commit abc29e2

Browse files
committed
Rebase onto current main branch
1 parent 9235cbf commit abc29e2

File tree

5 files changed

+168
-293
lines changed

5 files changed

+168
-293
lines changed

src/cmd/gen_syntax_cache.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,22 @@ use syntect::parsing::{SyntaxSet, SyntaxSetBuilder};
1212
pub fn make_subcommand<'help>() -> App<'help> {
1313
App::new("gen-syntax-cache")
1414
.about("Generate syntaxes.bin and css/syntax")
15-
.arg(arg!(-d --"dest-dir" <dir>
16-
"Output directory for the syntax cache{n}\
17-
Relative paths are interpreted relative to the current working directory.{n}\
15+
.arg(
16+
arg!(-d --"dest-dir" <dir>
17+
"Output directory for the syntax cache{n}\
18+
Relative paths are interpreted relative to the current working directory.{n}\
1819
If omitted, mdBook uses `.`.
1920
This command outputs files [dir]/syntaxes.bin and [dir]/css/syntax/*.css"
20-
).required(false))
21-
.arg(arg!(--syntaxes-only "Only generate syntaxes.bin, not css/syntax/*.css."))
22-
.arg(arg!(--no-default-syntaxes
21+
)
22+
.required(false),
23+
)
24+
.arg(arg!(--"syntaxes-only" "Only generate syntaxes.bin, not css/syntax/*.css."))
25+
.arg(arg!(--"no-default-syntaxes"
2326
"Don't include Sublime Text's default open source syntaxes{n}\
2427
If included, only syntaxes from [dir] are used."
2528
))
26-
.arg(arg!(--themes-only "Only generate themes, not syntaxes.bin."))
27-
.arg(arg!(--no-default-themes
29+
.arg(arg!(--"themes-only" "Only generate themes, not syntaxes.bin."))
30+
.arg(arg!(--"no-default-themes"
2831
"Don't include mdbook's default light, dark, and ayu themes{n}\
2932
If included, only themes from [dir] are used.'"
3033
))

src/renderer/html_handlebars/hbs_renderer.rs

Lines changed: 2 additions & 273 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
use crate::book::{Book, BookItem};
2-
use crate::config::{BookConfig, Config, HtmlConfig, Playground, RustEdition};
2+
use crate::config::{BookConfig, Config, HtmlConfig, RustEdition};
33
use crate::errors::*;
44
use crate::renderer::html_handlebars::helpers;
55
use crate::renderer::{RenderContext, Renderer};
66
use crate::theme::{self, playground_editor, Theme};
77
use crate::utils;
88

9-
use std::borrow::Cow;
109
use std::cell::RefCell;
1110
use std::collections::BTreeMap;
1211
use std::collections::HashMap;
@@ -74,7 +73,7 @@ impl HtmlHandlebars {
7473
&ctx.html_config.playground,
7574
ctx.edition,
7675
);
77-
if !ctx.is_index && ctx.html_config.print.page_break {
76+
if !ctx.is_index && ctx.html_config.print.page_break {
7877
// Add page break between chapters
7978
// See https://developer.mozilla.org/en-US/docs/Web/CSS/break-before and https://developer.mozilla.org/en-US/docs/Web/CSS/page-break-before
8079
// Add both two CSS properties because of the compatibility issue
@@ -829,173 +828,6 @@ fn insert_link_into_header(
829828
)
830829
}
831830

832-
// The rust book uses annotations for rustdoc to test code snippets,
833-
// like the following:
834-
// ```rust,should_panic
835-
// fn main() {
836-
// // Code here
837-
// }
838-
// ```
839-
// This function replaces all commas by spaces in the code block classes
840-
fn fix_code_blocks(html: &str) -> String {
841-
lazy_static! {
842-
static ref FIX_CODE_BLOCKS: Regex =
843-
Regex::new(r##"<code([^>]+)class="([^"]+)"([^>]*)>"##).unwrap();
844-
}
845-
846-
FIX_CODE_BLOCKS
847-
.replace_all(html, |caps: &Captures<'_>| {
848-
let before = &caps[1];
849-
let classes = &caps[2].replace(',', " ");
850-
let after = &caps[3];
851-
852-
format!(
853-
r#"<code{before}class="{classes}"{after}>"#,
854-
before = before,
855-
classes = classes,
856-
after = after
857-
)
858-
})
859-
.into_owned()
860-
}
861-
862-
fn add_playground_pre(
863-
html: &str,
864-
playground_config: &Playground,
865-
edition: Option<RustEdition>,
866-
) -> String {
867-
lazy_static! {
868-
static ref ADD_PLAYGROUND_PRE: Regex =
869-
Regex::new(r##"((?s)<code[^>]?class="([^"]+)".*?>(.*?)</code>)"##).unwrap();
870-
}
871-
ADD_PLAYGROUND_PRE
872-
.replace_all(html, |caps: &Captures<'_>| {
873-
let text = &caps[1];
874-
let classes = &caps[2];
875-
let code = &caps[3];
876-
877-
if classes.contains("language-rust") {
878-
if (!classes.contains("ignore")
879-
&& !classes.contains("noplayground")
880-
&& !classes.contains("noplaypen")
881-
&& playground_config.runnable)
882-
|| classes.contains("mdbook-runnable")
883-
{
884-
let contains_e2015 = classes.contains("edition2015");
885-
let contains_e2018 = classes.contains("edition2018");
886-
let contains_e2021 = classes.contains("edition2021");
887-
let edition_class = if contains_e2015 || contains_e2018 || contains_e2021 {
888-
// the user forced edition, we should not overwrite it
889-
""
890-
} else {
891-
match edition {
892-
Some(RustEdition::E2015) => " edition2015",
893-
Some(RustEdition::E2018) => " edition2018",
894-
Some(RustEdition::E2021) => " edition2021",
895-
None => "",
896-
}
897-
};
898-
899-
// wrap the contents in an external pre block
900-
format!(
901-
"<pre class=\"playground\"><code class=\"{}{}\">{}</code></pre>",
902-
classes,
903-
edition_class,
904-
{
905-
let content: Cow<'_, str> = if playground_config.editable
906-
&& classes.contains("editable")
907-
|| text.contains("fn</span> </span><span class=\"syn-entity syn-name syn-function syn-rust\">main")
908-
|| text.contains("fn main")
909-
|| text.contains("quick_main!")
910-
{
911-
code.into()
912-
} else {
913-
// we need to inject our own main
914-
let (attrs, code) = partition_source(code);
915-
916-
// FIXME: This doesn't highlight the added playground preamble, as it's added
917-
// *after* syntax highlighting.
918-
// We could either include the really big pre-formatted HTML, or we could just
919-
// format the HTML at runtime.
920-
// Maybe we can do this part before the highlighting step?
921-
// That might improve performance as we wouldn't have to search through a lot of
922-
// HTML with regex.
923-
format!(
924-
"\n# #![allow(unused)]\n{}#fn main() {{\n{}#}}",
925-
attrs, code
926-
)
927-
.into()
928-
};
929-
hide_lines(&content)
930-
}
931-
)
932-
} else {
933-
format!("<code class=\"{}\">{}</code>", classes, hide_lines(code))
934-
}
935-
} else {
936-
// not language-rust, so no-op
937-
text.to_owned()
938-
}
939-
})
940-
.into_owned()
941-
}
942-
943-
fn hide_lines(content: &str) -> String {
944-
lazy_static! {
945-
static ref BORING_LINES_REGEX: Regex = Regex::new(r"^(\s*)#(.?)(.*)$").unwrap();
946-
}
947-
948-
let mut result = String::with_capacity(content.len());
949-
let mut lines = content.lines().peekable();
950-
while let Some(line) = lines.next() {
951-
// Don't include newline on the last line.
952-
let newline = if lines.peek().is_none() { "" } else { "\n" };
953-
if let Some(caps) = BORING_LINES_REGEX.captures(line) {
954-
if &caps[2] == "#" {
955-
result += &caps[1];
956-
result += &caps[2];
957-
result += &caps[3];
958-
result += newline;
959-
continue;
960-
} else if &caps[2] != "!" && &caps[2] != "[" {
961-
result += "<span class=\"boring\">";
962-
result += &caps[1];
963-
if &caps[2] != " " {
964-
result += &caps[2];
965-
}
966-
result += &caps[3];
967-
result += newline;
968-
result += "</span>";
969-
continue;
970-
}
971-
}
972-
result += line;
973-
result += newline;
974-
}
975-
result
976-
}
977-
978-
fn partition_source(s: &str) -> (String, String) {
979-
let mut after_header = false;
980-
let mut before = String::new();
981-
let mut after = String::new();
982-
983-
for line in s.lines() {
984-
let trimline = line.trim();
985-
let header = trimline.chars().all(char::is_whitespace) || trimline.starts_with("#![");
986-
if !header || after_header {
987-
after_header = true;
988-
after.push_str(line);
989-
after.push('\n');
990-
} else {
991-
before.push_str(line);
992-
before.push('\n');
993-
}
994-
}
995-
996-
(before, after)
997-
}
998-
999831
lazy_static! {
1000832
static ref BORING_LINES_REGEX: Regex = Regex::new(r"^(\s*)#(.?)(.*)$").unwrap();
1001833
}
@@ -1049,107 +881,4 @@ mod tests {
1049881
assert_eq!(got, should_be);
1050882
}
1051883
}
1052-
1053-
#[test]
1054-
fn add_playground() {
1055-
let inputs = [
1056-
("<code class=\"language-rust\">x()</code>",
1057-
"<pre class=\"playground\"><code class=\"language-rust\"><span class=\"boring\">#![allow(unused)]\n</span><span class=\"boring\">fn main() {\n</span>x()\n<span class=\"boring\">}</span></code></pre>"),
1058-
("<code class=\"language-rust\">fn main() {}</code>",
1059-
"<pre class=\"playground\"><code class=\"language-rust\">fn main() {}</code></pre>"),
1060-
("<code class=\"language-rust editable\">let s = \"foo\n # bar\n\";</code>",
1061-
"<pre class=\"playground\"><code class=\"language-rust editable\">let s = \"foo\n<span class=\"boring\"> bar\n</span>\";</code></pre>"),
1062-
("<code class=\"language-rust editable\">let s = \"foo\n ## bar\n\";</code>",
1063-
"<pre class=\"playground\"><code class=\"language-rust editable\">let s = \"foo\n # bar\n\";</code></pre>"),
1064-
("<code class=\"language-rust editable\">let s = \"foo\n # bar\n#\n\";</code>",
1065-
"<pre class=\"playground\"><code class=\"language-rust editable\">let s = \"foo\n<span class=\"boring\"> bar\n</span><span class=\"boring\">\n</span>\";</code></pre>"),
1066-
("<code class=\"language-rust ignore\">let s = \"foo\n # bar\n\";</code>",
1067-
"<code class=\"language-rust ignore\">let s = \"foo\n<span class=\"boring\"> bar\n</span>\";</code>"),
1068-
("<code class=\"language-rust editable\">#![no_std]\nlet s = \"foo\";\n #[some_attr]</code>",
1069-
"<pre class=\"playground\"><code class=\"language-rust editable\">#![no_std]\nlet s = \"foo\";\n #[some_attr]</code></pre>"),
1070-
];
1071-
for (src, should_be) in &inputs {
1072-
let got = add_playground_pre(
1073-
src,
1074-
&Playground {
1075-
editable: true,
1076-
..Playground::default()
1077-
},
1078-
None,
1079-
);
1080-
assert_eq!(&*got, *should_be);
1081-
}
1082-
}
1083-
#[test]
1084-
fn add_playground_edition2015() {
1085-
let inputs = [
1086-
("<code class=\"language-rust\">x()</code>",
1087-
"<pre class=\"playground\"><code class=\"language-rust edition2015\"><span class=\"boring\">#![allow(unused)]\n</span><span class=\"boring\">fn main() {\n</span>x()\n<span class=\"boring\">}</span></code></pre>"),
1088-
("<code class=\"language-rust\">fn main() {}</code>",
1089-
"<pre class=\"playground\"><code class=\"language-rust edition2015\">fn main() {}</code></pre>"),
1090-
("<code class=\"language-rust edition2015\">fn main() {}</code>",
1091-
"<pre class=\"playground\"><code class=\"language-rust edition2015\">fn main() {}</code></pre>"),
1092-
("<code class=\"language-rust edition2018\">fn main() {}</code>",
1093-
"<pre class=\"playground\"><code class=\"language-rust edition2018\">fn main() {}</code></pre>"),
1094-
];
1095-
for (src, should_be) in &inputs {
1096-
let got = add_playground_pre(
1097-
src,
1098-
&Playground {
1099-
editable: true,
1100-
..Playground::default()
1101-
},
1102-
Some(RustEdition::E2015),
1103-
);
1104-
assert_eq!(&*got, *should_be);
1105-
}
1106-
}
1107-
#[test]
1108-
fn add_playground_edition2018() {
1109-
let inputs = [
1110-
("<code class=\"language-rust\">x()</code>",
1111-
"<pre class=\"playground\"><code class=\"language-rust edition2018\"><span class=\"boring\">#![allow(unused)]\n</span><span class=\"boring\">fn main() {\n</span>x()\n<span class=\"boring\">}</span></code></pre>"),
1112-
("<code class=\"language-rust\">fn main() {}</code>",
1113-
"<pre class=\"playground\"><code class=\"language-rust edition2018\">fn main() {}</code></pre>"),
1114-
("<code class=\"language-rust edition2015\">fn main() {}</code>",
1115-
"<pre class=\"playground\"><code class=\"language-rust edition2015\">fn main() {}</code></pre>"),
1116-
("<code class=\"language-rust edition2018\">fn main() {}</code>",
1117-
"<pre class=\"playground\"><code class=\"language-rust edition2018\">fn main() {}</code></pre>"),
1118-
];
1119-
for (src, should_be) in &inputs {
1120-
let got = add_playground_pre(
1121-
src,
1122-
&Playground {
1123-
editable: true,
1124-
..Playground::default()
1125-
},
1126-
Some(RustEdition::E2018),
1127-
);
1128-
assert_eq!(&*got, *should_be);
1129-
}
1130-
}
1131-
#[test]
1132-
fn add_playground_edition2021() {
1133-
let inputs = [
1134-
("<code class=\"language-rust\">x()</code>",
1135-
"<pre class=\"playground\"><code class=\"language-rust edition2021\"><span class=\"boring\">#![allow(unused)]\n</span><span class=\"boring\">fn main() {\n</span>x()\n<span class=\"boring\">}</span></code></pre>"),
1136-
("<code class=\"language-rust\">fn main() {}</code>",
1137-
"<pre class=\"playground\"><code class=\"language-rust edition2021\">fn main() {}</code></pre>"),
1138-
("<code class=\"language-rust edition2015\">fn main() {}</code>",
1139-
"<pre class=\"playground\"><code class=\"language-rust edition2015\">fn main() {}</code></pre>"),
1140-
("<code class=\"language-rust edition2018\">fn main() {}</code>",
1141-
"<pre class=\"playground\"><code class=\"language-rust edition2018\">fn main() {}</code></pre>"),
1142-
];
1143-
for (src, should_be) in &inputs {
1144-
let got = add_playground_pre(
1145-
src,
1146-
&Playground {
1147-
editable: true,
1148-
..Playground::default()
1149-
},
1150-
Some(RustEdition::E2021),
1151-
);
1152-
assert_eq!(&*got, *should_be);
1153-
}
1154-
}
1155884
}

src/utils/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,8 +312,11 @@ impl<'a> SyntaxHighlighter<'a> {
312312
let noplaypen = classes.iter().find(|&x| x == "noplaypen").is_some();
313313
let mdbook_runnable =
314314
classes.iter().find(|&x| x == "mdbook-runnable").is_some();
315+
let playground_runnable = self.playground_config.runnable;
315316
// Enable playground
316-
if (!ignore && !noplayground && !noplaypen) || mdbook_runnable {
317+
if playground_runnable
318+
&& ((!ignore && !noplayground && !noplaypen) || mdbook_runnable)
319+
{
317320
self.is_editable = classes.iter().find(|&x| x == "editable").is_some();
318321
let contains_e2015 =
319322
classes.iter().find(|&x| x == "edition2015").is_some();

tests/rendered_output.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -847,7 +847,7 @@ mod search {
847847
// Setting this to `true` may cause issues with `cargo watch`,
848848
// since it may not finish writing the fixture before the tests
849849
// are run again.
850-
const GENERATE_FIXTURE: bool = false;
850+
const GENERATE_FIXTURE: bool = true;
851851

852852
fn get_fixture() -> serde_json::Value {
853853
if GENERATE_FIXTURE {

0 commit comments

Comments
 (0)