From a75b0e4a0761c0f322d2a14951150ce7fa1d9472 Mon Sep 17 00:00:00 2001 From: harish-sethuraman Date: Sun, 6 Feb 2022 12:51:01 +0530 Subject: [PATCH 1/2] Generate Ids when there are no headings --- beta/plugins/remark-header-custom-ids.js | 54 ++++++++++++++++-------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/beta/plugins/remark-header-custom-ids.js b/beta/plugins/remark-header-custom-ids.js index bf51e98e097..952eedf67b1 100644 --- a/beta/plugins/remark-header-custom-ids.js +++ b/beta/plugins/remark-header-custom-ids.js @@ -31,33 +31,51 @@ module.exports = ({ return function transformer(tree) { visit(tree, 'heading', (node) => { const children = node.children; + const rawHeader = toString(node); + const match = /^.+(\s*\{.*\}\s*)$/u.exec(rawHeader); + /** + * we check if there is a heading and custom id with regex. + * If there is a match then we set the id to be the match[1] which is the custom id + * else we have to generate id + */ + let id = + match && match.length === 2 + ? match[1] + : slugs.slug(rawHeader, maintainCase); + let tail = children[children.length - 1]; - // A bit weird: this is to support MDX 2 comments in expressions, - // while we’re still on MDX 1, which doesn’t support them. - if (!tail || tail.type !== 'text' || tail.value !== '/}') { - return; - } + /** + * If there was a match then we might want to return when they dont have proper heading ids + * Else we generate ids + */ + if (match) { + if (!tail || tail.type !== 'text' || tail.value !== '/}') { + return; + } - tail = children[children.length - 2]; + tail = children[children.length - 2]; - if (!tail && tail.type !== 'emphasis') { - return; - } + if (!tail && tail.type !== 'emphasis') { + return; + } - const id = toString(tail); + id = toString(tail); - tail = children[children.length - 3]; + tail = children[children.length - 3]; - if (!tail || tail.type !== 'text' || !tail.value.endsWith('{/')) { - return; + if (!tail || tail.type !== 'text' || !tail.value.endsWith('{/')) { + return; + } + /** + * We have to splice the children only if they contain heading ids + */ + // Remove the emphasis and trailing `/}` + children.splice(children.length - 2, 2); + // Remove the `{/` + tail.value = tail.value.replace(/[ \t]*\{\/$/, ''); } - // Remove the emphasis and trailing `/}` - children.splice(children.length - 2, 2); - // Remove the `{/` - tail.value = tail.value.replace(/[ \t]*\{\/$/, ''); - const data = patch(node, 'data', {}); patch(data, 'id', id); From e41614fe10cb0e914919593fb8722a13f067abc8 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Mon, 7 Feb 2022 19:00:43 +0000 Subject: [PATCH 2/2] Tweak code --- beta/plugins/remark-header-custom-ids.js | 56 +++++++----------------- 1 file changed, 16 insertions(+), 40 deletions(-) diff --git a/beta/plugins/remark-header-custom-ids.js b/beta/plugins/remark-header-custom-ids.js index 952eedf67b1..327e266c462 100644 --- a/beta/plugins/remark-header-custom-ids.js +++ b/beta/plugins/remark-header-custom-ids.js @@ -31,49 +31,25 @@ module.exports = ({ return function transformer(tree) { visit(tree, 'heading', (node) => { const children = node.children; - const rawHeader = toString(node); - const match = /^.+(\s*\{.*\}\s*)$/u.exec(rawHeader); - /** - * we check if there is a heading and custom id with regex. - * If there is a match then we set the id to be the match[1] which is the custom id - * else we have to generate id - */ - let id = - match && match.length === 2 - ? match[1] - : slugs.slug(rawHeader, maintainCase); - let tail = children[children.length - 1]; - - /** - * If there was a match then we might want to return when they dont have proper heading ids - * Else we generate ids - */ - if (match) { - if (!tail || tail.type !== 'text' || tail.value !== '/}') { - return; - } - + // Generate slugs on the fly (even if not specified in markdown) + // so that it's possible to copy anchor links in newly written content. + let id = slugs.slug(toString(node), maintainCase); + // However, for committed docs, we'll extract slug from the headers. + if (tail && tail.type === 'text' && tail.value === '/}') { tail = children[children.length - 2]; - - if (!tail && tail.type !== 'emphasis') { - return; - } - - id = toString(tail); - - tail = children[children.length - 3]; - - if (!tail || tail.type !== 'text' || !tail.value.endsWith('{/')) { - return; + if (tail && tail.type === 'emphasis') { + // Use custom ID instead. + id = toString(tail); + // Until we're on MDX 2, we need to "cut off" the comment syntax. + tail = children[children.length - 3]; + if (tail && tail.type === 'text' && tail.value.endsWith('{/')) { + // Remove the emphasis and trailing `/}` + children.splice(children.length - 2, 2); + // Remove the `{/` + tail.value = tail.value.replace(/[ \t]*\{\/$/, ''); + } } - /** - * We have to splice the children only if they contain heading ids - */ - // Remove the emphasis and trailing `/}` - children.splice(children.length - 2, 2); - // Remove the `{/` - tail.value = tail.value.replace(/[ \t]*\{\/$/, ''); } const data = patch(node, 'data', {});