From d0af5f4903c25e3398b4402bf37fb12bad0498d4 Mon Sep 17 00:00:00 2001 From: Marcos Passos Date: Wed, 25 Sep 2024 08:25:59 -0600 Subject: [PATCH] Improve title parsing --- src/parsing.ts | 20 +++++++++++---- test/parsing.test.ts | 59 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 5 deletions(-) diff --git a/src/parsing.ts b/src/parsing.ts index 65badf7..e8bd33e 100644 --- a/src/parsing.ts +++ b/src/parsing.ts @@ -290,14 +290,24 @@ class MarkdownParser { this.match(']('); - const [href, titleWithEndQuote] = this.parseText(')').split(/\s+"/); + const href = this.parseText(')', '"'); + + let title: string|undefined; + + if (this.matches('"')) { + this.match('"'); + + title = this.parseText('"'); + + this.match('"'); + } this.match(')'); return { type: 'link', - href: href, - title: titleWithEndQuote?.slice(0, -1) /* remove quote character at the end */, + href: href.trim(), + ...(title !== undefined ? {title: title} : {}), children: label, source: this.getSlice(startIndex, this.index), }; @@ -308,7 +318,7 @@ class MarkdownParser { } } - private parseText(end: string): string { + private parseText(...end: string[]): string { let text = ''; while (!this.done) { @@ -322,7 +332,7 @@ class MarkdownParser { continue; } - if (end === '' || this.matches(end) || this.matches(...MarkdownParser.NEWLINE)) { + if (end.some(token => (token === '' || this.matches(token))) || this.matches(...MarkdownParser.NEWLINE)) { break; } diff --git a/test/parsing.test.ts b/test/parsing.test.ts index 182eae7..ffb824f 100644 --- a/test/parsing.test.ts +++ b/test/parsing.test.ts @@ -946,6 +946,35 @@ describe('A Markdown parser function', () => { ], }, }, + 'link with spaces': { + input: 'Hello, [world]( image.png )!', + output: { + type: 'fragment', + source: 'Hello, [world]( image.png )!', + children: [ + { + type: 'text', + source: 'Hello, ', + content: 'Hello, ', + }, + { + type: 'link', + source: '[world]( image.png )', + href: 'image.png', + children: { + type: 'text', + source: 'world', + content: 'world', + }, + }, + { + type: 'text', + source: '!', + content: '!', + }, + ], + }, + }, 'fenced code (unsupported)': { input: 'Hello, ```world```!', output: { @@ -1149,6 +1178,36 @@ describe('A Markdown parser function', () => { ], }, }, + 'link with title and escaped quote': { + input: 'Hello, [world](image.png "The \\"world\\"")!', + output: { + type: 'fragment', + source: 'Hello, [world](image.png "The \\"world\\"")!', + children: [ + { + type: 'text', + source: 'Hello, ', + content: 'Hello, ', + }, + { + type: 'link', + source: '[world](image.png "The \\"world\\"")', + href: 'image.png', + title: 'The "world"', + children: { + type: 'text', + source: 'world', + content: 'world', + }, + }, + { + type: 'text', + source: '!', + content: '!', + }, + ], + }, + }, image: { input: 'Hello, ![world](image.png)!', output: {