Skip to content

Commit 7b9f23b

Browse files
committed
feat: optional image captions using markdown title attribute
Images with title attribute are wrapped in <figure> with <figcaption>. Standard markdown syntax: ![alt](image.png "caption text") Title attribute kept on img for tooltips.
1 parent 195017d commit 7b9f23b

2 files changed

Lines changed: 14 additions & 5 deletions

File tree

shared/jekyll-markdown-parser.spec.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ export <span class="hljs-class"><span class="hljs-keyword">class</span> <span cl
6666
&lt;/<span class="hljs-symbol">div</span>&gt;
6767
</code></pre><h2 id="images">Images</h2>
6868
<p>Local image: <img src="https://example.com/blog/my-post/screenshot.png" alt="Screenshot"></p>
69-
<p>Image with title: <img src="https://example.com/blog/my-post/logo.png" alt="Logo" title="Company Logo"></p>
69+
<p>Image with title: <figure><img src="https://example.com/blog/my-post/logo.png" alt="Logo" title="Company Logo"><figcaption>Company Logo</figcaption></figure></p>
7070
<p>External image: <img src="https://example.com/external.png" alt="External"></p>
7171
<h2 id="links">Links</h2>
7272
<p>Check out <a href="https://angular-buch.com/docs">our documentation</a> for more info.</p>
@@ -425,6 +425,7 @@ describe('JekyllMarkdownParser', () => {
425425
// === Images with URL transformation ===
426426
expect(html).toContain(`src="${baseUrl}screenshot.png"`);
427427
expect(html).toContain(`src="${baseUrl}logo.png"`);
428+
expect(html).toContain('<figcaption>Company Logo</figcaption>');
428429
expect(html).toContain('title="Company Logo"');
429430
expect(html).toContain('src="https://example.com/external.png"'); // external unchanged
430431

@@ -525,6 +526,8 @@ title: Test
525526
const parser = new JekyllMarkdownParser(baseUrl);
526527
const result = parser.parse(input);
527528

529+
expect(result.html).toContain('<figure>');
530+
expect(result.html).toContain('<figcaption>Image Title</figcaption>');
528531
expect(result.html).toContain('title="Image Title"');
529532
expect(result.html).toContain(`src="${baseUrl}image.png"`);
530533
expect(result.html).toContain('alt="Alt text"');

shared/jekyll-markdown-parser.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ export class JekyllMarkdownParser {
103103
*
104104
* NOTE: In marked v17, the token contains RAW unescaped text.
105105
* We MUST escape special characters to prevent broken HTML.
106+
*
107+
* FEATURE: If a title is provided, the image is wrapped in a <figure> element
108+
* with a <figcaption> containing the title text. This allows optional captions
109+
* using standard Markdown syntax: ![alt](image.png "caption text")
106110
*/
107111
private imageRenderer(token: Tokens.Image): string {
108112
let src = token.href;
@@ -112,12 +116,14 @@ export class JekyllMarkdownParser {
112116
}
113117

114118
const escapedAlt = this.escapeHtml(token.text);
115-
let out = `<img src="${src}" alt="${escapedAlt}"`;
119+
116120
if (token.title) {
117-
out += ` title="${this.escapeHtml(token.title)}"`;
121+
const escapedTitle = this.escapeHtml(token.title);
122+
const imgTag = `<img src="${src}" alt="${escapedAlt}" title="${escapedTitle}">`;
123+
return `<figure>${imgTag}<figcaption>${escapedTitle}</figcaption></figure>`;
118124
}
119-
out += '>';
120-
return out;
125+
126+
return `<img src="${src}" alt="${escapedAlt}">`;
121127
}
122128

123129
// Transform relative paths in raw HTML <img> tags to absolute URLs

0 commit comments

Comments
 (0)