diff --git a/apps/showcase_ui/src/app/utils/markdown-parser.util.spec.ts b/apps/showcase_ui/src/app/utils/markdown-parser.util.spec.ts index 0fd04defa..0ffbdbb87 100644 --- a/apps/showcase_ui/src/app/utils/markdown-parser.util.spec.ts +++ b/apps/showcase_ui/src/app/utils/markdown-parser.util.spec.ts @@ -68,3 +68,78 @@ describe('markdown-parser.util verification & check lines', () => { expect(html).toContain('status is ok'); }); }); + +describe('renderMarkdownToHtml inline code', () => { + for (const literal of ['**literal**', '__name__', 'a*b*c', '_literal_', '***literal***', '___literal___', '~~literal~~']) { + it(`should preserve ${literal} inside inline code`, () => { + expect(renderMarkdownToHtml('`' + literal + '`')) + .toBe(`
${literal}**first** italic __second__ a*b_c~d after${close}a* plain *b and a_ plain _b and a~~ plain ~~b**first**__second__<img src=x onerror="alert(1)"> & </code> **literal**codeafter and beforecode and codex* and *x after<inline-code-1> $& $1 $$ **literal****heading**__item__~~quote~~');
+ });
+
+ it('should leave fenced code formatting unchanged', () => {
+ expect(renderMarkdownToHtml('```text\n`**literal**` &\n```'))
+ .toBe('`**literal**` <b>&</b>');
+ });
+});
diff --git a/apps/showcase_ui/src/app/utils/markdown-parser.util.ts b/apps/showcase_ui/src/app/utils/markdown-parser.util.ts
index 0b3e377a2..030430d4c 100644
--- a/apps/showcase_ui/src/app/utils/markdown-parser.util.ts
+++ b/apps/showcase_ui/src/app/utils/markdown-parser.util.ts
@@ -213,9 +213,14 @@ export function extractCheckerResult(text: string): CheckerResult | null {
*/
function formatInlineMarkdown(text: string): string {
if (!text) return '';
- return text
- // Inline code first (so asterisks inside code aren't formatted)
- .replace(/`([^`]+)`/g, '$1')
+ const codeSpans: string[] = [];
+ const formatted = text
+ // Input is already HTML-escaped, so these placeholders cannot collide with user text.
+ // Restore code after formatting so its contents remain literal.
+ .replace(/`([^`]+)`/g, (_, code: string) => {
+ codeSpans.push(code);
+ return `${codeSpans[Number(index)]}`);
}
/**