-
Notifications
You must be signed in to change notification settings - Fork 73
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add container around heading and anchor #100
Comments
This is how I get this result with markdown-it-anchor v7 (and Eleventy): https://github.com/nhoizey/nicolas-hoizey.com/blob/main/.eleventy.js#L102-L177 const markdownItAnchorOptions = {
permalink: true,
permalinkClass: 'deeplink',
permalinkSymbol:
'<svg class="icon" role="img" focusable="false" viewBox="0 0 24 24" width="1em" height="1em"><use xlink:href="#symbol-anchor" /></svg>',
level: [2, 3, 4],
slugify: function (s) {
return slugify(s);
},
renderPermalink: (slug, opts, state, idx) => {
// based on fifth version in
// https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/
const linkContent = state.tokens[idx + 1].children[0].content;
// Create the openning <div> for the wrapper
const headingWrapperTokenOpen = Object.assign(
new state.Token('div_open', 'div', 1),
{
attrs: [['class', 'heading-wrapper']],
}
);
// Create the closing </div> for the wrapper
const headingWrapperTokenClose = Object.assign(
new state.Token('div_close', 'div', -1),
{
attrs: [['class', 'heading-wrapper']],
}
);
// Create the tokens for the full accessible anchor link
// <a class="deeplink" href="#your-own-platform-is-the-nearest-you-can-get-help-to-setup">
// <span aria-hidden="true">
// ${opts.permalinkSymbol}
// </span>
// <span class="visually-hidden">
// Section titled Your "own" platform is the nearest you can(get help to) setup
// </span>
// </a >
const anchorTokens = [
Object.assign(new state.Token('link_open', 'a', 1), {
attrs: [
...(opts.permalinkClass ? [['class', opts.permalinkClass]] : []),
['href', opts.permalinkHref(slug, state)],
...Object.entries(opts.permalinkAttrs(slug, state)),
],
}),
Object.assign(new state.Token('span_open', 'span', 1), {
attrs: [['aria-hidden', 'true']],
}),
Object.assign(new state.Token('html_block', '', 0), {
content: opts.permalinkSymbol,
}),
Object.assign(new state.Token('span_close', 'span', -1), {}),
Object.assign(new state.Token('span_open', 'span', 1), {
attrs: [['class', 'visually-hidden']],
}),
Object.assign(new state.Token('html_block', '', 0), {
content: `Section titled ${linkContent}`,
}),
Object.assign(new state.Token('span_close', 'span', -1), {}),
new state.Token('link_close', 'a', -1),
];
// idx is the index of the heading's first token
// insert the wrapper opening before the heading
state.tokens.splice(idx, 0, headingWrapperTokenOpen);
// insert the anchor link tokens after the wrapper opening and the 3 tokens of the heading
state.tokens.splice(idx + 3 + 1, 0, ...anchorTokens);
// insert the wrapper closing after all these
state.tokens.splice(
idx + 3 + 1 + anchorTokens.length,
0,
headingWrapperTokenClose
);
},
}; |
Hey! Sorry for the late reply. I was about to suggest the following: const linkAfterHeader = anchor.permalink.linkAfterHeader({
class: 'deeplink',
symbol: '<svg class="icon" role="img" focusable="false" viewBox="0 0 24 24" width="1em" height="1em"><use xlink:href="#symbol-anchor" /></svg>',
style: 'visually-hidden',
visuallyHiddenClass: 'visually-hidden',
assistiveText: (title) => `Permalink to heading ${title}`,
})
const options = {
level: [2, 3, 4],
slugify,
permalink (slug, opts, state, idx) {
state.tokens.splice(idx, 0, Object.assign(new state.Token('div_open', 'div', 1), {
attrs: [['class', 'heading-wrapper']],
block: true
}))
state.tokens.splice(idx + 4, 0, Object.assign(new state.Token('div_close', 'div', -1), {
block: true
}))
linkAfterHeader(slug, opts, state, idx + 1)
}
} But sadly this doesn't work because the fact we splice before the current header causes an infinite loop (the "next" token from markdown-it-anchor's perspective is the header we just processed, so we call the permalink on it again and so on). By default it just throws on the second iteration of the same header because the I just made a quick fix so that markdown-it-anchor is more friendly to renderers that use |
Hi @valeriangalliat, it works indeed, thanks a lot! 🙏 |
I'm trying to migrate to v8 and couldn't find how to add a container around the heading and the anchor.
Here are my options:
I get this HTML:
I want to position the anchor link relative to the heading, so I need a container for both. It would be great to have an option to add this container with a class:
The text was updated successfully, but these errors were encountered: