Make co-located asset link permalinks
This commit is contained in:
parent
d39edd8ecb
commit
ef543b3d2b
|
@ -12,5 +12,4 @@ toml = "0.4"
|
||||||
regex = "1"
|
regex = "1"
|
||||||
lazy_static = "1"
|
lazy_static = "1"
|
||||||
|
|
||||||
|
|
||||||
errors = { path = "../errors" }
|
errors = { path = "../errors" }
|
||||||
|
|
|
@ -30,10 +30,15 @@ fn find_anchor(anchors: &[String], name: String, level: u8) -> String {
|
||||||
find_anchor(anchors, name, level + 1)
|
find_anchor(anchors, name, level + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_colocated_asset_link(link: &str) -> bool {
|
||||||
|
!link.contains("/") // http://, ftp://, ../ etc
|
||||||
|
&& !link.starts_with("mailto:")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn markdown_to_html(content: &str, context: &RenderContext) -> Result<(String, Vec<Header>)> {
|
pub fn markdown_to_html(content: &str, context: &RenderContext) -> Result<(String, Vec<Header>)> {
|
||||||
// the rendered html
|
// the rendered html
|
||||||
let mut html = String::new();
|
let mut html = String::with_capacity(content.len());
|
||||||
// Set while parsing
|
// Set while parsing
|
||||||
let mut error = None;
|
let mut error = None;
|
||||||
|
|
||||||
|
@ -104,29 +109,37 @@ pub fn markdown_to_html(content: &str, context: &RenderContext) -> Result<(Strin
|
||||||
Event::Html(Owned("</pre>".to_string()))
|
Event::Html(Owned("</pre>".to_string()))
|
||||||
},
|
},
|
||||||
// Need to handle relative links
|
// Need to handle relative links
|
||||||
Event::Start(Tag::Link(ref link, ref title)) => {
|
Event::Start(Tag::Link(link, title)) => {
|
||||||
if in_header {
|
// A few situations here:
|
||||||
if !title.is_empty() {
|
// - it could be a relative link (starting with `./`)
|
||||||
temp_header.push(&format!("<a href=\"{}\" title=\"{}\">", link, title));
|
// - it could be a link to a co-located asset
|
||||||
} else {
|
// - it could be a normal link
|
||||||
temp_header.push(&format!("<a href=\"{}\">", link));
|
// - any of those can be in a header or not: if it's in a header we need to append to a string
|
||||||
}
|
let fixed_link = if link.starts_with("./") {
|
||||||
return Event::Html(Owned(String::new()));
|
match resolve_internal_link(&link, context.permalinks) {
|
||||||
}
|
Ok(url) => url,
|
||||||
|
|
||||||
if link.starts_with("./") {
|
|
||||||
match resolve_internal_link(link, context.permalinks) {
|
|
||||||
Ok(url) => {
|
|
||||||
return Event::Start(Tag::Link(Owned(url), title.clone()));
|
|
||||||
},
|
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
error = Some(format!("Relative link {} not found.", link).into());
|
error = Some(format!("Relative link {} not found.", link).into());
|
||||||
return Event::Html(Owned(String::new()));
|
return Event::Html(Owned(String::new()));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
} else if is_colocated_asset_link(&link) {
|
||||||
|
format!("{}{}", context.current_page_permalink, link)
|
||||||
|
} else {
|
||||||
|
link.to_string()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if in_header {
|
||||||
|
let html = if title.is_empty() {
|
||||||
|
format!("<a href=\"{}\">", fixed_link)
|
||||||
|
} else {
|
||||||
|
format!("<a href=\"{}\" title=\"{}\">", fixed_link, title)
|
||||||
|
};
|
||||||
|
temp_header.push(&html);
|
||||||
|
return Event::Html(Owned(String::new()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::Start(Tag::Link(link.clone(), title.clone()))
|
Event::Start(Tag::Link(Owned(fixed_link), title))
|
||||||
},
|
},
|
||||||
Event::End(Tag::Link(_, _)) => {
|
Event::End(Tag::Link(_, _)) => {
|
||||||
if in_header {
|
if in_header {
|
||||||
|
|
|
@ -473,3 +473,34 @@ fn can_understand_link_with_title_in_header() {
|
||||||
"<h1 id=\"rust\"><a href=\"https://rust-lang.org\" title=\"Rust homepage\">Rust</a></h1>\n"
|
"<h1 id=\"rust\"><a href=\"https://rust-lang.org\" title=\"Rust homepage\">Rust</a></h1>\n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn can_make_valid_relative_link_in_header() {
|
||||||
|
let mut permalinks = HashMap::new();
|
||||||
|
permalinks.insert("pages/about.md".to_string(), "https://vincent.is/about/".to_string());
|
||||||
|
let tera_ctx = Tera::default();
|
||||||
|
let config = Config::default();
|
||||||
|
let context = RenderContext::new(&tera_ctx, &config, "", &permalinks, InsertAnchor::None);
|
||||||
|
let res = render_content(
|
||||||
|
r#" # [rel link](./pages/about.md)"#,
|
||||||
|
&context
|
||||||
|
).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
res.0,
|
||||||
|
"<h1 id=\"rel-link\"><a href=\"https://vincent.is/about/\">rel link</a></h1>\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn can_make_permalinks_with_colocated_assets() {
|
||||||
|
let permalinks_ctx = HashMap::new();
|
||||||
|
let config = Config::default();
|
||||||
|
let context = RenderContext::new(&GUTENBERG_TERA, &config, "https://vincent.is/about/", &permalinks_ctx, InsertAnchor::None);
|
||||||
|
let res = render_content("[an image](image.jpg)", &context).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
res.0,
|
||||||
|
"<p><a href=\"https://vincent.is/about/image.jpg\">an image</a></p>\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue