From c1a8ca7222ec24c2b71f156d40c4b8f6f5950c8c Mon Sep 17 00:00:00 2001 From: Mateusz Filipowicz Date: Sun, 7 Jun 2020 01:01:19 +0200 Subject: [PATCH] fix(toc): :bug: fix issue with table of contents not following properly Sections generated by gatsby-remark-sectionize were nested, while spying nested sections is unsupported by react-scrollspy. Thus needed to fork remark-sectionize plugin and change it to take into account ToC depth. --- gatsby-config.js | 7 +++- plugins/gatsby-remark-sectionize-toc/index.js | 8 ++++ .../gatsby-remark-sectionize-toc/package.json | 11 +++++ .../sectionize-toc.js | 42 +++++++++++++++++++ src/components/tableOfContents/index.js | 1 - 5 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 plugins/gatsby-remark-sectionize-toc/index.js create mode 100644 plugins/gatsby-remark-sectionize-toc/package.json create mode 100644 plugins/gatsby-remark-sectionize-toc/sectionize-toc.js diff --git a/gatsby-config.js b/gatsby-config.js index d72aaf33..5e67f5cd 100755 --- a/gatsby-config.js +++ b/gatsby-config.js @@ -70,7 +70,12 @@ const plugins = [ }, }, 'gatsby-remark-graphviz', - 'gatsby-remark-sectionize', + { + resolve: require.resolve(`./plugins/gatsby-remark-sectionize-toc`), + options: { + maxDepth: config.features.toc.depth + } + }, { resolve: 'gatsby-remark-images', options: { diff --git a/plugins/gatsby-remark-sectionize-toc/index.js b/plugins/gatsby-remark-sectionize-toc/index.js new file mode 100644 index 00000000..96b3d8d5 --- /dev/null +++ b/plugins/gatsby-remark-sectionize-toc/index.js @@ -0,0 +1,8 @@ +const sectionizeToc = require('./sectionize-toc'); + +const transform = sectionizeToc(); + +module.exports = function ({ markdownAST }, pluginOptions ) { + transform(markdownAST, pluginOptions.maxDepth); +}; + \ No newline at end of file diff --git a/plugins/gatsby-remark-sectionize-toc/package.json b/plugins/gatsby-remark-sectionize-toc/package.json new file mode 100644 index 00000000..6519b98e --- /dev/null +++ b/plugins/gatsby-remark-sectionize-toc/package.json @@ -0,0 +1,11 @@ +{ + "name": "gatsby-remark-sectionize-toc", + "description": "Forked sectionize plugin used to generate sections to make react-scrollspy work with Table of Contents", + "author": "Mateusz Filipowicz ", + "version": "0.1.0", + "dependencies": { + "remark": "^12.0.0" + }, + "license": "MIT", + "main": "index.js" +} diff --git a/plugins/gatsby-remark-sectionize-toc/sectionize-toc.js b/plugins/gatsby-remark-sectionize-toc/sectionize-toc.js new file mode 100644 index 00000000..5f9339ad --- /dev/null +++ b/plugins/gatsby-remark-sectionize-toc/sectionize-toc.js @@ -0,0 +1,42 @@ +const findAfter = require('unist-util-find-after'); +const visit = require('unist-util-visit-parents'); + +const MAX_HEADING_DEPTH = 6; + +module.exports = () => transform; + +const transform = (tree, maxDepth) => { + const maxTocDepth = maxDepth ? maxDepth : MAX_HEADING_DEPTH; + const visitFunction = sectionize(maxTocDepth); + for (let depth = MAX_HEADING_DEPTH; depth > 0; depth--) { + visit(tree, (node) => node.type === 'heading' && node.depth === depth, visitFunction); + } +}; +const sectionize = (maxTocDepth) => { + return (node, ancestors) => { + const start = node; + const depth = start.depth; + const parent = ancestors[ancestors.length - 1]; + + const isEnd = (node) => + (node.type === 'heading' && node.depth <= depth) || + (node.type === 'section' && node.depth > depth && node.depth <= maxTocDepth) || + node.type === 'export'; + const end = findAfter(parent, start, isEnd); + + const startIndex = parent.children.indexOf(start); + const endIndex = parent.children.indexOf(end); + + const between = parent.children.slice(startIndex, endIndex > 0 ? endIndex : undefined); + + const section = { + type: 'section', + depth: depth, + children: between, + data: { + hName: 'section', + }, + }; + parent.children.splice(startIndex, section.children.length, section); + }; +}; diff --git a/src/components/tableOfContents/index.js b/src/components/tableOfContents/index.js index af91980c..79b1e46a 100644 --- a/src/components/tableOfContents/index.js +++ b/src/components/tableOfContents/index.js @@ -45,7 +45,6 @@ const Sidebar = styled.aside` } .currentItem { a { - padding-left: 13px !important; border-left: 2px solid ${(props) => props.theme.tableOfContents.font.current} !important; color: ${(props) => props.theme.tableOfContents.font.current} !important; }