Use relative links and translate internal references (#603)
* Relative links for 0.1.8 * Compat for IE11 search
This commit is contained in:
parent
01656b610f
commit
bdb37ec117
|
@ -22,7 +22,7 @@ configuration files, etc.
|
|||
- The `book` directory is where your book is rendered. All the output is ready to be uploaded
|
||||
to a server to be seen by your audience.
|
||||
|
||||
- The `SUMMARY.md` file is the most important file, it's the skeleton of your book and is discussed in more detail in another [chapter](format/summary.html).
|
||||
- The `SUMMARY.md` file is the most important file, it's the skeleton of your book and is discussed in more detail in another [chapter](../format/summary.md)
|
||||
|
||||
#### Tip & Trick: Hidden Feature
|
||||
When a `SUMMARY.md` file already exists, the `init` command will first parse it and generate the missing files according to the paths used in the `SUMMARY.md`. This allows you to think and create the whole structure of your book and then let mdBook generate it for you.
|
||||
|
|
|
@ -11,8 +11,8 @@ The *For Developers* chapters are here to show you the more advanced usage of
|
|||
|
||||
The two main ways a developer can hook into the book's build process is via,
|
||||
|
||||
- [Preprocessors](for_developers/preprocessors.html)
|
||||
- [Alternate Backends](for_developers/backends.html)
|
||||
- [Preprocessors](preprocessors.md)
|
||||
- [Alternate Backends](backends.md)
|
||||
|
||||
|
||||
## The Build Process
|
||||
|
|
|
@ -42,10 +42,6 @@ impl HtmlHandlebars {
|
|||
.to_str()
|
||||
.chain_err(|| "Could not convert path to str")?;
|
||||
let filepath = Path::new(&ch.path).with_extension("html");
|
||||
let filepathstr = filepath
|
||||
.to_str()
|
||||
.chain_err(|| "Could not convert HTML path to str")?;
|
||||
let filepathstr = utils::fs::normalize_path(filepathstr);
|
||||
|
||||
// "print.html" is used for the print page.
|
||||
if ch.path == Path::new("print.md") {
|
||||
|
@ -75,10 +71,10 @@ impl HtmlHandlebars {
|
|||
debug!("Render template");
|
||||
let rendered = ctx.handlebars.render("index", &ctx.data)?;
|
||||
|
||||
let rendered = self.post_process(rendered, &filepathstr, &ctx.html_config.playpen);
|
||||
let rendered = self.post_process(rendered, &ctx.html_config.playpen);
|
||||
|
||||
// Write to file
|
||||
debug!("Creating {} ✓", filepathstr);
|
||||
debug!("Creating {} ✓", filepath.display());
|
||||
utils::fs::write_file(&ctx.destination, &filepath, &rendered.into_bytes())?;
|
||||
|
||||
if ctx.is_index {
|
||||
|
@ -120,9 +116,8 @@ impl HtmlHandlebars {
|
|||
}
|
||||
|
||||
#[cfg_attr(feature = "cargo-clippy", allow(let_and_return))]
|
||||
fn post_process(&self, rendered: String, filepath: &str, playpen_config: &Playpen) -> String {
|
||||
let rendered = build_header_links(&rendered, filepath);
|
||||
let rendered = fix_anchor_links(&rendered, filepath);
|
||||
fn post_process(&self, rendered: String, playpen_config: &Playpen) -> String {
|
||||
let rendered = build_header_links(&rendered);
|
||||
let rendered = fix_code_blocks(&rendered);
|
||||
let rendered = add_playpen_pre(&rendered, playpen_config);
|
||||
|
||||
|
@ -360,7 +355,7 @@ impl Renderer for HtmlHandlebars {
|
|||
debug!("Render template");
|
||||
let rendered = handlebars.render("index", &data)?;
|
||||
|
||||
let rendered = self.post_process(rendered, "print.html", &html_config.playpen);
|
||||
let rendered = self.post_process(rendered, &html_config.playpen);
|
||||
|
||||
utils::fs::write_file(&destination, "print.html", &rendered.into_bytes())?;
|
||||
debug!("Creating print.html ✓");
|
||||
|
@ -497,7 +492,7 @@ fn make_data(
|
|||
|
||||
/// Goes through the rendered HTML, making sure all header tags are wrapped in
|
||||
/// an anchor so people can link to sections directly.
|
||||
fn build_header_links(html: &str, filepath: &str) -> String {
|
||||
fn build_header_links(html: &str) -> String {
|
||||
let regex = Regex::new(r"<h(\d)>(.*?)</h\d>").unwrap();
|
||||
let mut id_counter = HashMap::new();
|
||||
|
||||
|
@ -507,7 +502,7 @@ fn build_header_links(html: &str, filepath: &str) -> String {
|
|||
.parse()
|
||||
.expect("Regex should ensure we only ever get numbers here");
|
||||
|
||||
wrap_header_with_link(level, &caps[2], &mut id_counter, filepath)
|
||||
wrap_header_with_link(level, &caps[2], &mut id_counter)
|
||||
})
|
||||
.into_owned()
|
||||
}
|
||||
|
@ -517,8 +512,7 @@ fn build_header_links(html: &str, filepath: &str) -> String {
|
|||
fn wrap_header_with_link(
|
||||
level: usize,
|
||||
content: &str,
|
||||
id_counter: &mut HashMap<String, usize>,
|
||||
filepath: &str,
|
||||
id_counter: &mut HashMap<String, usize>
|
||||
) -> String {
|
||||
let raw_id = utils::id_from_content(content);
|
||||
|
||||
|
@ -532,35 +526,13 @@ fn wrap_header_with_link(
|
|||
*id_count += 1;
|
||||
|
||||
format!(
|
||||
r##"<a class="header" href="{filepath}#{id}" id="{id}"><h{level}>{text}</h{level}></a>"##,
|
||||
r##"<a class="header" href="#{id}" id="{id}"><h{level}>{text}</h{level}></a>"##,
|
||||
level = level,
|
||||
id = id,
|
||||
text = content,
|
||||
filepath = filepath
|
||||
text = content
|
||||
)
|
||||
}
|
||||
|
||||
// anchors to the same page (href="#anchor") do not work because of
|
||||
// <base href="../"> pointing to the root folder. This function *fixes*
|
||||
// that in a very inelegant way
|
||||
fn fix_anchor_links(html: &str, filepath: &str) -> String {
|
||||
let regex = Regex::new(r##"<a([^>]+)href="#([^"]+)"([^>]*)>"##).unwrap();
|
||||
regex
|
||||
.replace_all(html, |caps: &Captures| {
|
||||
let before = &caps[1];
|
||||
let anchor = &caps[2];
|
||||
let after = &caps[3];
|
||||
|
||||
format!(
|
||||
"<a{before}href=\"{filepath}#{anchor}\"{after}>",
|
||||
before = before,
|
||||
filepath = filepath,
|
||||
anchor = anchor,
|
||||
after = after
|
||||
)
|
||||
})
|
||||
.into_owned()
|
||||
}
|
||||
|
||||
// The rust book uses annotations for rustdoc to test code snippets,
|
||||
// like the following:
|
||||
|
@ -660,37 +632,32 @@ mod tests {
|
|||
let inputs = vec![
|
||||
(
|
||||
"blah blah <h1>Foo</h1>",
|
||||
r##"blah blah <a class="header" href="./some_chapter/some_section.html#foo" id="foo"><h1>Foo</h1></a>"##,
|
||||
r##"blah blah <a class="header" href="#foo" id="foo"><h1>Foo</h1></a>"##,
|
||||
),
|
||||
(
|
||||
"<h1>Foo</h1>",
|
||||
r##"<a class="header" href="./some_chapter/some_section.html#foo" id="foo"><h1>Foo</h1></a>"##,
|
||||
r##"<a class="header" href="#foo" id="foo"><h1>Foo</h1></a>"##,
|
||||
),
|
||||
(
|
||||
"<h3>Foo^bar</h3>",
|
||||
r##"<a class="header" href="./some_chapter/some_section.html#foobar" id="foobar"><h3>Foo^bar</h3></a>"##,
|
||||
r##"<a class="header" href="#foobar" id="foobar"><h3>Foo^bar</h3></a>"##,
|
||||
),
|
||||
(
|
||||
"<h4></h4>",
|
||||
r##"<a class="header" href="./some_chapter/some_section.html#" id=""><h4></h4></a>"##,
|
||||
r##"<a class="header" href="#" id=""><h4></h4></a>"##,
|
||||
),
|
||||
(
|
||||
"<h4><em>Hï</em></h4>",
|
||||
r##"<a class="header" href="./some_chapter/some_section.html#hï" id="hï"><h4><em>Hï</em></h4></a>"##,
|
||||
r##"<a class="header" href="#hï" id="hï"><h4><em>Hï</em></h4></a>"##,
|
||||
),
|
||||
(
|
||||
"<h1>Foo</h1><h3>Foo</h3>",
|
||||
r##"<a class="header" href="./some_chapter/some_section.html#foo" id="foo"><h1>Foo</h1></a><a class="header" href="./some_chapter/some_section.html#foo-1" id="foo-1"><h3>Foo</h3></a>"##,
|
||||
r##"<a class="header" href="#foo" id="foo"><h1>Foo</h1></a><a class="header" href="#foo-1" id="foo-1"><h3>Foo</h3></a>"##,
|
||||
),
|
||||
];
|
||||
|
||||
for (src, should_be) in inputs {
|
||||
let filepath = "./some_chapter/some_section.html";
|
||||
let got = build_header_links(&src, filepath);
|
||||
assert_eq!(got, should_be);
|
||||
|
||||
// This is redundant for most cases
|
||||
let got = fix_anchor_links(&got, filepath);
|
||||
let got = build_header_links(&src);
|
||||
assert_eq!(got, should_be);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@ use std::collections::BTreeMap;
|
|||
use serde_json;
|
||||
use handlebars::{Context, Handlebars, Helper, RenderContext, RenderError, Renderable};
|
||||
|
||||
use utils;
|
||||
|
||||
type StringMap = BTreeMap<String, String>;
|
||||
|
||||
/// Target for `find_chapter`.
|
||||
|
@ -87,6 +89,13 @@ fn render(
|
|||
trace!("Creating BTreeMap to inject in context");
|
||||
|
||||
let mut context = BTreeMap::new();
|
||||
let base_path = rc.evaluate_absolute("path", false)?
|
||||
.as_str()
|
||||
.ok_or_else(|| RenderError::new("Type error for `path`, string expected"))?
|
||||
.replace("\"", "");
|
||||
|
||||
context.insert("path_to_root".to_owned(),
|
||||
json!(utils::fs::path_to_root(&base_path)));
|
||||
|
||||
chapter
|
||||
.get("name")
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
use std::path::Path;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use utils;
|
||||
|
||||
use serde_json;
|
||||
use handlebars::{Handlebars, Helper, HelperDef, RenderContext, RenderError};
|
||||
use pulldown_cmark::{html, Event, Parser, Tag};
|
||||
|
@ -77,6 +79,7 @@ impl HelperDef for RenderToc {
|
|||
.replace("\\", "/");
|
||||
|
||||
// Add link
|
||||
rc.writer.write_all(&utils::fs::path_to_root(¤t).as_bytes())?;
|
||||
rc.writer.write_all(tmp.as_bytes())?;
|
||||
rc.writer.write_all(b"\"")?;
|
||||
|
||||
|
|
|
@ -293,9 +293,9 @@ function playpen_text(playpen) {
|
|||
var themePopup = document.getElementById('theme-list');
|
||||
var themeColorMetaTag = document.querySelector('meta[name="theme-color"]');
|
||||
var stylesheets = {
|
||||
ayuHighlight: document.querySelector("[href='ayu-highlight.css']"),
|
||||
tomorrowNight: document.querySelector("[href='tomorrow-night.css']"),
|
||||
highlight: document.querySelector("[href='highlight.css']"),
|
||||
ayuHighlight: document.querySelector("[href$='ayu-highlight.css']"),
|
||||
tomorrowNight: document.querySelector("[href$='tomorrow-night.css']"),
|
||||
highlight: document.querySelector("[href$='highlight.css']"),
|
||||
};
|
||||
|
||||
function showThemes() {
|
||||
|
|
|
@ -9,20 +9,18 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<base href="{{ path_to_root }}">
|
||||
|
||||
<link rel="stylesheet" href="book.css">
|
||||
<link rel="stylesheet" href="{{ path_to_root }}book.css">
|
||||
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800" rel="stylesheet" type="text/css">
|
||||
<link href="https://fonts.googleapis.com/css?family=Source+Code+Pro:500" rel="stylesheet" type="text/css">
|
||||
|
||||
<link rel="shortcut icon" href="{{ favicon }}">
|
||||
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="{{ path_to_root }}FontAwesome/css/font-awesome.css">
|
||||
|
||||
<link rel="stylesheet" href="highlight.css">
|
||||
<link rel="stylesheet" href="tomorrow-night.css">
|
||||
<link rel="stylesheet" href="ayu-highlight.css">
|
||||
<link rel="stylesheet" href="{{ path_to_root }}highlight.css">
|
||||
<link rel="stylesheet" href="{{ path_to_root }}tomorrow-night.css">
|
||||
<link rel="stylesheet" href="{{ path_to_root }}ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
{{#each additional_css}}
|
||||
|
@ -107,7 +105,7 @@
|
|||
<h1 class="menu-title">{{ book_title }}</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="print.html" title="Print this book" aria-label="Print this book">
|
||||
<a href="{{ path_to_root }}print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
@ -144,13 +142,13 @@
|
|||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
{{#previous}}
|
||||
<a rel="prev" href="{{link}}" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<a rel="prev" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
{{/previous}}
|
||||
|
||||
{{#next}}
|
||||
<a rel="next" href="{{link}}" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<a rel="next" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
{{/next}}
|
||||
|
@ -162,13 +160,13 @@
|
|||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
{{#previous}}
|
||||
<a href="{{link}}" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<a href="{{ path_to_root }}{{link}}" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
{{/previous}}
|
||||
|
||||
{{#next}}
|
||||
<a href="{{link}}" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<a href="{{ path_to_root }}{{link}}" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
{{/next}}
|
||||
|
@ -213,29 +211,32 @@
|
|||
{{/if}}
|
||||
|
||||
{{#if playpen_js}}
|
||||
<script src="ace.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="editor.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="mode-rust.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="theme-dawn.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="theme-tomorrow_night.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="{{ path_to_root }}ace.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="{{ path_to_root }}editor.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="{{ path_to_root }}mode-rust.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="{{ path_to_root }}theme-dawn.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="{{ path_to_root }}theme-tomorrow_night.js" type="text/javascript" charset="utf-8"></script>
|
||||
{{/if}}
|
||||
|
||||
{{#if search_enabled}}
|
||||
<script src="searchindex.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="{{ path_to_root }}searchindex.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script>
|
||||
var path_to_root = "{{path_to_root}}";
|
||||
</script>
|
||||
{{/if}}
|
||||
{{#if search_js}}
|
||||
<script src="elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="{{ path_to_root }}elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="{{ path_to_root }}mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="{{ path_to_root }}searcher.js" type="text/javascript" charset="utf-8"></script>
|
||||
{{/if}}
|
||||
|
||||
<script src="clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="book.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="{{ path_to_root }}clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="{{ path_to_root }}highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="{{ path_to_root }}book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
{{#each additional_js}}
|
||||
<script type="text/javascript" src="{{this}}"></script>
|
||||
<script type="text/javascript" src="{{ path_to_root }}{{this}}"></script>
|
||||
{{/each}}
|
||||
|
||||
{{#if is_print}}
|
||||
|
|
|
@ -10,6 +10,13 @@ window.search = window.search || {};
|
|||
return;
|
||||
}
|
||||
|
||||
//IE 11 Compatibility from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith
|
||||
if (!String.prototype.startsWith) {
|
||||
String.prototype.startsWith = function(search, pos) {
|
||||
return this.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search;
|
||||
};
|
||||
}
|
||||
|
||||
var search_wrap = document.getElementById('search-wrapper'),
|
||||
searchbar = document.getElementById('searchbar'),
|
||||
searchbar_outer = document.getElementById('searchbar-outer'),
|
||||
|
@ -137,7 +144,7 @@ window.search = window.search || {};
|
|||
url.push("");
|
||||
}
|
||||
|
||||
return '<a href="' + url[0] + '?' + URL_MARK_PARAM + '=' + searchterms + '#' + url[1]
|
||||
return '<a href="' + path_to_root + url[0] + '?' + URL_MARK_PARAM + '=' + searchterms + '#' + url[1]
|
||||
+ '" aria-details="teaser_' + teaser_count + '">' + result.doc.breadcrumbs + '</a>'
|
||||
+ '<span class="teaser" id="teaser_' + teaser_count + '" aria-label="Search Result Teaser">'
|
||||
+ teaser + '</span>';
|
||||
|
|
|
@ -68,6 +68,35 @@ pub fn id_from_content(content: &str) -> String {
|
|||
normalize_id(trimmed)
|
||||
}
|
||||
|
||||
fn adjust_links(event: Event) -> Event {
|
||||
|
||||
lazy_static! {
|
||||
static ref HTTP_LINK: Regex = Regex::new("^https?://").unwrap();
|
||||
static ref MD_LINK: Regex = Regex::new("(?P<link>.*).md(?P<anchor>#.*)?").unwrap();
|
||||
}
|
||||
|
||||
match event {
|
||||
Event::Start(Tag::Link(dest, title)) => {
|
||||
if !HTTP_LINK.is_match(&dest) {
|
||||
if let Some(caps) = MD_LINK.captures(&dest) {
|
||||
|
||||
let mut html_link = [&caps["link"], ".html"].concat();
|
||||
|
||||
if let Some(anchor) = caps.name("anchor") {
|
||||
html_link.push_str(anchor.as_str());
|
||||
}
|
||||
|
||||
return Event::Start(Tag::Link(Cow::from(html_link), title))
|
||||
}
|
||||
}
|
||||
|
||||
Event::Start(Tag::Link(dest, title))
|
||||
},
|
||||
_ => event
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Wrapper around the pulldown-cmark parser for rendering markdown to HTML.
|
||||
pub fn render_markdown(text: &str, curly_quotes: bool) -> String {
|
||||
let mut s = String::with_capacity(text.len() * 3 / 2);
|
||||
|
@ -79,6 +108,7 @@ pub fn render_markdown(text: &str, curly_quotes: bool) -> String {
|
|||
let p = Parser::new_ext(text, opts);
|
||||
let mut converter = EventQuoteConverter::new(curly_quotes);
|
||||
let events = p.map(clean_codeblock_headers)
|
||||
.map(adjust_links)
|
||||
.map(|event| converter.convert(event));
|
||||
|
||||
html::push_html(&mut s, events);
|
||||
|
@ -177,6 +207,17 @@ mod tests {
|
|||
mod render_markdown {
|
||||
use super::super::render_markdown;
|
||||
|
||||
#[test]
|
||||
fn preserves_external_links() {
|
||||
assert_eq!(render_markdown("[example](https://www.rust-lang.org/)", false), "<p><a href=\"https://www.rust-lang.org/\">example</a></p>\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_can_adjust_markdown_links() {
|
||||
assert_eq!(render_markdown("[example](example.md)", false), "<p><a href=\"example.html\">example</a></p>\n");
|
||||
assert_eq!(render_markdown("[example_anchor](example.md#anchor)", false), "<p><a href=\"example.html#anchor\">example_anchor</a></p>\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_can_keep_quotes_straight() {
|
||||
assert_eq!(render_markdown("'one'", false), "<p>'one'</p>\n");
|
||||
|
|
|
@ -83,12 +83,11 @@ fn check_correct_cross_links_in_nested_dir() {
|
|||
|
||||
let first = temp.path().join("book").join("first");
|
||||
let links = vec![
|
||||
r#"<base href="../">"#,
|
||||
r#"href="intro.html""#,
|
||||
r#"href="first/index.html""#,
|
||||
r#"href="first/nested.html""#,
|
||||
r#"href="second.html""#,
|
||||
r#"href="conclusion.html""#,
|
||||
r#"href="../intro.html""#,
|
||||
r#"href="../first/index.html""#,
|
||||
r#"href="../first/nested.html""#,
|
||||
r#"href="../second.html""#,
|
||||
r#"href="../conclusion.html""#,
|
||||
];
|
||||
|
||||
let files_in_nested_dir = vec!["index.html", "nested.html"];
|
||||
|
@ -100,14 +99,14 @@ fn check_correct_cross_links_in_nested_dir() {
|
|||
assert_contains_strings(
|
||||
first.join("index.html"),
|
||||
&[
|
||||
r##"href="first/index.html#some-section" id="some-section""##,
|
||||
r##"href="#some-section" id="some-section""##,
|
||||
],
|
||||
);
|
||||
|
||||
assert_contains_strings(
|
||||
first.join("nested.html"),
|
||||
&[
|
||||
r##"href="first/nested.html#some-section" id="some-section""##,
|
||||
r##"href="#some-section" id="some-section""##,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
@ -367,8 +366,8 @@ fn by_default_mdbook_use_index_preprocessor_to_convert_readme_to_index() {
|
|||
.join("first")
|
||||
.join("index.html");
|
||||
let expected_strings = vec![
|
||||
r#"href="first/index.html""#,
|
||||
r#"href="second/index.html""#,
|
||||
r#"href="../first/index.html""#,
|
||||
r#"href="../second/index.html""#,
|
||||
"First README",
|
||||
];
|
||||
assert_contains_strings(&first_index, &expected_strings);
|
||||
|
|
Loading…
Reference in New Issue