From 0f8fd5357b316fc0c6e37afc070afc9254241040 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yaroslav=20de=20la=20Pe=C3=B1a=20Smirnov?= Date: Thu, 5 May 2022 01:21:30 +0300 Subject: [PATCH] Fix broken links to images in summary Restores the change of relative to absolute links for colocated files that was removed in commit 4086b075 / PR #1582. --- components/rendering/src/markdown.rs | 31 ++++++++++++++++++++++++++ components/rendering/tests/markdown.rs | 4 ++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/components/rendering/src/markdown.rs b/components/rendering/src/markdown.rs index 4181c2dcb3..d4d0990daa 100644 --- a/components/rendering/src/markdown.rs +++ b/components/rendering/src/markdown.rs @@ -1,5 +1,6 @@ use lazy_static::lazy_static; use pulldown_cmark as cmark; +use regex::Regex; use crate::context::RenderContext; use crate::table_of_contents::{make_table_of_contents, Heading}; @@ -64,6 +65,26 @@ fn is_external_link(link: &str) -> bool { link.starts_with("http:") || link.starts_with("https:") } +/// Returns whether the given string starts with a schema. +/// +/// Although there exists [a list of registered URI schemes][uri-schemes], a link may use arbitrary, +/// private schemes. This function checks if the given string starts with something that just looks +/// like a scheme, i.e., a case-insensitive identifier followed by a colon. +/// +/// [uri-schemes]: https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml +fn starts_with_schema(s: &str) -> bool { + lazy_static! { + static ref PATTERN: Regex = Regex::new(r"^[0-9A-Za-z\-]+:").unwrap(); + } + PATTERN.is_match(s) +} + +/// Colocated asset links refers to the files in the same directory, +/// there it shouldn't start with / or a schema +fn is_colocated_asset_link(link: &str) -> bool { + !link.starts_with("/") && !starts_with_schema(link) +} + fn fix_link( link_type: LinkType, link: &str, @@ -89,6 +110,8 @@ fn fix_link( return Err(format!("Relative link {} not found.", link).into()); } } + } else if is_colocated_asset_link(link) { + format!("{}{}", context.current_page_permalink, link) } else { if is_external_link(link) { external_links.push(link.to_owned()); @@ -298,6 +321,14 @@ pub fn markdown_to_html( code_block = None; events.push(Event::Html("\n".into())); } + Event::Start(Tag::Image(link_type, src, title)) => { + if is_colocated_asset_link(&src) { + let link = format!("{}{}", context.current_page_permalink, &*src); + events.push(Event::Start(Tag::Image(link_type, link.into(), title))); + } else { + events.push(Event::Start(Tag::Image(link_type, src, title))); + } + } Event::Start(Tag::Link(link_type, link, title)) if link.is_empty() => { error = Some(Error::msg("There is a link that is missing a URL")); events.push(Event::Start(Tag::Link(link_type, "#".into(), title))); diff --git a/components/rendering/tests/markdown.rs b/components/rendering/tests/markdown.rs index bcd0eda297..8e06e68ab4 100644 --- a/components/rendering/tests/markdown.rs +++ b/components/rendering/tests/markdown.rs @@ -1017,7 +1017,7 @@ fn can_make_permalinks_with_colocated_assets_for_link() { InsertAnchor::None, ); let res = render_content("[an image](image.jpg)", &context).unwrap(); - assert_eq!(res.body, "

an image

\n"); + assert_eq!(res.body, "

an image

\n"); } #[test] @@ -1033,7 +1033,7 @@ fn can_make_permalinks_with_colocated_assets_for_image() { InsertAnchor::None, ); let res = render_content("![alt text](image.jpg)", &context).unwrap(); - assert_eq!(res.body, "

\"alt

\n"); + assert_eq!(res.body, "

\"alt

\n"); } #[test]