Pete Bacon Darwin 83b32a0a0a build(aio): render heading anchors on the right
This approach simplifies the styling needed considerably.
Previously, we had to make room on the left for heading that
are in visual containers. Also we had to apply a `float:right`
when on narrow screens as the gutter not available then.
This float didn't render nicely if the heading text was longer
than could be rendered on a single line.

Closes #22131
2018-02-27 18:32:32 -08:00

50 lines
1.4 KiB
JavaScript

const has = require('hast-util-has-property');
const is = require('hast-util-is-element');
const slug = require('rehype-slug');
const visit = require('unist-util-visit');
/**
* Get remark to add IDs to headings and inject anchors into them.
* This is a stripped-down equivalent of [rehype-autolink-headings](https://github.com/wooorm/rehype-autolink-headings)
* that supports ignoring headings with the `no-anchor` class.
*/
const HEADINGS = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
const NO_ANCHOR_CLASS = 'no-anchor';
const clone = obj => JSON.parse(JSON.stringify(obj));
const hasClass = (node, cls) => {
const className = node.properties.className;
return className && className.includes(cls);
};
const link = options =>
tree => visit(tree, node => {
if (is(node, HEADINGS) && has(node, 'id') && !hasClass(node, NO_ANCHOR_CLASS)) {
node.children.push({
type: 'element',
tagName: 'a',
properties: Object.assign(clone(options.properties), {href: `#${node.properties.id}`}),
children: clone(options.content)
});
}
});
module.exports = [
slug,
[link, {
properties: {
title: 'Link to this heading',
className: ['header-link'],
'aria-hidden': 'true'
},
content: [
{
type: 'element',
tagName: 'i',
properties: {className: ['material-icons']},
children: [{ type: 'text', value: 'link' }]
}
]
}]
];