Skip to content

Commit e5a973a

Browse files
authored
Merge pull request #212 from azerupi/fix-anchors
Fix anchors #211
2 parents 5e3a3f3 + e218257 commit e5a973a

File tree

1 file changed

+26
-6
lines changed

1 file changed

+26
-6
lines changed

src/renderer/html_handlebars/hbs_renderer.rs

+26-6
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,16 @@ impl Renderer for HtmlHandlebars {
9595
debug!("[*]: Render template");
9696
let rendered = try!(handlebars.render("index", &data));
9797

98-
// create links for headers
99-
let rendered = build_header_links(rendered);
98+
let filename = Path::new(&ch.path).with_extension("html");
99+
100+
// create links for headers and fix anchors
101+
let rendered = build_header_links(rendered, filename.to_str().unwrap_or(""));
102+
let rendered = fix_anchor_links(rendered, filename.to_str().unwrap_or(""));
100103

101104
// fix code blocks
102105
let rendered = fix_code_blocks(rendered);
103106

104107
// Write to file
105-
let filename = Path::new(&ch.path).with_extension("html");
106108
info!("[*] Creating {:?} ✓", filename.display());
107109
try!(book.write_file(filename, &rendered.into_bytes()));
108110

@@ -144,7 +146,8 @@ impl Renderer for HtmlHandlebars {
144146
debug!("[*]: Render template");
145147

146148
let rendered = try!(handlebars.render("index", &data));
147-
let rendered = build_header_links(rendered);
149+
let rendered = build_header_links(rendered, "print.html");
150+
let rendered = fix_anchor_links(rendered, "print.html");
148151

149152
// fix code blocks
150153
let rendered = fix_code_blocks(rendered);
@@ -224,7 +227,7 @@ fn make_data(book: &MDBook) -> Result<serde_json::Map<String, serde_json::Value>
224227
Ok(data)
225228
}
226229

227-
fn build_header_links(html: String) -> String {
230+
fn build_header_links(html: String, filename: &str) -> String {
228231
let regex = Regex::new(r"<h(\d)>(.*?)</h\d>").unwrap();
229232

230233
regex.replace_all(&html, |caps: &Captures| {
@@ -251,10 +254,27 @@ fn build_header_links(html: String) -> String {
251254
}
252255
}).collect::<String>();
253256

254-
format!("<a class=\"header\" href=\"#{id}\" name=\"{id}\"><h{level}>{text}</h{level}></a>", level=level, id=id, text=text)
257+
format!("<a class=\"header\" href=\"{filename}#{id}\" name=\"{id}\"><h{level}>{text}</h{level}></a>",
258+
level=level, id=id, text=text, filename=filename)
255259
}).into_owned()
256260
}
257261

262+
// anchors to the same page (href="#anchor") do not work because of
263+
// <base href="../"> pointing to the root folder. This function *fixes*
264+
// that in a very inelegant way
265+
fn fix_anchor_links(html: String, filename: &str) -> String {
266+
let regex = Regex::new(r##"<a([^>]+)href="#([^"]+)"([^>]*)>"##).unwrap();
267+
regex.replace_all(&html, |caps: &Captures| {
268+
let before = &caps[1];
269+
let anchor = &caps[2];
270+
let after = &caps[3];
271+
272+
format!("<a{before}href=\"{filename}#{anchor}\"{after}>",
273+
before=before, filename=filename, anchor=anchor, after=after)
274+
}).into_owned()
275+
}
276+
277+
258278
// The rust book uses annotations for rustdoc to test code snippets, like the following:
259279
// ```rust,should_panic
260280
// fn main() {

0 commit comments

Comments
 (0)