From d32d9c62eb1ff6873c0a1e07d54f198b21cb6042 Mon Sep 17 00:00:00 2001 From: Lim Chee Aun Date: Mon, 12 Dec 2022 21:51:59 +0800 Subject: [PATCH] Style backtick inline codes The tree walker code is generated via Copilot, hope it works --- src/components/status.css | 3 ++ src/utils/enhance-content.js | 88 +++++++++++++++++++++++++++++------- 2 files changed, 75 insertions(+), 16 deletions(-) diff --git a/src/components/status.css b/src/components/status.css index c4906fb..ea2db46 100644 --- a/src/components/status.css +++ b/src/components/status.css @@ -173,6 +173,9 @@ .status .content p:last-child { margin-block-end: 0; } +.status .content p code { + color: var(--green-color); +} .status .content .invisible { display: none; } diff --git a/src/utils/enhance-content.js b/src/utils/enhance-content.js index c048bbb..d94d43c 100644 --- a/src/utils/enhance-content.js +++ b/src/utils/enhance-content.js @@ -20,22 +20,78 @@ export default (content, opts = {}) => { // 3. Code blocks // Check for

with markdown-like content "```" - const blocks = Array.from(dom.querySelectorAll('p')).filter((p) => - /^```[^]+```$/g.test(p.innerText.trim()), - ); - blocks.forEach((block) => { - const pre = document.createElement('pre'); - const code = document.createElement('code'); - const breaks = block.querySelectorAll('br'); - breaks.forEach((br) => br.replaceWith('\n')); - code.innerHTML = block.innerText - .trim() - // .replace(/^```/g, '') - // .replace(/```$/g, '') - .replace(/^[\n\r]+/, ''); - pre.appendChild(code); - block.replaceWith(pre); - }); + { + const blocks = Array.from(dom.querySelectorAll('p')).filter((p) => + /^```[^]+```$/g.test(p.innerText.trim()), + ); + blocks.forEach((block) => { + const pre = document.createElement('pre'); + const code = document.createElement('code'); + const breaks = block.querySelectorAll('br'); + breaks.forEach((br) => br.replaceWith('\n')); + code.innerHTML = block.innerText + .trim() + // .replace(/^```/g, '') + // .replace(/```$/g, '') + .replace(/^[\n\r]+/, ''); + pre.appendChild(code); + block.replaceWith(pre); + }); + } + + // 4. Inline code + { + // Get all text nodes in the DOM + const textNodes = []; + const walk = document.createTreeWalker( + dom, + NodeFilter.SHOW_TEXT, + null, + false, + ); + let node; + while ((node = walk.nextNode())) { + // Only get text that contains markdown-like code syntax + if (/`[^]+`/g.test(node.nodeValue)) { + textNodes.push(node); + } + } + if (textNodes.length) { + // - Split text nodes into array of text and DOM nodes + // - Replace markdown-like code syntax with element + // - Apply them all back to parent node + textNodes.forEach((node) => { + const parent = node.parentNode; + const text = node.nodeValue; + const nodes = []; + let i = 0; + let j = 0; + let k = 0; + while ((i = text.indexOf('`', j)) !== -1) { + if (i > j) { + nodes.push(document.createTextNode(text.substring(j, i))); + } + j = i + 1; + if ((k = text.indexOf('`', j)) === -1) { + k = j; + } + if (j < k) { + const code = document.createElement('code'); + code.appendChild(document.createTextNode(text.substring(j, k))); + nodes.push(document.createTextNode('`')); + nodes.push(code); + nodes.push(document.createTextNode('`')); + } + j = k + 1; + } + if (j < text.length) { + nodes.push(document.createTextNode(text.substring(j))); + } + nodes.forEach((n) => parent.insertBefore(n, node)); + parent.removeChild(node); + }); + } + } if (postEnhanceDOM) { postEnhanceDOM(dom); // mutate dom