Merge pull request #866 from rust-lang-nursery/gh828

Fixing links in print.html
This commit is contained in:
Steve Klabnik 2019-01-18 09:54:17 -05:00 committed by GitHub
commit 25c1ca1275
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 370 additions and 61 deletions

View File

@ -33,7 +33,11 @@ impl HtmlHandlebars {
if let BookItem::Chapter(ref ch) = *item { if let BookItem::Chapter(ref ch) = *item {
let content = ch.content.clone(); let content = ch.content.clone();
let content = utils::render_markdown(&content, ctx.html_config.curly_quotes); let content = utils::render_markdown(&content, ctx.html_config.curly_quotes);
print_content.push_str(&content);
let string_path = ch.path.parent().unwrap().display().to_string();
let fixed_content = utils::render_markdown_with_base(&ch.content, ctx.html_config.curly_quotes, &string_path);
print_content.push_str(&fixed_content);
// Update the context with data for this file // Update the context with data for this file
let path = ch let path = ch

View File

@ -66,15 +66,21 @@ pub fn id_from_content(content: &str) -> String {
normalize_id(trimmed) normalize_id(trimmed)
} }
fn adjust_links(event: Event) -> Event { fn adjust_links<'a>(event: Event<'a>, with_base: &str) -> Event<'a> {
lazy_static! { lazy_static! {
static ref HTTP_LINK: Regex = Regex::new("^https?://").unwrap(); static ref HTTP_LINK: Regex = Regex::new("^https?://").unwrap();
static ref MD_LINK: Regex = Regex::new("(?P<link>.*).md(?P<anchor>#.*)?").unwrap(); static ref MD_LINK: Regex = Regex::new(r"(?P<link>.*)\.md(?P<anchor>#.*)?").unwrap();
} }
match event { match event {
Event::Start(Tag::Link(dest, title)) => { Event::Start(Tag::Link(dest, title)) => {
if !HTTP_LINK.is_match(&dest) { if !HTTP_LINK.is_match(&dest) {
let dest = if !with_base.is_empty() {
format!("{}/{}", with_base, dest)
} else {
dest.clone().into_owned()
};
if let Some(caps) = MD_LINK.captures(&dest) { if let Some(caps) = MD_LINK.captures(&dest) {
let mut html_link = [&caps["link"], ".html"].concat(); let mut html_link = [&caps["link"], ".html"].concat();
@ -94,6 +100,10 @@ fn adjust_links(event: Event) -> Event {
/// Wrapper around the pulldown-cmark parser for rendering markdown to HTML. /// Wrapper around the pulldown-cmark parser for rendering markdown to HTML.
pub fn render_markdown(text: &str, curly_quotes: bool) -> String { pub fn render_markdown(text: &str, curly_quotes: bool) -> String {
render_markdown_with_base(text, curly_quotes, "")
}
pub fn render_markdown_with_base(text: &str, curly_quotes: bool, base: &str) -> String {
let mut s = String::with_capacity(text.len() * 3 / 2); let mut s = String::with_capacity(text.len() * 3 / 2);
let mut opts = Options::empty(); let mut opts = Options::empty();
@ -104,7 +114,7 @@ pub fn render_markdown(text: &str, curly_quotes: bool) -> String {
let mut converter = EventQuoteConverter::new(curly_quotes); let mut converter = EventQuoteConverter::new(curly_quotes);
let events = p let events = p
.map(clean_codeblock_headers) .map(clean_codeblock_headers)
.map(adjust_links) .map(|event| adjust_links(event, base))
.map(|event| converter.convert(event)); .map(|event| converter.convert(event));
html::push_html(&mut s, events); html::push_html(&mut s, events);
@ -220,6 +230,12 @@ mod tests {
render_markdown("[example_anchor](example.md#anchor)", false), render_markdown("[example_anchor](example.md#anchor)", false),
"<p><a href=\"example.html#anchor\">example_anchor</a></p>\n" "<p><a href=\"example.html#anchor\">example_anchor</a></p>\n"
); );
// this anchor contains 'md' inside of it
assert_eq!(
render_markdown("[phantom data](foo.html#phantomdata)", false),
"<p><a href=\"foo.html#phantomdata\">phantom data</a></p>\n"
);
} }
#[test] #[test]

View File

@ -8,6 +8,7 @@
- [Includes](first/includes.md) - [Includes](first/includes.md)
- [Recursive](first/recursive.md) - [Recursive](first/recursive.md)
- [Second Chapter](second.md) - [Second Chapter](second.md)
- [Nested Chapter](second/nested.md)
--- ---

View File

@ -0,0 +1,4 @@
# Testing relative links for the print page
When we link to [the first section](../first/nested.md), it should work on
both the print page and the non-print page.

View File

@ -31,7 +31,7 @@ const TOC_TOP_LEVEL: &[&'static str] = &[
"Introduction", "Introduction",
]; ];
const TOC_SECOND_LEVEL: &[&'static str] = const TOC_SECOND_LEVEL: &[&'static str] =
&["1.1. Nested Chapter", "1.2. Includes", "1.3. Recursive"]; &["1.1. Nested Chapter", "1.2. Includes", "2.1. Nested Chapter", "1.3. Recursive"];
/// Make sure you can load the dummy book and build it without panicking. /// Make sure you can load the dummy book and build it without panicking.
#[test] #[test]
@ -109,6 +109,20 @@ fn check_correct_cross_links_in_nested_dir() {
); );
} }
#[test]
fn check_correct_relative_links_in_print_page() {
let temp = DummyBook::new().build().unwrap();
let md = MDBook::load(temp.path()).unwrap();
md.build().unwrap();
let first = temp.path().join("book");
assert_contains_strings(
first.join("print.html"),
&[r##"<a href="second/../first/nested.html">the first section</a>,"##],
);
}
#[test] #[test]
fn rendered_code_has_playpen_stuff() { fn rendered_code_has_playpen_stuff() {
let temp = DummyBook::new().build().unwrap(); let temp = DummyBook::new().build().unwrap();
@ -443,7 +457,7 @@ mod search {
assert_eq!(docs[&some_section]["body"], ""); assert_eq!(docs[&some_section]["body"], "");
assert_eq!( assert_eq!(
docs[&summary]["body"], docs[&summary]["body"],
"Dummy Book Introduction First Chapter Nested Chapter Includes Recursive Second Chapter Conclusion" "Dummy Book Introduction First Chapter Nested Chapter Includes Recursive Second Chapter Nested Chapter Conclusion"
); );
assert_eq!(docs[&summary]["breadcrumbs"], "First Chapter » Summary"); assert_eq!(docs[&summary]["breadcrumbs"], "First Chapter » Summary");
assert_eq!(docs[&conclusion]["body"], "I put &lt;HTML&gt; in here!"); assert_eq!(docs[&conclusion]["body"], "I put &lt;HTML&gt; in here!");

View File

@ -9,6 +9,7 @@
"first/includes.html#includes", "first/includes.html#includes",
"first/includes.html#summary", "first/includes.html#summary",
"second.html#second-chapter", "second.html#second-chapter",
"second/nested.html#testing-relative-links-for-the-print-page",
"conclusion.html#conclusion" "conclusion.html#conclusion"
], ],
"index": { "index": {
@ -24,6 +25,11 @@
"breadcrumbs": 1, "breadcrumbs": 1,
"title": 1 "title": 1
}, },
"10": {
"body": 3,
"breadcrumbs": 1,
"title": 1
},
"2": { "2": {
"body": 2, "body": 2,
"breadcrumbs": 2, "breadcrumbs": 2,
@ -50,7 +56,7 @@
"title": 1 "title": 1
}, },
"7": { "7": {
"body": 12, "body": 14,
"breadcrumbs": 3, "breadcrumbs": 3,
"title": 1 "title": 1
}, },
@ -60,9 +66,9 @@
"title": 2 "title": 2
}, },
"9": { "9": {
"body": 3, "body": 10,
"breadcrumbs": 1, "breadcrumbs": 7,
"title": 1 "title": 5
} }
}, },
"docs": { "docs": {
@ -78,6 +84,12 @@
"id": "1", "id": "1",
"title": "Introduction" "title": "Introduction"
}, },
"10": {
"body": "I put &lt;HTML&gt; in here!",
"breadcrumbs": "Conclusion",
"id": "10",
"title": "Conclusion"
},
"2": { "2": {
"body": "more text.", "body": "more text.",
"breadcrumbs": "First Chapter", "breadcrumbs": "First Chapter",
@ -109,7 +121,7 @@
"title": "Includes" "title": "Includes"
}, },
"7": { "7": {
"body": "Dummy Book Introduction First Chapter Nested Chapter Includes Recursive Second Chapter Conclusion", "body": "Dummy Book Introduction First Chapter Nested Chapter Includes Recursive Second Chapter Nested Chapter Conclusion",
"breadcrumbs": "First Chapter » Summary", "breadcrumbs": "First Chapter » Summary",
"id": "7", "id": "7",
"title": "Summary" "title": "Summary"
@ -121,13 +133,13 @@
"title": "Second Chapter" "title": "Second Chapter"
}, },
"9": { "9": {
"body": "I put &lt;HTML&gt; in here!", "body": "When we link to the first section , it should work on both the print page and the non-print page.",
"breadcrumbs": "Conclusion", "breadcrumbs": "Second Chapter » Testing relative links for the print page",
"id": "9", "id": "9",
"title": "Conclusion" "title": "Testing relative links for the print page"
} }
}, },
"length": 10, "length": 11,
"save": true "save": true
}, },
"fields": [ "fields": [
@ -206,6 +218,18 @@
} }
} }
} }
},
"t": {
"df": 0,
"docs": {},
"h": {
"df": 1,
"docs": {
"9": {
"tf": 1.0
}
}
}
} }
} }
}, },
@ -251,7 +275,7 @@
"tf": 1.0 "tf": 1.0
}, },
"7": { "7": {
"tf": 1.7320508075688773 "tf": 2.0
}, },
"8": { "8": {
"tf": 1.0 "tf": 1.0
@ -296,10 +320,10 @@
"s": { "s": {
"df": 2, "df": 2,
"docs": { "docs": {
"7": { "10": {
"tf": 1.0 "tf": 1.0
}, },
"9": { "7": {
"tf": 1.0 "tf": 1.0
} }
} }
@ -420,13 +444,16 @@
"df": 0, "df": 0,
"docs": {}, "docs": {},
"t": { "t": {
"df": 2, "df": 3,
"docs": { "docs": {
"2": { "2": {
"tf": 1.0 "tf": 1.0
}, },
"7": { "7": {
"tf": 1.0 "tf": 1.0
},
"9": {
"tf": 1.0
} }
} }
} }
@ -485,7 +512,7 @@
"0": { "0": {
"tf": 1.0 "tf": 1.0
}, },
"9": { "10": {
"tf": 1.0 "tf": 1.0
} }
} }
@ -683,6 +710,14 @@
"tf": 1.0 "tf": 1.0
} }
} }
},
"k": {
"df": 1,
"docs": {
"9": {
"tf": 1.4142135623730951
}
}
} }
} }
}, },
@ -709,7 +744,7 @@
"t": { "t": {
"df": 1, "df": 1,
"docs": { "docs": {
"9": { "10": {
"tf": 1.0 "tf": 1.0
} }
} }
@ -791,14 +826,42 @@
"tf": 1.0 "tf": 1.0
}, },
"7": { "7": {
"tf": 1.0 "tf": 1.4142135623730951
} }
} }
} }
} }
},
"o": {
"df": 0,
"docs": {},
"n": {
"df": 1,
"docs": {
"9": {
"tf": 1.0
}
}
}
} }
}, },
"p": { "p": {
"a": {
"df": 0,
"docs": {},
"g": {
"df": 0,
"docs": {},
"e": {
"df": 1,
"docs": {
"9": {
"tf": 1.7320508075688772
}
}
}
}
},
"df": 0, "df": 0,
"docs": {}, "docs": {},
"r": { "r": {
@ -871,8 +934,12 @@
"df": 0, "df": 0,
"docs": {}, "docs": {},
"t": { "t": {
"df": 0, "df": 1,
"docs": {}, "docs": {
"9": {
"tf": 1.7320508075688772
}
},
"l": { "l": {
"df": 0, "df": 0,
"docs": {}, "docs": {},
@ -935,7 +1002,7 @@
"t": { "t": {
"df": 1, "df": 1,
"docs": { "docs": {
"9": { "10": {
"tf": 1.0 "tf": 1.0
} }
} }
@ -967,7 +1034,15 @@
} }
}, },
"df": 0, "df": 0,
"docs": {} "docs": {},
"l": {
"df": 1,
"docs": {
"9": {
"tf": 1.0
}
}
}
}, },
"u": { "u": {
"df": 0, "df": 0,
@ -1050,13 +1125,16 @@
"df": 0, "df": 0,
"docs": {}, "docs": {},
"n": { "n": {
"df": 2, "df": 3,
"docs": { "docs": {
"3": { "3": {
"tf": 1.0 "tf": 1.0
}, },
"5": { "5": {
"tf": 1.0 "tf": 1.0
},
"9": {
"tf": 1.0
} }
} }
} }
@ -1170,8 +1248,12 @@
"df": 0, "df": 0,
"docs": {} "docs": {}
}, },
"df": 0, "df": 1,
"docs": {} "docs": {
"9": {
"tf": 1.0
}
}
} }
}, },
"x": { "x": {
@ -1200,6 +1282,14 @@
"r": { "r": {
"df": 0, "df": 0,
"docs": {}, "docs": {},
"k": {
"df": 1,
"docs": {
"9": {
"tf": 1.0
}
}
},
"l": { "l": {
"d": { "d": {
"df": 1, "df": 1,
@ -1280,13 +1370,25 @@
"df": 2, "df": 2,
"docs": { "docs": {
"0": { "0": {
"tf": 1.4142135623730952 "tf": 1.4142135623730951
}, },
"7": { "7": {
"tf": 1.0 "tf": 1.0
} }
} }
} }
},
"t": {
"df": 0,
"docs": {},
"h": {
"df": 1,
"docs": {
"9": {
"tf": 1.0
}
}
}
} }
} }
}, },
@ -1323,13 +1425,13 @@
"df": 0, "df": 0,
"docs": {}, "docs": {},
"r": { "r": {
"df": 6, "df": 7,
"docs": { "docs": {
"2": { "2": {
"tf": 1.4142135623730952 "tf": 1.4142135623730951
}, },
"4": { "4": {
"tf": 1.7320508075688773 "tf": 1.7320508075688772
}, },
"5": { "5": {
"tf": 1.0 "tf": 1.0
@ -1338,10 +1440,13 @@
"tf": 1.0 "tf": 1.0
}, },
"7": { "7": {
"tf": 2.0 "tf": 2.23606797749979
}, },
"8": { "8": {
"tf": 1.4142135623730952 "tf": 1.4142135623730951
},
"9": {
"tf": 1.0
} }
} }
} }
@ -1383,11 +1488,11 @@
"s": { "s": {
"df": 2, "df": 2,
"docs": { "docs": {
"10": {
"tf": 1.4142135623730951
},
"7": { "7": {
"tf": 1.0 "tf": 1.0
},
"9": {
"tf": 1.4142135623730952
} }
} }
} }
@ -1419,7 +1524,7 @@
"df": 2, "df": 2,
"docs": { "docs": {
"0": { "0": {
"tf": 1.4142135623730952 "tf": 1.4142135623730951
}, },
"7": { "7": {
"tf": 1.0 "tf": 1.0
@ -1507,10 +1612,10 @@
"df": 0, "df": 0,
"docs": {}, "docs": {},
"t": { "t": {
"df": 5, "df": 6,
"docs": { "docs": {
"2": { "2": {
"tf": 1.4142135623730952 "tf": 1.4142135623730951
}, },
"4": { "4": {
"tf": 1.0 "tf": 1.0
@ -1522,7 +1627,10 @@
"tf": 1.0 "tf": 1.0
}, },
"7": { "7": {
"tf": 1.4142135623730952 "tf": 1.4142135623730951
},
"9": {
"tf": 1.0
} }
} }
} }
@ -1581,7 +1689,7 @@
"0": { "0": {
"tf": 1.0 "tf": 1.0
}, },
"9": { "10": {
"tf": 1.0 "tf": 1.0
} }
} }
@ -1636,7 +1744,7 @@
"df": 2, "df": 2,
"docs": { "docs": {
"6": { "6": {
"tf": 1.4142135623730952 "tf": 1.4142135623730951
}, },
"7": { "7": {
"tf": 1.0 "tf": 1.0
@ -1728,7 +1836,7 @@
"df": 2, "df": 2,
"docs": { "docs": {
"1": { "1": {
"tf": 1.4142135623730952 "tf": 1.4142135623730951
}, },
"7": { "7": {
"tf": 1.0 "tf": 1.0
@ -1779,6 +1887,14 @@
"tf": 1.0 "tf": 1.0
} }
} }
},
"k": {
"df": 1,
"docs": {
"9": {
"tf": 1.7320508075688772
}
}
} }
} }
}, },
@ -1805,7 +1921,7 @@
"t": { "t": {
"df": 1, "df": 1,
"docs": { "docs": {
"9": { "10": {
"tf": 1.0 "tf": 1.0
} }
} }
@ -1884,17 +2000,45 @@
"df": 2, "df": 2,
"docs": { "docs": {
"4": { "4": {
"tf": 1.4142135623730952 "tf": 1.4142135623730951
}, },
"7": { "7": {
"tf": 1.0 "tf": 1.4142135623730951
} }
} }
} }
} }
},
"o": {
"df": 0,
"docs": {},
"n": {
"df": 1,
"docs": {
"9": {
"tf": 1.0
}
}
}
} }
}, },
"p": { "p": {
"a": {
"df": 0,
"docs": {},
"g": {
"df": 0,
"docs": {},
"e": {
"df": 1,
"docs": {
"9": {
"tf": 2.0
}
}
}
}
},
"df": 0, "df": 0,
"docs": {}, "docs": {},
"r": { "r": {
@ -1967,8 +2111,12 @@
"df": 0, "df": 0,
"docs": {}, "docs": {},
"t": { "t": {
"df": 0, "df": 1,
"docs": {}, "docs": {
"9": {
"tf": 2.0
}
},
"l": { "l": {
"df": 0, "df": 0,
"docs": {}, "docs": {},
@ -2031,7 +2179,7 @@
"t": { "t": {
"df": 1, "df": 1,
"docs": { "docs": {
"9": { "10": {
"tf": 1.0 "tf": 1.0
} }
} }
@ -2063,7 +2211,15 @@
} }
}, },
"df": 0, "df": 0,
"docs": {} "docs": {},
"l": {
"df": 1,
"docs": {
"9": {
"tf": 1.4142135623730951
}
}
}
}, },
"u": { "u": {
"df": 0, "df": 0,
@ -2122,13 +2278,16 @@
"docs": {}, "docs": {},
"n": { "n": {
"d": { "d": {
"df": 2, "df": 3,
"docs": { "docs": {
"7": { "7": {
"tf": 1.0 "tf": 1.0
}, },
"8": { "8": {
"tf": 1.4142135623730952 "tf": 1.4142135623730951
},
"9": {
"tf": 1.0
} }
} }
}, },
@ -2146,13 +2305,16 @@
"df": 0, "df": 0,
"docs": {}, "docs": {},
"n": { "n": {
"df": 2, "df": 3,
"docs": { "docs": {
"3": { "3": {
"tf": 1.4142135623730952 "tf": 1.4142135623730951
}, },
"5": { "5": {
"tf": 1.4142135623730952 "tf": 1.4142135623730951
},
"9": {
"tf": 1.0
} }
} }
} }
@ -2216,7 +2378,7 @@
"df": 1, "df": 1,
"docs": { "docs": {
"7": { "7": {
"tf": 1.4142135623730952 "tf": 1.4142135623730951
} }
} }
} }
@ -2266,8 +2428,12 @@
"df": 0, "df": 0,
"docs": {} "docs": {}
}, },
"df": 0, "df": 1,
"docs": {} "docs": {
"9": {
"tf": 1.4142135623730951
}
}
} }
}, },
"x": { "x": {
@ -2296,6 +2462,14 @@
"r": { "r": {
"df": 0, "df": 0,
"docs": {}, "docs": {},
"k": {
"df": 1,
"docs": {
"9": {
"tf": 1.0
}
}
},
"l": { "l": {
"d": { "d": {
"df": 1, "df": 1,
@ -2388,7 +2562,7 @@
"s": { "s": {
"df": 1, "df": 1,
"docs": { "docs": {
"9": { "10": {
"tf": 1.0 "tf": 1.0
} }
} }
@ -2511,6 +2685,26 @@
} }
} }
}, },
"l": {
"df": 0,
"docs": {},
"i": {
"df": 0,
"docs": {},
"n": {
"df": 0,
"docs": {},
"k": {
"df": 1,
"docs": {
"9": {
"tf": 1.0
}
}
}
}
}
},
"n": { "n": {
"df": 0, "df": 0,
"docs": {}, "docs": {},
@ -2531,6 +2725,62 @@
} }
} }
}, },
"p": {
"a": {
"df": 0,
"docs": {},
"g": {
"df": 0,
"docs": {},
"e": {
"df": 1,
"docs": {
"9": {
"tf": 1.0
}
}
}
}
},
"df": 0,
"docs": {},
"r": {
"df": 0,
"docs": {},
"i": {
"df": 0,
"docs": {},
"n": {
"df": 0,
"docs": {},
"t": {
"df": 1,
"docs": {
"9": {
"tf": 1.0
}
}
}
}
}
}
},
"r": {
"df": 0,
"docs": {},
"e": {
"df": 0,
"docs": {},
"l": {
"df": 1,
"docs": {
"9": {
"tf": 1.0
}
}
}
}
},
"s": { "s": {
"df": 0, "df": 0,
"docs": {}, "docs": {},
@ -2609,6 +2859,26 @@
} }
} }
} }
},
"t": {
"df": 0,
"docs": {},
"e": {
"df": 0,
"docs": {},
"s": {
"df": 0,
"docs": {},
"t": {
"df": 1,
"docs": {
"9": {
"tf": 1.0
}
}
}
}
}
} }
} }
} }