diff --git a/packages/gatsby-transformer-remark/src/__tests__/__snapshots__/extend-node.js.snap b/packages/gatsby-transformer-remark/src/__tests__/__snapshots__/extend-node.js.snap index 824fd17e28055..07927c69c3a1b 100644 --- a/packages/gatsby-transformer-remark/src/__tests__/__snapshots__/extend-node.js.snap +++ b/packages/gatsby-transformer-remark/src/__tests__/__snapshots__/extend-node.js.snap @@ -523,6 +523,40 @@ Object { } `; +exports[`Headings are generated correctly from schema returns id if heading has one 1`] = ` +Object { + "headings": Array [ + Object { + "depth": 1, + "id": "first-title", + "value": "first title", + }, + Object { + "depth": 2, + "id": "second-title", + "value": "second title", + }, + ], +} +`; + +exports[`Headings are generated correctly from schema returns null id if heading has no id 1`] = ` +Object { + "headings": Array [ + Object { + "depth": 1, + "id": null, + "value": "first title", + }, + Object { + "depth": 2, + "id": null, + "value": "second title", + }, + ], +} +`; + exports[`Headings are generated correctly from schema returns value 1`] = ` Object { "headings": Array [ diff --git a/packages/gatsby-transformer-remark/src/__tests__/extend-node.js b/packages/gatsby-transformer-remark/src/__tests__/extend-node.js index 5e57617d6faf2..0bdce94709ff1 100644 --- a/packages/gatsby-transformer-remark/src/__tests__/extend-node.js +++ b/packages/gatsby-transformer-remark/src/__tests__/extend-node.js @@ -1266,6 +1266,77 @@ describe(`Headings are generated correctly from schema`, () => { } ) + bootstrapTest( + `returns null id if heading has no id`, + ` + # first title + + ## second title + `, + `headings { + id + value + depth + }`, + node => { + expect(node).toMatchSnapshot() + expect(node.headings).toEqual([ + { + id: null, + value: `first title`, + depth: 1, + }, + { + id: null, + value: `second title`, + depth: 2, + }, + ]) + } + ) + + bootstrapTest( + `returns id if heading has one`, + ` + # first title + + ## second title + `, + `headings { + id + value + depth + }`, + node => { + expect(node).toMatchSnapshot() + expect(node.headings).toEqual([ + { + id: `first-title`, + value: `first title`, + depth: 1, + }, + { + id: `second-title`, + value: `second title`, + depth: 2, + }, + ]) + }, + { + pluginOptions: { + plugins: [ + // to pass subplugin we need to use object with `resolve` and `pluginOptions` + // (this is what gatsby core internally turns plugin entries to + gatsby core always set empty object {} + // if options were not provided and lot of plugins rely on this and are not checking for options existence) + { + resolve: require.resolve(`gatsby-remark-autolink-headers/src`), + pluginOptions: {}, + }, + ], + }, + } + ) + bootstrapTest( `returns value with inlineCode`, ` diff --git a/packages/gatsby-transformer-remark/src/create-schema-customization.js b/packages/gatsby-transformer-remark/src/create-schema-customization.js index efa316d2317b6..2c1c16f03443f 100644 --- a/packages/gatsby-transformer-remark/src/create-schema-customization.js +++ b/packages/gatsby-transformer-remark/src/create-schema-customization.js @@ -1,5 +1,6 @@ const typeDefs = ` type MarkdownHeading { + id: String value: String depth: Int } diff --git a/packages/gatsby-transformer-remark/src/extend-node-type.js b/packages/gatsby-transformer-remark/src/extend-node-type.js index b4f1d5449e43c..ba9bfa165f9d7 100644 --- a/packages/gatsby-transformer-remark/src/extend-node-type.js +++ b/packages/gatsby-transformer-remark/src/extend-node-type.js @@ -21,6 +21,7 @@ const { findLastTextNode, } = require(`./hast-processing`) const codeHandler = require(`./code-handler`) +const { getHeadingID } = require(`./utils/get-heading-id`) const { timeToRead } = require(`./utils/time-to-read`) let fileNodes @@ -271,6 +272,7 @@ module.exports = ( const ast = await getAST(markdownNode) const headings = select(ast, `heading`).map(heading => { return { + id: getHeadingID(heading), value: mdastToString(heading), depth: heading.depth, } diff --git a/packages/gatsby-transformer-remark/src/utils/get-heading-id.js b/packages/gatsby-transformer-remark/src/utils/get-heading-id.js new file mode 100644 index 0000000000000..7c7e1ef6e5563 --- /dev/null +++ b/packages/gatsby-transformer-remark/src/utils/get-heading-id.js @@ -0,0 +1,15 @@ +export const getHeadingID = heading => { + const data = heading.data + if (data) { + if (data.id) return data.id + if (data.htmlAttributes && data.htmlAttributes.id) { + return data.htmlAttributes.id + } + + if (data.hProperties && data.hProperties.id) { + return data.hProperties.id + } + } + + return null +}