From 28ec546eec5fb713bdbf67f9d65812c2fe8ecc00 Mon Sep 17 00:00:00 2001 From: Jordan Stapinski Date: Fri, 26 Mar 2021 14:21:23 -0400 Subject: [PATCH] DEVHUB-545: Add Headings to TOC --- src/templates/strapi-article.js | 10 +++++++-- src/utils/find-section-headings.js | 10 +++++++-- src/utils/setup/parse-markdown-to-ast.js | 27 ++++++++++++++++++------ 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/templates/strapi-article.js b/src/templates/strapi-article.js index 7c011d2bb..067cb3090 100644 --- a/src/templates/strapi-article.js +++ b/src/templates/strapi-article.js @@ -18,6 +18,7 @@ import ShareMenu from '../components/dev-hub/share-menu'; import ContentsMenu from '../components/dev-hub/contents-menu'; import { addTrailingSlashIfMissing } from '../utils/add-trailing-slash-if-missing'; import ArticleSchema from '../components/dev-hub/article-schema'; +import { findSectionHeadings } from '../utils/find-section-headings'; const dateFormatOptions = { month: 'short', @@ -104,8 +105,13 @@ const StrapiArticle = props => { } const tagList = getTagLinksFromMeta({ tags, products, languages }); const articleUrl = addTrailingSlashIfMissing(`${siteUrl}${slug}`); - // TODO: Fill in - const headingNodes = []; + const headingNodes = findSectionHeadings( + childNodes, + 'type', + 'heading', + 1, + -1 + ); const formattedPublishedDate = toDateString( published_at, dateFormatOptions diff --git a/src/utils/find-section-headings.js b/src/utils/find-section-headings.js index b635f825d..53d4cb8d3 100644 --- a/src/utils/find-section-headings.js +++ b/src/utils/find-section-headings.js @@ -1,10 +1,16 @@ -export const findSectionHeadings = (nodes, key, value, maxDepth) => { +export const findSectionHeadings = ( + nodes, + key, + value, + maxDepth, + minDepth = 1 +) => { const results = []; const searchNode = (node, sectionDepth) => { if ( node[key] === value && sectionDepth - 1 <= maxDepth && - sectionDepth > 1 + sectionDepth > minDepth ) { const nodeTitle = node.children; const newNode = { diff --git a/src/utils/setup/parse-markdown-to-ast.js b/src/utils/setup/parse-markdown-to-ast.js index d40a38368..1584840f8 100644 --- a/src/utils/setup/parse-markdown-to-ast.js +++ b/src/utils/setup/parse-markdown-to-ast.js @@ -2,6 +2,8 @@ import remark from 'remark'; import directive from 'remark-directive'; import gfm from 'remark-gfm'; import visit from 'unist-util-visit'; +import { getNestedText } from '../get-nested-text'; +import { getTagPageUriComponent } from '../get-tag-page-uri-component'; export const parseMarkdownToAST = markdown => { const result = remark().use(gfm).use(directive).parse(markdown); @@ -9,17 +11,30 @@ export const parseMarkdownToAST = markdown => { function transform(tree) { visit( tree, - ['textDirective', 'leafDirective', 'containerDirective'], + ['heading', 'textDirective', 'leafDirective', 'containerDirective'], ondirective ); } function ondirective(node) { - var data = node.data || (node.data = {}); - node['argument'] = [{ value: node.attributes.vid }]; - data['name'] = node.name; - node.type = node.name; - node.nodeData = data; + const data = node.data || (node.data = {}); + switch (node.type) { + case 'heading': + node['id'] = getTagPageUriComponent( + getNestedText(node['children']) + ); + break; + case 'textDirective': + // Custom directive definitions go here + // Right now, this is just YouTube + node['argument'] = [{ value: node.attributes.vid }]; + data['name'] = node.name; + node.type = node.name; + node.nodeData = data; + break; + default: + break; + } } transform(result); return result;