aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Oliver Speir <115520730+OliverSpeir@users.noreply.github.com> 2024-01-23 16:18:09 -0700
committerGravatar GitHub <noreply@github.com> 2024-01-23 18:18:09 -0500
commitdf37366556d46f7abdf82b09e33b08bd94e631b3 (patch)
treef3df548cdf291e8c150810793f1ebdf578187bc5
parent2e58904cd44eb6a36d2b093dc3b27ee29758326b (diff)
downloadastro-df37366556d46f7abdf82b09e33b08bd94e631b3.tar.gz
astro-df37366556d46f7abdf82b09e33b08bd94e631b3.tar.zst
astro-df37366556d46f7abdf82b09e33b08bd94e631b3.zip
MDX remark image props (#9753)
* rearrange plugins and add props to Image component * add tests and update lockfile * add changeset * re-rearrange plugin order, gfm/smartypants then user defined then image related then shiki/prism * make more generic * add more/better tests * remove unused logger --------- Co-authored-by: Erika <3019731+Princesseuh@users.noreply.github.com>
-rw-r--r--.changeset/quick-cars-kneel.md5
-rw-r--r--packages/integrations/mdx/src/plugins.ts4
-rw-r--r--packages/integrations/mdx/src/remark-images-to-component.ts49
-rw-r--r--packages/integrations/mdx/test/fixtures/image-remark-imgattr/astro.config.mjs8
-rw-r--r--packages/integrations/mdx/test/fixtures/image-remark-imgattr/package.json12
-rw-r--r--packages/integrations/mdx/test/fixtures/image-remark-imgattr/remarkPlugin.js22
-rw-r--r--packages/integrations/mdx/test/fixtures/image-remark-imgattr/src/assets/penguin2.jpgbin0 -> 11677 bytes
-rw-r--r--packages/integrations/mdx/test/fixtures/image-remark-imgattr/src/pages/index.mdx1
-rw-r--r--packages/integrations/mdx/test/remark-imgattr.test.js50
-rw-r--r--pnpm-lock.yaml9
10 files changed, 157 insertions, 3 deletions
diff --git a/.changeset/quick-cars-kneel.md b/.changeset/quick-cars-kneel.md
new file mode 100644
index 000000000..deecfed6c
--- /dev/null
+++ b/.changeset/quick-cars-kneel.md
@@ -0,0 +1,5 @@
+---
+"@astrojs/mdx": minor
+---
+
+Allows remark plugins to pass options specifying how images in .mdx files will be optimized
diff --git a/packages/integrations/mdx/src/plugins.ts b/packages/integrations/mdx/src/plugins.ts
index e6584aacf..2217a4da7 100644
--- a/packages/integrations/mdx/src/plugins.ts
+++ b/packages/integrations/mdx/src/plugins.ts
@@ -43,7 +43,7 @@ export function createMdxProcessor(mdxOptions: MdxOptions, extraOptions: MdxProc
}
function getRemarkPlugins(mdxOptions: MdxOptions): PluggableList {
- let remarkPlugins: PluggableList = [remarkCollectImages, remarkImageToComponent];
+ let remarkPlugins: PluggableList = [];
if (!isPerformanceBenchmark) {
if (mdxOptions.gfm) {
@@ -54,7 +54,7 @@ function getRemarkPlugins(mdxOptions: MdxOptions): PluggableList {
}
}
- remarkPlugins = [...remarkPlugins, ...mdxOptions.remarkPlugins];
+ remarkPlugins = [...remarkPlugins, ...mdxOptions.remarkPlugins, remarkCollectImages, remarkImageToComponent];
if (!isPerformanceBenchmark) {
// Apply syntax highlighters after user plugins to match `markdown/remark` behavior
diff --git a/packages/integrations/mdx/src/remark-images-to-component.ts b/packages/integrations/mdx/src/remark-images-to-component.ts
index 810056def..86f04aa47 100644
--- a/packages/integrations/mdx/src/remark-images-to-component.ts
+++ b/packages/integrations/mdx/src/remark-images-to-component.ts
@@ -1,6 +1,6 @@
import type { MarkdownVFile } from '@astrojs/markdown-remark';
import type { Image, Parent } from 'mdast';
-import type { MdxJsxFlowElement, MdxjsEsm } from 'mdast-util-mdx';
+import type { MdxJsxFlowElement, MdxjsEsm, MdxJsxAttribute } from 'mdast-util-mdx';
import { visit } from 'unist-util-visit';
import { jsToTreeNode } from './utils.js';
@@ -89,6 +89,53 @@ export function remarkImageToComponent() {
});
}
+ if (node.data && node.data.hProperties) {
+ const createArrayAttribute = (name: string, values: string[]): MdxJsxAttribute => {
+ return {
+ type: 'mdxJsxAttribute',
+ name: name,
+ value: {
+ type: 'mdxJsxAttributeValueExpression',
+ value: name,
+ data: {
+ estree: {
+ type: 'Program',
+ body: [
+ {
+ type: 'ExpressionStatement',
+ expression: {
+ type: 'ArrayExpression',
+ elements: values.map((value) => ({
+ type: 'Literal',
+ value: value,
+ raw: String(value),
+ })),
+ },
+ },
+ ],
+ sourceType: 'module',
+ comments: [],
+ },
+ },
+ },
+ };
+ };
+ // Go through every hProperty and add it as an attribute of the <Image>
+ Object.entries(node.data.hProperties as Record<string, string | string[]>).forEach(
+ ([key, value]) => {
+ if (Array.isArray(value)) {
+ componentElement.attributes.push(createArrayAttribute(key, value));
+ } else {
+ componentElement.attributes.push({
+ name: key,
+ type: 'mdxJsxAttribute',
+ value: String(value),
+ });
+ }
+ }
+ );
+ }
+
parent!.children.splice(index!, 1, componentElement);
}
});
diff --git a/packages/integrations/mdx/test/fixtures/image-remark-imgattr/astro.config.mjs b/packages/integrations/mdx/test/fixtures/image-remark-imgattr/astro.config.mjs
new file mode 100644
index 000000000..1ba809580
--- /dev/null
+++ b/packages/integrations/mdx/test/fixtures/image-remark-imgattr/astro.config.mjs
@@ -0,0 +1,8 @@
+import { defineConfig } from 'astro/config';
+import mdx from '@astrojs/mdx';
+import plugin from "./remarkPlugin"
+
+// https://astro.build/config
+export default defineConfig({
+ integrations: [mdx({remarkPlugins:[plugin]})],
+});
diff --git a/packages/integrations/mdx/test/fixtures/image-remark-imgattr/package.json b/packages/integrations/mdx/test/fixtures/image-remark-imgattr/package.json
new file mode 100644
index 000000000..89868f9f4
--- /dev/null
+++ b/packages/integrations/mdx/test/fixtures/image-remark-imgattr/package.json
@@ -0,0 +1,12 @@
+{
+ "name": "@test/image-remark-imgattr",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "@astrojs/mdx": "workspace:*",
+ "astro": "workspace:*"
+ },
+ "scripts": {
+ "dev": "astro dev"
+ }
+}
diff --git a/packages/integrations/mdx/test/fixtures/image-remark-imgattr/remarkPlugin.js b/packages/integrations/mdx/test/fixtures/image-remark-imgattr/remarkPlugin.js
new file mode 100644
index 000000000..f42d9ec52
--- /dev/null
+++ b/packages/integrations/mdx/test/fixtures/image-remark-imgattr/remarkPlugin.js
@@ -0,0 +1,22 @@
+export default function plugin() {
+ return transformer;
+
+ function transformer(tree) {
+ function traverse(node) {
+ if (node.type === "image") {
+ node.data = node.data || {};
+ node.data.hProperties = node.data.hProperties || {};
+ node.data.hProperties.id = "test";
+ node.data.hProperties.width = "300";
+ node.data.hProperties.widths = [300,600];
+ node.data.hProperties.sizes = "(min-width: 600px) 600w, 300w";
+ }
+
+ if (node.children) {
+ node.children.forEach(traverse);
+ }
+ }
+
+ traverse(tree);
+ }
+}
diff --git a/packages/integrations/mdx/test/fixtures/image-remark-imgattr/src/assets/penguin2.jpg b/packages/integrations/mdx/test/fixtures/image-remark-imgattr/src/assets/penguin2.jpg
new file mode 100644
index 000000000..e859ac3c9
--- /dev/null
+++ b/packages/integrations/mdx/test/fixtures/image-remark-imgattr/src/assets/penguin2.jpg
Binary files differ
diff --git a/packages/integrations/mdx/test/fixtures/image-remark-imgattr/src/pages/index.mdx b/packages/integrations/mdx/test/fixtures/image-remark-imgattr/src/pages/index.mdx
new file mode 100644
index 000000000..e415e505d
--- /dev/null
+++ b/packages/integrations/mdx/test/fixtures/image-remark-imgattr/src/pages/index.mdx
@@ -0,0 +1 @@
+![alt](../assets/penguin2.jpg)
diff --git a/packages/integrations/mdx/test/remark-imgattr.test.js b/packages/integrations/mdx/test/remark-imgattr.test.js
new file mode 100644
index 000000000..7bedc3e91
--- /dev/null
+++ b/packages/integrations/mdx/test/remark-imgattr.test.js
@@ -0,0 +1,50 @@
+import { expect } from 'chai';
+import * as cheerio from 'cheerio';
+import { loadFixture } from '../../../astro/test/test-utils.js';
+
+const FIXTURE_ROOT = new URL('./fixtures/image-remark-imgattr/', import.meta.url);
+
+describe('Testing remark plugins for image processing', () => {
+ /** @type {import('./test-utils').Fixture} */
+ let fixture;
+
+ describe('start dev server', () => {
+ /** @type {import('./test-utils').DevServer} */
+ let devServer;
+
+ before(async () => {
+ fixture = await loadFixture({
+ root: FIXTURE_ROOT,
+ });
+
+ devServer = await fixture.startDevServer();
+ });
+
+ after(async () => {
+ await devServer.stop();
+ });
+
+ describe('Test image attributes can be added by remark plugins', () => {
+ let $;
+ before(async () => {
+ let res = await fixture.fetch('/');
+ let html = await res.text();
+ $ = cheerio.load(html);
+ });
+
+ it('<img> has correct attributes', async () => {
+ let $img = $('img');
+ expect($img.attr('id')).to.equal('test');
+ expect($img.attr('sizes')).to.equal('(min-width: 600px) 600w, 300w');
+ expect($img.attr('srcset')).to.not.be.empty;
+ });
+
+ it('<img> was processed properly', async () => {
+ let $img = $('img');
+ expect(new URL($img.attr('src'), 'http://example.com').searchParams.get('w')).to.equal(
+ '300'
+ );
+ });
+ });
+ });
+});
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index bd9c3985a..fafa7a936 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -4138,6 +4138,15 @@ importers:
specifier: 0.2.4
version: 0.2.4
+ packages/integrations/mdx/test/fixtures/image-remark-imgattr:
+ dependencies:
+ '@astrojs/mdx':
+ specifier: workspace:*
+ version: link:../../..
+ astro:
+ specifier: workspace:*
+ version: link:../../../../../astro
+
packages/integrations/mdx/test/fixtures/mdx-frontmatter-injection:
dependencies:
'@astrojs/mdx':