From 3a212288e98886e1b9fedf2e31b0685deb22b370 Mon Sep 17 00:00:00 2001 From: sxjeru Date: Tue, 6 Aug 2024 21:34:00 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fix:=20Handling=20invalid=20Mark?= =?UTF-8?q?down=20bold=20(#190)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update utils.ts * Update index.tsx * Update utils.ts * Create utils.test.ts * Update index.tsx * Update type.ts * Update type.ts * Update utils.ts * Update utils.ts --------- Co-authored-by: CanisMinor --- src/Markdown/index.tsx | 8 ++++---- src/Markdown/utils.test.ts | 32 ++++++++++++++++++++++++++++++++ src/Markdown/utils.ts | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 src/Markdown/utils.test.ts diff --git a/src/Markdown/index.tsx b/src/Markdown/index.tsx index 24a7bb3e..9b8d9e1d 100644 --- a/src/Markdown/index.tsx +++ b/src/Markdown/index.tsx @@ -21,7 +21,7 @@ import { CodeFullFeatured, CodeLite } from './CodeBlock'; import type { TypographyProps } from './Typography'; import { useStyles as useMarkdownStyles } from './markdown.style'; import { useStyles } from './style'; -import { escapeBrackets, escapeMhchem } from './utils'; +import { escapeBrackets, escapeMhchem, fixMarkdownBold } from './utils'; export interface MarkdownProps extends TypographyProps { allowHtml?: boolean; @@ -62,10 +62,10 @@ const Markdown = memo( const { cx, styles } = useStyles({ fontSize, headerMultiple, lineHeight, marginMultiple }); const { styles: mdStyles } = useMarkdownStyles({ fontSize, headerMultiple, marginMultiple }); const isChatMode = variant === 'chat'; - + const escapedContent = useMemo(() => { - if (!enableLatex) return children; - return escapeMhchem(escapeBrackets(children)); + if (!enableLatex) return fixMarkdownBold(children); + return fixMarkdownBold(escapeMhchem(escapeBrackets(children))); }, [children, enableLatex]); const components: Components = useMemo( diff --git a/src/Markdown/utils.test.ts b/src/Markdown/utils.test.ts new file mode 100644 index 00000000..eb6d6dd3 --- /dev/null +++ b/src/Markdown/utils.test.ts @@ -0,0 +1,32 @@ +import { describe, expect, it } from 'vitest'; +import { fixMarkdownBold } from './utils'; + +describe('fixMarkdownBold', () => { + it('should add space after closing bold markers if needed', () => { + expect(fixMarkdownBold('**123:**456')).toBe('**123:** 456'); + expect(fixMarkdownBold('**bold text**')).toBe('**bold text**'); + expect(fixMarkdownBold('**bold text** and more')).toBe('**bold text** and more'); + expect(fixMarkdownBold('**123**456')).toBe('**123**456'); + }); + + it('should handle multiple bold sections', () => { + expect(fixMarkdownBold('**bold1** **bold2**')).toBe('**bold1** **bold2**'); + expect(fixMarkdownBold('**123:**456**789:**123')).toBe('**123:** 456**789:** 123'); + }); + + it('should not affect text without bold markers', () => { + expect(fixMarkdownBold('normal text')).toBe('normal text'); + }); + + it('should not affect empty strings', () => { + expect(fixMarkdownBold('')).toBe(''); + }); + + it('should handle odd number of asterisks', () => { + expect(fixMarkdownBold('*text* *')).toBe('*text* *'); + }); + + it('should handle asterisks within words', () => { + expect(fixMarkdownBold('t*e*st')).toBe('t*e*st'); + }); +}); diff --git a/src/Markdown/utils.ts b/src/Markdown/utils.ts index 0dc7479c..7010997c 100644 --- a/src/Markdown/utils.ts +++ b/src/Markdown/utils.ts @@ -15,3 +15,38 @@ export function escapeBrackets(text: string) { export function escapeMhchem(text: string) { return text.replaceAll('$\\ce{', '$\\\\ce{').replaceAll('$\\pu{', '$\\\\pu{'); } + +export function fixMarkdownBold(text: string): string { + let count = 0; + let count2 = 0; + let result = ''; + for (let i = 0; i < text.length; i++) { + const char = text[i]; + if (char === '*') { + count++; + if (count === 2) { + count2++; + } + if (count > 2) { + result += char; + continue; + } + if (count === 2 && count2 % 2 === 0) { + const prevChar = i > 0 ? text[i - 2] : ''; + const isPrevCharAlphanumeric = /[a-zA-Z0-9]/.test(prevChar); + + if (i + 1 < text.length && text[i + 1] !== ' ' && !isPrevCharAlphanumeric) { + result += '* '; + } else { + result += '*'; + } + } else { + result += '*'; + } + } else { + result += char; + count = 0; + } + } + return result; +}