Skip to content

Commit

Permalink
Allow relative links
Browse files Browse the repository at this point in the history
  • Loading branch information
cetra3 committed Feb 2, 2018
1 parent 1f4dab3 commit 70d366c
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 29 deletions.
2 changes: 1 addition & 1 deletion book-example/src/cli/init.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions book-example/src/for_developers/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 10 additions & 0 deletions src/renderer/html_handlebars/helpers/navigation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::collections::BTreeMap;
use serde_json;
use handlebars::{Context, Handlebars, Helper, RenderContext, RenderError, Renderable};

use utils;

type StringMap = BTreeMap<String, String>;

Expand Down Expand Up @@ -91,6 +92,15 @@ fn render(

let mut context = BTreeMap::new();

let base_path = rc.evaluate_absolute("path")?
.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")
.ok_or_else(|| RenderError::new("No title found for chapter in JSON data"))
.map(|name| context.insert("title".to_owned(), json!(name)))?;
Expand Down
4 changes: 4 additions & 0 deletions src/renderer/html_handlebars/helpers/toc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use serde_json;
use handlebars::{Handlebars, Helper, HelperDef, RenderContext, RenderError};
use pulldown_cmark::{html, Event, Parser, Tag};

use utils;

// Handlebars helper to construct TOC
#[derive(Clone, Copy)]
pub struct RenderToc {
Expand Down Expand Up @@ -66,6 +68,7 @@ impl HelperDef for RenderToc {

// Link
let path_exists = if let Some(path) = item.get("path") {

if !path.is_empty() {
rc.writer.write_all(b"<a href=\"")?;

Expand All @@ -77,6 +80,7 @@ impl HelperDef for RenderToc {
.replace("\\", "/");

// Add link
rc.writer.write_all(&utils::fs::path_to_root(&current).as_bytes())?;
rc.writer.write_all(tmp.as_bytes())?;
rc.writer.write_all(b"\"")?;

Expand Down
6 changes: 3 additions & 3 deletions src/theme/book.js
Original file line number Diff line number Diff line change
Expand Up @@ -290,9 +290,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() {
Expand Down
33 changes: 16 additions & 17 deletions src/theme/index.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@
<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">

Expand All @@ -19,9 +18,9 @@
<!-- Font Awesome -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.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 -->
{{#each additional_css}}
Expand Down Expand Up @@ -131,13 +130,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}}
Expand All @@ -149,13 +148,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 {{path_to_root}}" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
{{/next}}
Expand Down Expand Up @@ -212,11 +211,11 @@
{{/if}}

{{#if playpens_editable}}
<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 is_print}}
Expand All @@ -227,12 +226,12 @@
</script>
{{/if}}

<script src="highlight.js"></script>
<script src="book.js"></script>
<script src="{{path_to_root}}highlight.js"></script>
<script src="{{path_to_root}}book.js"></script>

<!-- Custom JS script -->
{{#each additional_js}}
<script type="text/javascript" src="{{this}}"></script>
<script type="text/javascript" src="{{ path_to_root }}{{this}}"></script>
{{/each}}

</body>
Expand Down
27 changes: 27 additions & 0 deletions src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,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);
Expand Down Expand Up @@ -62,6 +63,22 @@ impl EventQuoteConverter {
}
}

// Adjusts links so that local markdown links are converted to html
fn adjust_links(event: Event) -> Event {
match event {
Event::Start(Tag::Link(dest, title)) => {
if dest.ends_with(".md") && !dest.starts_with("http://") && !dest.starts_with("https://") {
let html_link = [&dest[..dest.len() - 3], ".html"].concat();

return Event::Start(Tag::Link(Cow::from(html_link), title))
}
Event::Start(Tag::Link(dest, title))
},
_ => event
}

}

fn clean_codeblock_headers(event: Event) -> Event {
match event {
Event::Start(Tag::CodeBlock(ref info)) => {
Expand Down Expand Up @@ -119,6 +136,16 @@ 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");
}

#[test]
fn it_can_keep_quotes_straight() {
assert_eq!(render_markdown("'one'", false), "<p>'one'</p>\n");
Expand Down
11 changes: 5 additions & 6 deletions tests/rendered_output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"];
Expand Down

0 comments on commit 70d366c

Please sign in to comment.