diff --git a/CHANGELOG.md b/CHANGELOG.md index 34b54f61cc..6f09100bcf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,11 +4,11 @@ ### Breaking -- Switch to pulldown-cmark anchor rather than ours, some (very niche) edge cases are not supported anymore, you can +- Switch to pulldown-cmark anchor system rather than ours, some (very niche) edge cases are not supported anymore, you can also specify classes on headers now - Now outputs empty taxonomies instead of ignoring them - Unify all pages sorting variable names in templates to `lower`/`higher` in order to make it easy to re-use templates and it -was becoming hard to come up with names +was becoming hard to come up with names to be honest ### Other - Fix markup for fenced code with linenos @@ -24,11 +24,12 @@ any pages related to that taxonomy - Ignore sections with `render=false` when looking for path collisions - Add support for backlinks - Add a warning mode for internal/external link checking in case you don't want zola to stop the build on invalid links -- Always follow symlinks +- Always follow symlinks when loading the site/assets - Add `rel="alternate"` to Atom post links - Fix taxonomy `current_path` - Fix feed location for taxonomies not in the default language - Add `title_bytes` sorting method +- Add `insert_anchor = "heading"`, which allows users to use the entire heading as a link (rather than needing a seperate icon) ## 0.15.3 (2022-01-23) diff --git a/components/markdown/src/markdown.rs b/components/markdown/src/markdown.rs index efbac3621a..37cc224f9b 100644 --- a/components/markdown/src/markdown.rs +++ b/components/markdown/src/markdown.rs @@ -30,6 +30,10 @@ static EMOJI_REPLACER: Lazy = Lazy::new(EmojiReplacer::new); /// [uri-schemes]: https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml static STARTS_WITH_SCHEMA_RE: Lazy = Lazy::new(|| Regex::new(r"^[0-9A-Za-z\-]+:").unwrap()); +/// Matches a .. tag, getting the opening tag in a capture group. +/// Used only with AnchorInsert::Heading to grab it from the template +static A_HTML_TAG: Lazy = Lazy::new(|| Regex::new(r"(<\s*a[^>]*>).*?<\s*/\s*a>").unwrap()); + /// Efficiently insert multiple element in their specified index. /// The elements should sorted in ascending order by their index. /// @@ -516,7 +520,8 @@ pub fn markdown_to_html( let anchor_idx = match context.insert_anchor { InsertAnchor::Left => start_idx + 1, InsertAnchor::Right => end_idx, - InsertAnchor::None => 0, // Not important + InsertAnchor::Heading => 0, // modified later to the correct value + InsertAnchor::None => unreachable!(), }; let mut c = tera::Context::new(); c.insert("id", &id); @@ -530,7 +535,15 @@ pub fn markdown_to_html( &None, ) .context("Failed to render anchor link template")?; - anchors_to_insert.push((anchor_idx, Event::Html(anchor_link.into()))); + if context.insert_anchor != InsertAnchor::Heading { + anchors_to_insert.push((anchor_idx, Event::Html(anchor_link.into()))); + } else { + if let Some(captures) = A_HTML_TAG.captures(&anchor_link) { + let opening_tag = captures.get(1).map_or("", |m| m.as_str()).to_string(); + anchors_to_insert.push((start_idx + 1, Event::Html(opening_tag.into()))); + anchors_to_insert.push((end_idx, Event::Html("".into()))); + } + } } // record heading to make table of contents diff --git a/components/markdown/tests/markdown.rs b/components/markdown/tests/markdown.rs index bee984099b..a12246837b 100644 --- a/components/markdown/tests/markdown.rs +++ b/components/markdown/tests/markdown.rs @@ -101,6 +101,9 @@ fn can_insert_anchors() { let body = common::render_with_insert_anchor(&cases.join("\n"), InsertAnchor::Right).unwrap().body; insta::assert_snapshot!(body); + let body = + common::render_with_insert_anchor(&cases.join("\n"), InsertAnchor::Heading).unwrap().body; + insta::assert_snapshot!(body); } #[test] diff --git a/components/markdown/tests/snapshots/markdown__can_insert_anchors-3.snap b/components/markdown/tests/snapshots/markdown__can_insert_anchors-3.snap new file mode 100644 index 0000000000..9051a6f936 --- /dev/null +++ b/components/markdown/tests/snapshots/markdown__can_insert_anchors-3.snap @@ -0,0 +1,10 @@ +--- +source: components/markdown/tests/markdown.rs +expression: body +--- +

Hello

+

World

+

Hello!

+

Rust

+

Hello*_()

+ diff --git a/components/utils/src/types.rs b/components/utils/src/types.rs index 3feb957637..d4d53a151d 100644 --- a/components/utils/src/types.rs +++ b/components/utils/src/types.rs @@ -5,5 +5,12 @@ use serde::{Deserialize, Serialize}; pub enum InsertAnchor { Left, Right, + Heading, None, } + +impl InsertAnchor { + pub fn uses_template(&self) -> bool { + matches!(self, InsertAnchor::Left | InsertAnchor::Right) + } +} diff --git a/docs/content/documentation/content/linking.md b/docs/content/documentation/content/linking.md index 03c84c8b80..a426e0641b 100644 --- a/docs/content/documentation/content/linking.md +++ b/docs/content/documentation/content/linking.md @@ -32,7 +32,7 @@ links working. ## Anchor insertion It is possible to have Zola automatically insert anchor links next to the heading, as you can see on this documentation -if you hover a title. +if you hover a title or covering the full heading text. This option is set at the section level: the `insert_anchor_links` variable on the [section front matter page](@/documentation/content/section.md#front-matter). @@ -47,6 +47,9 @@ The anchor link template has the following variables: - `lang`: the current language, unless called from the `markdown` template filter, in which case it will always be `en` - `level`: the heading level (between 1 and 6) +If you use `insert_anchor = "heading"`, the template will still be used but only the opening `` tag will get extracted +from it, everything else will not be used. + ## Internal links Linking to other pages and their headings is so common that Zola adds a special syntax to Markdown links to handle them: start the link with `@/` and point to the `.md` file you want diff --git a/docs/content/documentation/content/section.md b/docs/content/documentation/content/section.md index c569205f80..527451473d 100644 --- a/docs/content/documentation/content/section.md +++ b/docs/content/documentation/content/section.md @@ -79,7 +79,8 @@ paginate_reversed = false # This determines whether to insert a link for each header like the ones you can see on this site if you hover over # a header. # The default template can be overridden by creating an `anchor-link.html` file in the `templates` directory. -# This value can be "left", "right" or "none". +# This value can be "left", "right", "heading" or "none". +# "heading" means the full heading becomes the text of the anchor. insert_anchor_links = "none" # If set to "true", the section pages will be in the search index. This is only used if