Skip to content

Commit

Permalink
feat(gatsby-remark-autolink-headers): add option to maintain case (#9313
Browse files Browse the repository at this point in the history
)

The remark-autolink-headers plugin creates lowercase ids by default. Adding an option to maintain the case for markdown headers

Use case: You want the url to have the same case as the function name.

example: https://reactjs.org/docs/react-component.html# **componentDidMount**

- [x] Added optional configuration to the API
- [x] Added a test
- [x] Added documentation in README
  • Loading branch information
siddharthkp authored and pieh committed Oct 23, 2018
1 parent ba82bc4 commit 4265ff3
Show file tree
Hide file tree
Showing 4 changed files with 221 additions and 2 deletions.
2 changes: 2 additions & 0 deletions packages/gatsby-remark-autolink-headers/README.md
Expand Up @@ -55,6 +55,7 @@ Note: if you are using `gatsby-remark-prismjs`, make sure that it’s listed aft
- `offsetY`: Signed integer. Vertical offset value in pixels (optional)
- `icon`: SVG shape inside a template literal or boolean `false`. Set your own svg or disable icon (optional)
- `className`: String. Set your own class for the anchor (optional)
- `maintainCase`: Boolean. Maintains the case for markdown header (optional)

```javascript
// In your gatsby-config.js
Expand All @@ -70,6 +71,7 @@ module.exports = {
offsetY: `100`,
icon: `<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>`,
className: `custom-class`,
maintainCase: true,
},
},
],
Expand Down
Expand Up @@ -242,3 +242,198 @@ Object {
"type": "heading",
}
`;

exports[`gatsby-remark-autolink-headers maintain case of markdown header for id 1`] = `
Object {
"children": Array [
Object {
"data": Object {
"hChildren": Array [
Object {
"type": "raw",
"value": "<svg aria-hidden=\\"true\\" height=\\"16\\" version=\\"1.1\\" viewBox=\\"0 0 16 16\\" width=\\"16\\"><path fill-rule=\\"evenodd\\" d=\\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\\"></path></svg>",
},
],
"hProperties": Object {
"aria-hidden": true,
"class": "anchor",
},
},
"title": null,
"type": "link",
"url": "#Heading-One",
},
Object {
"position": Position {
"end": Object {
"column": 14,
"line": 2,
"offset": 14,
},
"indent": Array [],
"start": Object {
"column": 3,
"line": 2,
"offset": 3,
},
},
"type": "text",
"value": "Heading One",
},
],
"data": Object {
"hProperties": Object {
"id": "Heading-One",
},
"htmlAttributes": Object {
"id": "Heading-One",
},
"id": "Heading-One",
},
"depth": 1,
"position": Position {
"end": Object {
"column": 14,
"line": 2,
"offset": 14,
},
"indent": Array [],
"start": Object {
"column": 1,
"line": 2,
"offset": 1,
},
},
"type": "heading",
}
`;

exports[`gatsby-remark-autolink-headers maintain case of markdown header for id 2`] = `
Object {
"children": Array [
Object {
"data": Object {
"hChildren": Array [
Object {
"type": "raw",
"value": "<svg aria-hidden=\\"true\\" height=\\"16\\" version=\\"1.1\\" viewBox=\\"0 0 16 16\\" width=\\"16\\"><path fill-rule=\\"evenodd\\" d=\\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\\"></path></svg>",
},
],
"hProperties": Object {
"aria-hidden": true,
"class": "anchor",
},
},
"title": null,
"type": "link",
"url": "#Heading-Two",
},
Object {
"position": Position {
"end": Object {
"column": 15,
"line": 4,
"offset": 30,
},
"indent": Array [],
"start": Object {
"column": 4,
"line": 4,
"offset": 19,
},
},
"type": "text",
"value": "Heading Two",
},
],
"data": Object {
"hProperties": Object {
"id": "Heading-Two",
},
"htmlAttributes": Object {
"id": "Heading-Two",
},
"id": "Heading-Two",
},
"depth": 2,
"position": Position {
"end": Object {
"column": 15,
"line": 4,
"offset": 30,
},
"indent": Array [],
"start": Object {
"column": 1,
"line": 4,
"offset": 16,
},
},
"type": "heading",
}
`;

exports[`gatsby-remark-autolink-headers maintain case of markdown header for id 3`] = `
Object {
"children": Array [
Object {
"data": Object {
"hChildren": Array [
Object {
"type": "raw",
"value": "<svg aria-hidden=\\"true\\" height=\\"16\\" version=\\"1.1\\" viewBox=\\"0 0 16 16\\" width=\\"16\\"><path fill-rule=\\"evenodd\\" d=\\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\\"></path></svg>",
},
],
"hProperties": Object {
"aria-hidden": true,
"class": "anchor",
},
},
"title": null,
"type": "link",
"url": "#Heading-Three",
},
Object {
"position": Position {
"end": Object {
"column": 18,
"line": 6,
"offset": 49,
},
"indent": Array [],
"start": Object {
"column": 5,
"line": 6,
"offset": 36,
},
},
"type": "text",
"value": "Heading Three",
},
],
"data": Object {
"hProperties": Object {
"id": "Heading-Three",
},
"htmlAttributes": Object {
"id": "Heading-Three",
},
"id": "Heading-Three",
},
"depth": 3,
"position": Position {
"end": Object {
"column": 18,
"line": 6,
"offset": 49,
},
"indent": Array [],
"start": Object {
"column": 1,
"line": 6,
"offset": 32,
},
},
"type": "heading",
}
`;
19 changes: 19 additions & 0 deletions packages/gatsby-remark-autolink-headers/src/__tests__/index.js
Expand Up @@ -127,4 +127,23 @@ describe(`gatsby-remark-autolink-headers`, () => {
expect(node.data.id).toBeDefined()
})
})

it(`maintain case of markdown header for id`, () => {
const markdownAST = remark.parse(`
# Heading One
## Heading Two
### Heading Three
`)
const maintainCase = true

const transformed = plugin({ markdownAST }, { maintainCase })

visit(transformed, `heading`, node => {
expect(node.data.id).toBeDefined()

expect(node).toMatchSnapshot()
})
})
})
7 changes: 5 additions & 2 deletions packages/gatsby-remark-autolink-headers/src/index.js
Expand Up @@ -12,11 +12,14 @@ function patch(context, key, value) {

const svgIcon = `<svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>`

module.exports = ({ markdownAST }, { icon = svgIcon, className = `anchor` }) => {
module.exports = (
{ markdownAST },
{ icon = svgIcon, className = `anchor`, maintainCase = false }
) => {
slugs.reset()

visit(markdownAST, `heading`, node => {
const id = slugs.slug(toString(node))
const id = slugs.slug(toString(node), maintainCase)
const data = patch(node, `data`, {})

patch(data, `id`, id)
Expand Down

0 comments on commit 4265ff3

Please sign in to comment.