diff --git a/readme.md b/readme.md index 9e375e0..2760105 100644 --- a/readme.md +++ b/readme.md @@ -85,8 +85,8 @@ How to create links (`string`, default: `'prepend'`). * `'before'` — insert link before the heading * `'after'` — insert link after the heading -Note that supplying `wrap` will ignore any value defined by the `content` -option. +Supplying `wrap` will ignore any value defined by the `content` option. +Supplying `prepend`, `append`, or `wrap` will ignore the `group` option. ###### `options.content` @@ -101,6 +101,8 @@ By default, the following is used: } ``` +If `behavior` is `wrap`, then `content` is ignored. + If `content` is a function, it’s called with the current heading (`Node`) and should return one or more nodes: @@ -118,6 +120,27 @@ function content(node) { } ``` +###### `options.group` + +[**hast**][hast] node to wrap the heading and link with (`Function|Node`), if +`behavior` is `before` or `after`. +There is no default. + +If `behavior` is `prepend`, `append`, or `wrap`, then `group` is ignored. + +If `group` is a function, it’s called with the current heading (`Node`) and +should return a hast node. + +```js +const h = require('hastscript') + +// … + +function group(node) { + return h('div.heading-' + node.depth + '-group') +} +``` + ###### `options.linkProperties` Extra properties to set on the link (`Object?`). diff --git a/src/__tests__/index.js b/src/__tests__/index.js index c4f62dd..4ae242e 100644 --- a/src/__tests__/index.js +++ b/src/__tests__/index.js @@ -94,6 +94,43 @@ test('should accept link properties', (t) => { ) }) +test('should accept a custom group', (t) => { + t.is( + remark() + .use(slug) + .use(html) + .use(headings, { + group: { + tagName: 'div', + properties: {className: ['heading-group']} + }, + behaviour: 'before' + }) + .processSync('# method') + .toString(), + '

method

\n' + ) +}) + +test('should accept a custom group as a function', (t) => { + t.is( + remark() + .use(slug) + .use(html) + .use(headings, {group, behaviour: 'after'}) + .processSync('# method') + .toString(), + '

method

\n' + ) + + function group(node) { + return { + tagName: 'div', + properties: {className: ['heading-' + node.depth + '-group']} + } + } +}) + test('should do nothing if slugs are not used', (t) => { t.is( remark().use(headings).use(html).processSync(base('input.md')).toString(), diff --git a/src/index.js b/src/index.js index 551e42c..49fe822 100644 --- a/src/index.js +++ b/src/index.js @@ -16,7 +16,7 @@ const splice = [].splice let deprecationWarningIssued = false export default function attacher(options = {}) { - let {linkProperties, behavior, content} = {...defaults, ...options} + let {linkProperties, behavior, content, group} = {...defaults, ...options} let method // NOTE: Remove in next major version @@ -67,13 +67,19 @@ export default function attacher(options = {}) { function around(node, url, index, parent) { const link = create(url) + const grouping = group ? toGrouping(group, node) : undefined link.data = { hProperties: toProps(linkProperties), hChildren: toChildren(content, node) } - const nodes = behavior === 'before' ? [link, node] : [node, link] + let nodes = behavior === 'before' ? [link, node] : [node, link] + + if (grouping) { + grouping.children = nodes + nodes = grouping + } splice.apply(parent.children, [index, 1].concat(nodes)) @@ -92,14 +98,36 @@ export default function attacher(options = {}) { return deepAssign({}, value) } + function toNode(value, node) { + return typeof value === 'function' ? value(node) : value + } + function toChildren(value, node) { - let children = typeof value === 'function' ? value(node) : value + let children = toNode(value, node) children = Array.isArray(children) ? children : [children] return typeof value === 'function' ? children : deepAssign([], children) } + function toGrouping(value, node) { + const grouping = toNode(value, node) + const hName = grouping.tagName + const hProperties = grouping.properties + + return { + type: 'heading-group', + data: { + hName, + hProperties: + typeof value === 'function' + ? deepAssign({}, hProperties) + : hProperties + }, + children: [] + } + } + function create(url, children) { return { type: 'link',