From 48554be76d4e817557deb28942d4ca37d8dadcb3 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Thu, 18 May 2023 21:04:27 +0800 Subject: [PATCH] fix: wrap link with == --- packages/api/src/utils/highlightGenerator.ts | 7 +- packages/api/src/utils/parser.ts | 79 +++++++++++++++++++- 2 files changed, 81 insertions(+), 5 deletions(-) diff --git a/packages/api/src/utils/highlightGenerator.ts b/packages/api/src/utils/highlightGenerator.ts index e9c8e05b5..9b21c14df 100644 --- a/packages/api/src/utils/highlightGenerator.ts +++ b/packages/api/src/utils/highlightGenerator.ts @@ -393,7 +393,10 @@ export function makeHighlightNodeAttributes( let startingTextNodeIndex = textNodeIndex let quote = '' - while (highlightTextEnd > textNodes[startingTextNodeIndex].startIndex) { + while ( + startingTextNodeIndex < textNodes.length && + highlightTextEnd > textNodes[startingTextNodeIndex].startIndex + ) { const { node, textPartsToHighlight, isParagraphStart } = fillHighlight({ textNodes, startingTextNodeIndex, @@ -419,7 +422,7 @@ export function makeHighlightNodeAttributes( isParagraphStart && !i && quote && (quote += '\n') quote += text } - + console.log('quote', quote) const newHighlightSpan = document.createElement('span') newHighlightSpan.setAttribute(highlightIdAttribute, id) newHighlightSpan.appendChild(newTextNode) diff --git a/packages/api/src/utils/parser.ts b/packages/api/src/utils/parser.ts index a8df379ba..5e9a83969 100644 --- a/packages/api/src/utils/parser.ts +++ b/packages/api/src/utils/parser.ts @@ -11,6 +11,7 @@ import { decode } from 'html-entities' import * as jwt from 'jsonwebtoken' import { parseHTML } from 'linkedom' import { NodeHtmlMarkdown, TranslatorConfigObject } from 'node-html-markdown' +import { ElementNode } from 'node-html-markdown/dist/nodes' import { ILike } from 'typeorm' import { promisify } from 'util' import { v4 as uuid } from 'uuid' @@ -494,14 +495,86 @@ export const fetchFavicon = async ( // custom transformer to wrap tags in markdown highlight tags `==` export const highlightTranslators: TranslatorConfigObject = { + /* Link */ + a: ({ node, options, visitor }) => { + const href = node.getAttribute('href') + if (!href) return {} + + // Encodes symbols that can cause problems in markdown + let encodedHref = '' + for (const chr of href) { + switch (chr) { + case '(': + encodedHref += '%28' + break + case ')': + encodedHref += '%29' + break + case '_': + encodedHref += '%5F' + break + case '*': + encodedHref += '%2A' + break + default: + encodedHref += chr + } + } + + const title = node.getAttribute('title') + + let hasHighlight = false + // If the link is a highlight, wrap it in `==` tags + node.childNodes.forEach((child) => { + if ( + child.nodeType === 1 && + (child as ElementNode).getAttribute(highlightIdAttribute) + ) { + hasHighlight = true + return + } + }) + + // Inline link, when possible + // See: https://github.com/crosstype/node-html-markdown/issues/17 + if (node.textContent === href && options.useInlineLinks) + return { + prefix: hasHighlight ? '==' : undefined, + postfix: hasHighlight ? '==' : undefined, + content: `<${encodedHref}>`, + } + + const prefix = hasHighlight ? '==[' : '[' + const postfix = + ']' + + (!options.useLinkReferenceDefinitions + ? `(${encodedHref}${title ? ` "${title}"` : ''})` + : `[${visitor.addOrGetUrlDefinition(encodedHref)}]`) + + `${hasHighlight ? '==' : ''}` + + return { + postprocess: ({ content }) => content.replace(/(?:\r?\n)+/g, ' '), + childTranslators: visitor.instance.aTagTranslators, + prefix, + postfix, + } + }, + span: ({ node }) => { const id = node.getAttribute(highlightIdAttribute) if (!id) return {} + const hasLeadingSpace = node.innerHTML.startsWith(' ') + const hasTrailingSpace = node.innerHTML.endsWith(' ') + // remove the leading and trailing space + const content = node.innerHTML.trim() + const prefix = hasLeadingSpace ? ' ==' : '==' + const postfix = hasTrailingSpace ? '== ' : '==' + return { - prefix: '==', - postfix: '==', - content: node.innerHTML.trim(), + prefix, + postfix, + content, } }, }