Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/macro-converter.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
// `<mark title="1>0">`) 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
Expand Down
25 changes: 25 additions & 0 deletions tests/macro-converter.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1048,6 +1048,31 @@ describe('MacroConverter <u>/<sub>/<sup>/<mark> passthrough', () => {
});
});

describe('MacroConverter <br> passthrough', () => {
// `<br>` 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('<br> in a table cell passes through instead of being escaped', () => {
const md = '| 버전 | 변경 |\n| --- | --- |\n| v1 | 가<br>나<br>다 |';
const result = converter.markdownToStorage(md);
expect(result).toContain('<td><p>가<br>나<br>다</p></td>');
expect(result).not.toContain('&lt;br&gt;');
});

test('<br/> and <br /> variants pass through', () => {
const result = converter.markdownToStorage('a<br/>b and c<br />d');
expect(result).toContain('a<br>b and c<br>d');
expect(result).not.toContain('&lt;br');
});

test('literal <br> inside inline code stays escaped, not passed through', () => {
const result = converter.markdownToStorage('`<br>`');
expect(result).toContain('&lt;br&gt;');
expect(result).not.toMatch(/<br>/);
});
});

describe('MacroConverter storageToMarkdown panel formatting', () => {
const converter = new MacroConverter({ isCloud: true });

Expand Down