diff --git a/.changeset/grumpy-seas-learn.md b/.changeset/grumpy-seas-learn.md new file mode 100644 index 0000000000..84daf0f441 --- /dev/null +++ b/.changeset/grumpy-seas-learn.md @@ -0,0 +1,5 @@ +--- +'@astrojs/markdown-remark': minor +--- + +feat(markdown): Add support for `imageReference` paths when collecting images diff --git a/packages/markdown/remark/package.json b/packages/markdown/remark/package.json index 8710cce085..b25950c00f 100644 --- a/packages/markdown/remark/package.json +++ b/packages/markdown/remark/package.json @@ -34,6 +34,7 @@ "@astrojs/prism": "^3.0.0", "github-slugger": "^2.0.0", "import-meta-resolve": "^3.0.0", + "mdast-util-definitions": "^6.0.0", "rehype-raw": "^6.1.1", "rehype-stringify": "^9.0.4", "remark-gfm": "^3.0.1", diff --git a/packages/markdown/remark/src/remark-collect-images.ts b/packages/markdown/remark/src/remark-collect-images.ts index ecaa82d1dc..cfce513765 100644 --- a/packages/markdown/remark/src/remark-collect-images.ts +++ b/packages/markdown/remark/src/remark-collect-images.ts @@ -1,4 +1,5 @@ -import type { Image } from 'mdast'; +import type { Image, ImageReference } from 'mdast'; +import { definitions } from 'mdast-util-definitions'; import { visit } from 'unist-util-visit'; import type { MarkdownVFile } from './types.js'; @@ -6,9 +7,18 @@ export function remarkCollectImages() { return function (tree: any, vfile: MarkdownVFile) { if (typeof vfile?.path !== 'string') return; + const definition = definitions(tree); const imagePaths = new Set(); - visit(tree, 'image', (node: Image) => { - if (shouldOptimizeImage(node.url)) imagePaths.add(node.url); + visit(tree, ['image', 'imageReference'], (node: Image | ImageReference) => { + if (node.type === 'image') { + if (shouldOptimizeImage(node.url)) imagePaths.add(node.url); + } + if (node.type === 'imageReference') { + const imageDefinition = definition(node.identifier); + if (imageDefinition) { + if (shouldOptimizeImage(imageDefinition.url)) imagePaths.add(imageDefinition.url); + } + } }); vfile.data.imagePaths = imagePaths; diff --git a/packages/markdown/remark/test/remark-collect-images.test.js b/packages/markdown/remark/test/remark-collect-images.test.js new file mode 100644 index 0000000000..d5c743e20d --- /dev/null +++ b/packages/markdown/remark/test/remark-collect-images.test.js @@ -0,0 +1,28 @@ +import { renderMarkdown } from '../dist/index.js'; +import { mockRenderMarkdownParams } from './test-utils.js'; +import chai from 'chai'; + +describe('collect images', () => { + it('should collect inline image paths', async () => { + const { code, vfile } = await renderMarkdown( + `Hello ![inline image url](./img.png)`, + mockRenderMarkdownParams + ); + + chai + .expect(code) + .to.equal('

Hello inline image url

'); + + chai.expect(Array.from(vfile.data.imagePaths)).to.deep.equal(['./img.png']); + }); + + it('should add image paths from definition', async () => { + const { code, vfile } = await renderMarkdown( + `Hello ![image ref][img-ref]\n\n[img-ref]: ./img.webp`, + mockRenderMarkdownParams + ); + + chai.expect(code).to.equal('

Hello image ref

'); + chai.expect(Array.from(vfile.data.imagePaths)).to.deep.equal(['./img.webp']); + }); +}); diff --git a/packages/markdown/remark/test/test-utils.js b/packages/markdown/remark/test/test-utils.js index 10b779a7de..76b593deb7 100644 --- a/packages/markdown/remark/test/test-utils.js +++ b/packages/markdown/remark/test/test-utils.js @@ -1,3 +1,4 @@ export const mockRenderMarkdownParams = { + fileURL: 'file.md', contentDir: new URL('file:///src/content/'), }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bb4bf96d73..e178a0ee91 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4918,6 +4918,9 @@ importers: import-meta-resolve: specifier: ^3.0.0 version: 3.0.0 + mdast-util-definitions: + specifier: ^6.0.0 + version: 6.0.0 rehype-raw: specifier: ^6.1.1 version: 6.1.1 @@ -13425,6 +13428,14 @@ packages: '@types/unist': 2.0.7 unist-util-visit: 4.1.2 + /mdast-util-definitions@6.0.0: + resolution: {integrity: sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==} + dependencies: + '@types/mdast': 4.0.0 + '@types/unist': 3.0.0 + unist-util-visit: 5.0.0 + dev: false + /mdast-util-find-and-replace@2.2.2: resolution: {integrity: sha512-MTtdFRz/eMDHXzeK6W3dO7mXUlF82Gom4y0oOgvHhh/HXZAGvIQDUvQ0SuUx+j2tv44b8xTHOm8K/9OoRFnXKw==} dependencies: