From 5bec9722d6d48db8b18ed2f20509477500d53153 Mon Sep 17 00:00:00 2001 From: Sana Javed Date: Fri, 21 Apr 2023 21:01:43 +0200 Subject: [PATCH 1/3] Adding anchor links --- package.json | 1 + source/helpers/components/anchors.ts | 38 ++++++++++++++++++++++++++++ source/helpers/engines.ts | 9 +++++-- yarn.lock | 11 ++++++++ 4 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 source/helpers/components/anchors.ts diff --git a/package.json b/package.json index 966faebe5..7522fd092 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "kleur": "^4.1.5", "lorem-ipsum": "^2.0.8", "markdown-it": "^13.0.1", + "markdown-it-anchor": "^8.6.7", "markdown-it-attrs": "^4.1.6", "markdown-it-deflist": "^2.1.0", "netlify-plugin-11ty": "^1.3.0", diff --git a/source/helpers/components/anchors.ts b/source/helpers/components/anchors.ts new file mode 100644 index 000000000..c1cd3d23c --- /dev/null +++ b/source/helpers/components/anchors.ts @@ -0,0 +1,38 @@ +import Token from 'markdown-it/lib/token'; +import anchor from 'markdown-it-anchor/types'; + +// Custom permalink function, inspired by and modification of linkInsideHeader +// More context on custom permalink fns: https://github.com/valeriangalliat/markdown-it-anchor#custom-permalink +// linkInsideHeader function: https://github.com/valeriangalliat/markdown-it-anchor/blob/649582d58185b00cfb2ceee9b6b4cd6aafc645b7/permalink.js#L76 +export const renderPermalink: anchor.PermalinkGenerator = ( + slug, + opts: anchor.LinkInsideHeaderPermalinkOptions, + state, + idx, +) => { + opts.ariaHidden = false; + + const title = state?.tokens[idx + 1].children + ?.filter( + (token: Token) => token.type === 'text' || token.type === 'code_inline', + ) + .reduce((acc, t) => acc + t.content, ''); + + const linkTokens = [ + Object.assign(new state.Token('link_open', 'a', 1), { + attrs: [ + ['class', 'anchor'], + ['href', `#${slug}`], + ...(opts.ariaHidden ? [['aria-hidden', 'true']] : []), + ], + }), + Object.assign(new state.Token('html_inline', '', 0), { + content: `${ + title ? title : 'section' + } permalink'`, + }), + new state.Token('link_close', 'a', -1), + ]; + + state?.tokens[idx + 1]?.children?.push(...linkTokens); +}; diff --git a/source/helpers/engines.ts b/source/helpers/engines.ts index b6fc6a884..9257b0c93 100644 --- a/source/helpers/engines.ts +++ b/source/helpers/engines.ts @@ -1,9 +1,11 @@ import { Liquid } from 'liquidjs'; -import markdown from 'markdown-it'; +import markdown, { PluginWithOptions } from 'markdown-it'; import markdownItAttrs from 'markdown-it-attrs'; import markdownDefList from 'markdown-it-deflist'; import path from 'path'; +import { renderPermalink } from './components/anchors'; + /** * Returns Markdown engine with custom configuration and plugins. * @@ -16,7 +18,10 @@ export const markdownEngine = markdown({ typographer: true, }) .use(markdownDefList) - .use(markdownItAttrs); + .use(markdownItAttrs) + .use(require('markdown-it-anchor') as PluginWithOptions, { + permalink: renderPermalink, + }); /** * Returns LiquidJS engine with custom configuration. diff --git a/yarn.lock b/yarn.lock index eff02b31d..6c074d9cc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5303,6 +5303,16 @@ __metadata: languageName: node linkType: hard +"markdown-it-anchor@npm:^8.6.7": + version: 8.6.7 + resolution: "markdown-it-anchor@npm:8.6.7" + peerDependencies: + "@types/markdown-it": "*" + markdown-it: "*" + checksum: 828236768ac7f61ed5591393c1b1bfc5dbf2b6d0c58a3deec606c61dddaa12658a34450cbef37ab50a04453e618ce1efd47d86e4e52595024334898fd306225b + languageName: node + linkType: hard + "markdown-it-attrs@npm:^4.1.6": version: 4.1.6 resolution: "markdown-it-attrs@npm:4.1.6" @@ -6758,6 +6768,7 @@ __metadata: kleur: ^4.1.5 lorem-ipsum: ^2.0.8 markdown-it: ^13.0.1 + markdown-it-anchor: ^8.6.7 markdown-it-attrs: ^4.1.6 markdown-it-deflist: ^2.1.0 netlify-plugin-11ty: ^1.3.0 From a81fc0b362f5d305845cf6f4a7b7371d31db6a9c Mon Sep 17 00:00:00 2001 From: Jonny Gerig Meyer Date: Mon, 24 Apr 2023 12:28:42 -0400 Subject: [PATCH 2/3] Fix TS error --- source/helpers/components/anchors.ts | 2 +- source/helpers/engines.ts | 5 +++-- tsconfig.json | 7 ++----- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/source/helpers/components/anchors.ts b/source/helpers/components/anchors.ts index c1cd3d23c..d1f6c285f 100644 --- a/source/helpers/components/anchors.ts +++ b/source/helpers/components/anchors.ts @@ -1,5 +1,5 @@ import Token from 'markdown-it/lib/token'; -import anchor from 'markdown-it-anchor/types'; +import type anchor from 'markdown-it-anchor'; // Custom permalink function, inspired by and modification of linkInsideHeader // More context on custom permalink fns: https://github.com/valeriangalliat/markdown-it-anchor#custom-permalink diff --git a/source/helpers/engines.ts b/source/helpers/engines.ts index 9257b0c93..213ec6999 100644 --- a/source/helpers/engines.ts +++ b/source/helpers/engines.ts @@ -1,5 +1,6 @@ import { Liquid } from 'liquidjs'; -import markdown, { PluginWithOptions } from 'markdown-it'; +import markdown from 'markdown-it'; +import markdownAnchor from 'markdown-it-anchor'; import markdownItAttrs from 'markdown-it-attrs'; import markdownDefList from 'markdown-it-deflist'; import path from 'path'; @@ -19,7 +20,7 @@ export const markdownEngine = markdown({ }) .use(markdownDefList) .use(markdownItAttrs) - .use(require('markdown-it-anchor') as PluginWithOptions, { + .use(markdownAnchor, { permalink: renderPermalink, }); diff --git a/tsconfig.json b/tsconfig.json index fccc0ee28..68cbed7d3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,15 +1,12 @@ { + "extends": "ts-node/node16/tsconfig.json", "ts-node": { "transpileOnly": true }, "compilerOptions": { - "module": "node16", "target": "es2022", - "moduleResolution": "Node16", - "strict": true, - "esModuleInterop": true, + "lib": ["es2022", "DOM"], "isolatedModules": true, - "forceConsistentCasingInFileNames": true, "noEmit": true }, "include": ["source/**/*.ts"], From 0bd3e83ccc2472c8eeaecf301cdbfa2a14072939 Mon Sep 17 00:00:00 2001 From: Jonny Gerig Meyer Date: Mon, 1 May 2023 14:01:28 -0400 Subject: [PATCH 3/3] review --- source/helpers/components/anchors.ts | 30 ++++++++++++++++++---------- source/helpers/engines.ts | 1 + 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/source/helpers/components/anchors.ts b/source/helpers/components/anchors.ts index d1f6c285f..46ff50c00 100644 --- a/source/helpers/components/anchors.ts +++ b/source/helpers/components/anchors.ts @@ -1,38 +1,46 @@ import Token from 'markdown-it/lib/token'; import type anchor from 'markdown-it-anchor'; -// Custom permalink function, inspired by and modification of linkInsideHeader -// More context on custom permalink fns: https://github.com/valeriangalliat/markdown-it-anchor#custom-permalink -// linkInsideHeader function: https://github.com/valeriangalliat/markdown-it-anchor/blob/649582d58185b00cfb2ceee9b6b4cd6aafc645b7/permalink.js#L76 +/** + * Custom permalink function, inspired by `linkInsideHeader`, + * modified to include title text in permalink a11y text. + * @see https://github.com/valeriangalliat/markdown-it-anchor#custom-permalink + * @see https://github.com/valeriangalliat/markdown-it-anchor/blob/649582d58185b00cfb2ceee9b6b4cd6aafc645b7/permalink.js#L76 + */ export const renderPermalink: anchor.PermalinkGenerator = ( slug, opts: anchor.LinkInsideHeaderPermalinkOptions, state, idx, ) => { - opts.ariaHidden = false; - - const title = state?.tokens[idx + 1].children + // https://github.com/valeriangalliat/markdown-it-anchor/blob/649582d58185b00cfb2ceee9b6b4cd6aafc645b7/permalink.js#L148-L151 + const title = state.tokens[idx + 1]?.children ?.filter( (token: Token) => token.type === 'text' || token.type === 'code_inline', ) .reduce((acc, t) => acc + t.content, ''); + opts.class = 'anchor'; + opts.ariaHidden = false; + opts.symbol = `${ + title || 'section' + } permalink`; + + // https://github.com/valeriangalliat/markdown-it-anchor/blob/649582d58185b00cfb2ceee9b6b4cd6aafc645b7/permalink.js#L77-L97 const linkTokens = [ Object.assign(new state.Token('link_open', 'a', 1), { attrs: [ - ['class', 'anchor'], + ...(opts.class ? [['class', opts.class]] : []), ['href', `#${slug}`], ...(opts.ariaHidden ? [['aria-hidden', 'true']] : []), ], }), Object.assign(new state.Token('html_inline', '', 0), { - content: `${ - title ? title : 'section' - } permalink'`, + content: opts.symbol, + meta: { isPermalinkSymbol: true }, }), new state.Token('link_close', 'a', -1), ]; - state?.tokens[idx + 1]?.children?.push(...linkTokens); + state.tokens[idx + 1]?.children?.push(...linkTokens); }; diff --git a/source/helpers/engines.ts b/source/helpers/engines.ts index 213ec6999..909db214e 100644 --- a/source/helpers/engines.ts +++ b/source/helpers/engines.ts @@ -21,6 +21,7 @@ export const markdownEngine = markdown({ .use(markdownDefList) .use(markdownItAttrs) .use(markdownAnchor, { + level: [2], permalink: renderPermalink, });