diff --git a/lib/macro-converter.js b/lib/macro-converter.js index 2dc2a25..e2def3e 100644 --- a/lib/macro-converter.js +++ b/lib/macro-converter.js @@ -21,7 +21,7 @@ const STASH_DELIM = '\uE000'; // The body alternation `"[^"]*"|'[^']*'|[^>]` makes the match quote-aware // so a literal `>` inside a quoted attribute value (e.g. // ``) does not terminate the tag prematurely. -const PASSTHROUGH_TAG_RE = /<\/?(?:u|sub|sup|mark|details|summary)(?=[\s/>])(?:"[^"]*"|'[^']*'|[^>])*>/gi; +const PASSTHROUGH_TAG_RE = /<\/?(?:br|u|sub|sup|mark|details|summary)(?=[\s/>])(?:"[^"]*"|'[^']*'|[^>])*>/gi; // Block-level HTML elements that should pass through WITHOUT markdown processing of their content. const PASSTHROUGH_BLOCK_RE = /<(svg|div)(?:\s[^>]*)?>[\s\S]*?<\/\1>/gi; // Single-backtick inline code spans. Block-level code (fenced + indented) is diff --git a/tests/macro-converter.test.js b/tests/macro-converter.test.js index 29c860a..e7649e2 100644 --- a/tests/macro-converter.test.js +++ b/tests/macro-converter.test.js @@ -1048,6 +1048,31 @@ describe('MacroConverter /// passthrough', () => { }); }); +describe('MacroConverter
passthrough', () => { + // `
` is the practical way to get a line break inside a table cell via + // markdown, since markdown table grammar allows only inline text per cell. + const converter = new MacroConverter({ isCloud: true }); + + test('
in a table cell passes through instead of being escaped', () => { + const md = '| 버전 | 변경 |\n| --- | --- |\n| v1 | 가

다 |'; + const result = converter.markdownToStorage(md); + expect(result).toContain('



'); + expect(result).not.toContain('<br>'); + }); + + test('
and
variants pass through', () => { + const result = converter.markdownToStorage('a
b and c
d'); + expect(result).toContain('a
b and c
d'); + expect(result).not.toContain('<br'); + }); + + test('literal
inside inline code stays escaped, not passed through', () => { + const result = converter.markdownToStorage('`
`'); + expect(result).toContain('<br>'); + expect(result).not.toMatch(/
/); + }); +}); + describe('MacroConverter storageToMarkdown panel formatting', () => { const converter = new MacroConverter({ isCloud: true });