From e179ed19bc3afaa10279b4b6c28dd10fbfec962d Mon Sep 17 00:00:00 2001 From: "Tobias H. Michaelsen" Date: Wed, 25 Sep 2024 15:46:35 +0200 Subject: [PATCH] Add support for title on links (#33) --- src/ast.ts | 1 + src/parsing.ts | 3 ++- src/rendering.ts | 2 ++ test/parsing.test.ts | 30 ++++++++++++++++++++++++++++++ test/rendering.test.ts | 19 +++++++++++++++++++ 5 files changed, 54 insertions(+), 1 deletion(-) diff --git a/src/ast.ts b/src/ast.ts index a9f3eb6..e5dbebf 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -16,6 +16,7 @@ type MarkdownNodeMap = { }, link: { href: string, + title?: string, children: MarkdownNode, }, image: { diff --git a/src/parsing.ts b/src/parsing.ts index d28a545..65badf7 100644 --- a/src/parsing.ts +++ b/src/parsing.ts @@ -290,13 +290,14 @@ class MarkdownParser { this.match(']('); - const href = this.parseText(')'); + const [href, titleWithEndQuote] = this.parseText(')').split(/\s+"/); this.match(')'); return { type: 'link', href: href, + title: titleWithEndQuote?.slice(0, -1) /* remove quote character at the end */, children: label, source: this.getSlice(startIndex, this.index), }; diff --git a/src/rendering.ts b/src/rendering.ts index 7622461..251f944 100644 --- a/src/rendering.ts +++ b/src/rendering.ts @@ -19,6 +19,7 @@ type VisitedMarkdownNodeMap = { }, link: { href: string, + title?: string, children: C, }, image: { @@ -92,6 +93,7 @@ function visit(node: MarkdownNode, visitor: MarkdownRenderer): T { return visitor.link({ type: node.type, href: node.href, + title: node.title, children: visit(node.children, visitor), source: node.source, }); diff --git a/test/parsing.test.ts b/test/parsing.test.ts index 9a94497..182eae7 100644 --- a/test/parsing.test.ts +++ b/test/parsing.test.ts @@ -1119,6 +1119,36 @@ describe('A Markdown parser function', () => { ], }, }, + 'link with title': { + 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: { diff --git a/test/rendering.test.ts b/test/rendering.test.ts index adbecb4..bd0f4e7 100644 --- a/test/rendering.test.ts +++ b/test/rendering.test.ts @@ -65,6 +65,7 @@ describe('A Markdown render function', () => { type: 'link', source: node.source, href: node.href, + title: node.title, children: node.children, }; } @@ -86,6 +87,7 @@ describe('A Markdown render function', () => { '`Code`', '![Image](https://example.com/image.png)', '[Link](https://example.com)', + '[Link with title](https://example.com "Link title")', ].join('\n\n'); const tree: MarkdownNode = { @@ -195,6 +197,23 @@ describe('A Markdown render function', () => { }, ], }, + { + type: 'paragraph', + source: '[Link with title](https://example.com "Link title")', + children: [ + { + type: 'link', + source: '[Link with title](https://example.com "Link title")', + href: 'https://example.com', + title: 'Link title', + children: { + type: 'text', + source: 'Link with title', + content: 'Link with title', + }, + }, + ], + }, ], };