Insert anchor as full heading (#1916)

* Add insert_anchor = "heading"

* Update CHANGELOG.md

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
This commit is contained in:
Vincent Prouillet 2022-07-10 15:02:07 +02:00 committed by GitHub
parent 065e8e64e5
commit 7208b86d77
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 45 additions and 7 deletions

View File

@ -4,11 +4,11 @@
### Breaking ### 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 also specify classes on headers now
- Now outputs empty taxonomies instead of ignoring them - 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 - 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 ### Other
- Fix markup for fenced code with linenos - 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 - Ignore sections with `render=false` when looking for path collisions
- Add support for backlinks - 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 - 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 - Add `rel="alternate"` to Atom post links
- Fix taxonomy `current_path` - Fix taxonomy `current_path`
- Fix feed location for taxonomies not in the default language - Fix feed location for taxonomies not in the default language
- Add `title_bytes` sorting method - 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) ## 0.15.3 (2022-01-23)

View File

@ -30,6 +30,10 @@ static EMOJI_REPLACER: Lazy<EmojiReplacer> = Lazy::new(EmojiReplacer::new);
/// [uri-schemes]: https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml /// [uri-schemes]: https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml
static STARTS_WITH_SCHEMA_RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"^[0-9A-Za-z\-]+:").unwrap()); static STARTS_WITH_SCHEMA_RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"^[0-9A-Za-z\-]+:").unwrap());
/// Matches a <a>..</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<Regex> = Lazy::new(|| Regex::new(r"(<\s*a[^>]*>).*?<\s*/\s*a>").unwrap());
/// Efficiently insert multiple element in their specified index. /// Efficiently insert multiple element in their specified index.
/// The elements should sorted in ascending order by their 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 { let anchor_idx = match context.insert_anchor {
InsertAnchor::Left => start_idx + 1, InsertAnchor::Left => start_idx + 1,
InsertAnchor::Right => end_idx, 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(); let mut c = tera::Context::new();
c.insert("id", &id); c.insert("id", &id);
@ -530,7 +535,15 @@ pub fn markdown_to_html(
&None, &None,
) )
.context("Failed to render anchor link template")?; .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("</a>".into())));
}
}
} }
// record heading to make table of contents // record heading to make table of contents

View File

@ -101,6 +101,9 @@ fn can_insert_anchors() {
let body = let body =
common::render_with_insert_anchor(&cases.join("\n"), InsertAnchor::Right).unwrap().body; common::render_with_insert_anchor(&cases.join("\n"), InsertAnchor::Right).unwrap().body;
insta::assert_snapshot!(body); insta::assert_snapshot!(body);
let body =
common::render_with_insert_anchor(&cases.join("\n"), InsertAnchor::Heading).unwrap().body;
insta::assert_snapshot!(body);
} }
#[test] #[test]

View File

@ -0,0 +1,10 @@
---
source: components/markdown/tests/markdown.rs
expression: body
---
<h1 id="hello"><a class="zola-anchor" href="#hello" aria-label="Anchor link for: hello">Hello</a></h1>
<h1 id="world"><a class="zola-anchor" href="#world" aria-label="Anchor link for: world">World</a></h1>
<h1 id="hello-1"><a class="zola-anchor" href="#hello-1" aria-label="Anchor link for: hello-1">Hello!</a></h1>
<h2 id="rust"><a class="zola-anchor" href="#rust" aria-label="Anchor link for: rust"><a href="https://rust-lang.org">Rust</a></a></h2>
<h1 id="hello-2"><a class="zola-anchor" href="#hello-2" aria-label="Anchor link for: hello-2">Hello*_()</a></h1>

View File

@ -5,5 +5,12 @@ use serde::{Deserialize, Serialize};
pub enum InsertAnchor { pub enum InsertAnchor {
Left, Left,
Right, Right,
Heading,
None, None,
} }
impl InsertAnchor {
pub fn uses_template(&self) -> bool {
matches!(self, InsertAnchor::Left | InsertAnchor::Right)
}
}

View File

@ -32,7 +32,7 @@ links working.
## Anchor insertion ## Anchor insertion
It is possible to have Zola automatically insert anchor links next to the heading, as you can see on this documentation 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 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). [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` - `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) - `level`: the heading level (between 1 and 6)
If you use `insert_anchor = "heading"`, the template will still be used but only the opening `<a>` tag will get extracted
from it, everything else will not be used.
## Internal links ## Internal links
Linking to other pages and their headings is so common that Zola adds a 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 special syntax to Markdown links to handle them: start the link with `@/` and point to the `.md` file you want

View File

@ -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 # 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. # a header.
# The default template can be overridden by creating an `anchor-link.html` file in the `templates` directory. # 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" insert_anchor_links = "none"
# If set to "true", the section pages will be in the search index. This is only used if # If set to "true", the section pages will be in the search index. This is only used if