From bfe42bc9adc29d6d56e36c8ef71c3948a934552c Mon Sep 17 00:00:00 2001 From: hvarany Date: Fri, 21 Jul 2023 12:54:05 +0400 Subject: [PATCH] feat(docs): Add functions for generating header IDs and anchor links This commit adds the `generateHeadersIds` and `generateAnchors` functions to the MDRenderer class. These functions are responsible for generating header IDs and anchor links in the rendered markdown content. --- pages/11ty/markdown.shortcut.js | 38 +++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/pages/11ty/markdown.shortcut.js b/pages/11ty/markdown.shortcut.js index 536e89654..8a9cfac7e 100644 --- a/pages/11ty/markdown.shortcut.js +++ b/pages/11ty/markdown.shortcut.js @@ -27,6 +27,9 @@ class MDRenderer { endAnchorElement.remove(); } + //Add headers ids + MDRenderer.generateHeadersIds(window.document.body); + // Resolve content links MDRenderer.resolveLinks(window.document.body, filePath); @@ -71,6 +74,41 @@ class MDRenderer { } return github.srcUrl + linkPath; } + + static generateHeadersIds(content) { + const headerTags = ['h1', 'h2', 'h3', 'h4']; + const idLengthLimit = 20; + + headerTags.forEach(tag => { + const headers = content.getElementsByTagName(tag); + + for (let header of headers) { + const text = header.textContent; + const id = text + .replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => (index === 0 ? word.toLowerCase() : word.toUpperCase())) + .replace(/[^\w\s]|_/g, "").replace(/\s+/g, "") + .substring(0, idLengthLimit); + + header.setAttribute('id', id); + + this.generateAnchors(content, text, `#${id}`) + } + }); + return content; + } + + static generateAnchors(content, text, link) { + const matches = Array.from(content.querySelectorAll('*')) + .filter(element => element.textContent.includes(text) || element.textContent.includes(text.replace(/_/g, " "))); + const regex = new RegExp(`(^|\\s)${text}(\\s|[,\\.])`, 'g'); + + matches.forEach(match => { + if (!['H1', 'H2', 'H3', 'H4', 'H5', 'H6'].includes(match.tagName)) { + match.innerHTML = match.innerHTML.replace(regex, `$1${text}$2`); + } + }); + } + } module.exports = (config) => {