Merge pull request #207 from steveklabnik/gh204

Generate links at compile-time rather than use JS
This commit is contained in:
Mathieu David 2017-02-17 11:00:39 +01:00 committed by GitHub
commit 864be6cf42
4 changed files with 39 additions and 15 deletions

View File

@ -21,9 +21,10 @@ serde = "0.9"
serde_json = "0.9" serde_json = "0.9"
pulldown-cmark = "0.0.8" pulldown-cmark = "0.0.8"
log = "0.3" log = "0.3"
env_logger = "0.3" env_logger = "0.4.0"
toml = { version = "0.2", features = ["serde"] } toml = { version = "0.2", features = ["serde"] }
open = "1.1" open = "1.1"
regex = "0.2.1"
# Watch feature # Watch feature
notify = { version = "3.0", optional = true } notify = { version = "3.0", optional = true }

View File

@ -74,6 +74,7 @@ extern crate serde;
extern crate serde_json; extern crate serde_json;
extern crate handlebars; extern crate handlebars;
extern crate pulldown_cmark; extern crate pulldown_cmark;
extern crate regex;
#[macro_use] extern crate log; #[macro_use] extern crate log;
pub mod book; pub mod book;

View File

@ -3,7 +3,9 @@ use renderer::Renderer;
use book::MDBook; use book::MDBook;
use book::bookitem::BookItem; use book::bookitem::BookItem;
use {utils, theme}; use {utils, theme};
use regex::{Regex, Captures};
use std::ascii::AsciiExt;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::fs::{self, File}; use std::fs::{self, File};
use std::error::Error; use std::error::Error;
@ -92,6 +94,9 @@ impl Renderer for HtmlHandlebars {
debug!("[*]: Render template"); debug!("[*]: Render template");
let rendered = try!(handlebars.render("index", &data)); let rendered = try!(handlebars.render("index", &data));
// create links for headers
let rendered = build_header_links(rendered);
// Write to file // Write to file
let filename = Path::new(&ch.path).with_extension("html"); let filename = Path::new(&ch.path).with_extension("html");
info!("[*] Creating {:?} ✓", filename.display()); info!("[*] Creating {:?} ✓", filename.display());
@ -208,3 +213,34 @@ fn make_data(book: &MDBook) -> Result<serde_json::Map<String, serde_json::Value>
debug!("[*]: JSON constructed"); debug!("[*]: JSON constructed");
Ok(data) Ok(data)
} }
fn build_header_links(html: String) -> String {
let regex = Regex::new(r"<h(\d)>(.*?)</h\d>").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!["<em>", "</em>", "<code>", "</code>",
"<strong>", "</strong>",
"&lt;", "&gt;", "&amp;", "&#39;", "&quot;"];
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::<String>();
format!("<a class=\"header\" href=\"#{id}\" name=\"{id}\"><h{level}>{text}</h{level}></a>", level=level, id=id, text=text)
}).into_owned()
}

View File

@ -55,20 +55,6 @@ $( document ).ready(function() {
var page_wrapper = $("#page-wrapper"); var page_wrapper = $("#page-wrapper");
var content = $("#content"); var content = $("#content");
// Add anchors for all content headers
content.find("h1, h2, h3, h4, h5").wrap(function(){
var wrapper = $("<a class=\"header\">");
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 // Toggle sidebar
$("#sidebar-toggle").click(function(event){ $("#sidebar-toggle").click(function(event){
if ( html.hasClass("sidebar-hidden") ) { if ( html.hasClass("sidebar-hidden") ) {