Skip to content

Commit

Permalink
Merge pull request #212 from azerupi/fix-anchors
Browse files Browse the repository at this point in the history
Fix anchors #211
  • Loading branch information
azerupi authored Feb 28, 2017
2 parents 5e3a3f3 + e218257 commit e5a973a
Showing 1 changed file with 26 additions and 6 deletions.
32 changes: 26 additions & 6 deletions src/renderer/html_handlebars/hbs_renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,16 @@ impl Renderer for HtmlHandlebars {
debug!("[*]: Render template");
let rendered = try!(handlebars.render("index", &data));

// create links for headers
let rendered = build_header_links(rendered);
let filename = Path::new(&ch.path).with_extension("html");

// create links for headers and fix anchors
let rendered = build_header_links(rendered, filename.to_str().unwrap_or(""));
let rendered = fix_anchor_links(rendered, filename.to_str().unwrap_or(""));

// fix code blocks
let rendered = fix_code_blocks(rendered);

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

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

let rendered = try!(handlebars.render("index", &data));
let rendered = build_header_links(rendered);
let rendered = build_header_links(rendered, "print.html");
let rendered = fix_anchor_links(rendered, "print.html");

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

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

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

format!("<a class=\"header\" href=\"#{id}\" name=\"{id}\"><h{level}>{text}</h{level}></a>", level=level, id=id, text=text)
format!("<a class=\"header\" href=\"{filename}#{id}\" name=\"{id}\"><h{level}>{text}</h{level}></a>",
level=level, id=id, text=text, filename=filename)
}).into_owned()
}

// 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: String, filename: &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=\"{filename}#{anchor}\"{after}>",
before=before, filename=filename, anchor=anchor, after=after)
}).into_owned()
}


// The rust book uses annotations for rustdoc to test code snippets, like the following:
// ```rust,should_panic
// fn main() {
Expand Down

0 comments on commit e5a973a

Please sign in to comment.