diff --git a/Cargo.toml b/Cargo.toml index 9451e2f2..7f245977 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,9 +21,10 @@ serde = "0.9" serde_json = "0.9" pulldown-cmark = "0.0.8" log = "0.3" -env_logger = "0.3" +env_logger = "0.4.0" toml = { version = "0.2", features = ["serde"] } open = "1.1" +regex = "0.2.1" # Watch feature notify = { version = "3.0", optional = true } diff --git a/src/lib.rs b/src/lib.rs index 0a59f9e7..49c56fac 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -74,6 +74,7 @@ extern crate serde; extern crate serde_json; extern crate handlebars; extern crate pulldown_cmark; +extern crate regex; #[macro_use] extern crate log; pub mod book; diff --git a/src/renderer/html_handlebars/hbs_renderer.rs b/src/renderer/html_handlebars/hbs_renderer.rs index b122ed14..a8bfa8eb 100644 --- a/src/renderer/html_handlebars/hbs_renderer.rs +++ b/src/renderer/html_handlebars/hbs_renderer.rs @@ -3,7 +3,9 @@ use renderer::Renderer; use book::MDBook; use book::bookitem::BookItem; use {utils, theme}; +use regex::{Regex, Captures}; +use std::ascii::AsciiExt; use std::path::{Path, PathBuf}; use std::fs::{self, File}; use std::error::Error; @@ -91,6 +93,9 @@ impl Renderer for HtmlHandlebars { // Render the handlebars template with the data debug!("[*]: Render template"); let rendered = try!(handlebars.render("index", &data)); + + // create links for headers + let rendered = build_header_links(rendered); // Write to file let filename = Path::new(&ch.path).with_extension("html"); @@ -208,3 +213,34 @@ fn make_data(book: &MDBook) -> Result debug!("[*]: JSON constructed"); Ok(data) } + +fn build_header_links(html: String) -> String { + let regex = Regex::new(r"(.*?)").unwrap(); + + regex.replace_all(&html, |caps: &Captures| { + let level = &caps[1]; + let text = &caps[2]; + let mut id = text.to_string(); + let repl_sub = vec!["", "", "", "", + "", "", + "<", ">", "&", "'", """]; + for sub in repl_sub { + id = id.replace(sub, ""); + } + let id = id.chars().filter_map(|c| { + if c.is_alphanumeric() || c == '-' || c == '_' { + if c.is_ascii() { + Some(c.to_ascii_lowercase()) + } else { + Some(c) + } + } else if c.is_whitespace() && c.is_ascii() { + Some('-') + } else { + None + } + }).collect::(); + + format!("{text}", level=level, id=id, text=text) + }).into_owned() +} diff --git a/src/theme/book.js b/src/theme/book.js index 8731880c..21295140 100644 --- a/src/theme/book.js +++ b/src/theme/book.js @@ -55,20 +55,6 @@ $( document ).ready(function() { var page_wrapper = $("#page-wrapper"); var content = $("#content"); - - // Add anchors for all content headers - content.find("h1, h2, h3, h4, h5").wrap(function(){ - var wrapper = $(""); - var header_name = $(this).text().trim().replace(/\W/g, '-') - wrapper.attr("name", header_name); - // Add so that when you click the link actually shows up in the url bar... - // Remove any existing anchor then append the new one - // ensuring eg. no spaces are present within it ie. they become %20 - wrapper.attr("href", $(location).attr('href').split("#")[0] + "#" + header_name ); - return wrapper; - }); - - // Toggle sidebar $("#sidebar-toggle").click(function(event){ if ( html.hasClass("sidebar-hidden") ) {