Skip to content

Commit

Permalink
Allow AlpineJS syntax extensions in Markdown (#3554)
Browse files Browse the repository at this point in the history
* Allow AlpineJS syntax extensions in Markdown

* Remove unwanted MDX ESM import/export support
  • Loading branch information
hippotastic authored Jun 8, 2022
1 parent 073bab5 commit c549f16
Show file tree
Hide file tree
Showing 6 changed files with 554 additions and 398 deletions.
5 changes: 5 additions & 0 deletions .changeset/swift-rocks-refuse.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@astrojs/markdown-remark': patch
---

Allow AlpineJS syntax extensions in Markdown
9 changes: 7 additions & 2 deletions packages/markdown/remark/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,18 @@
"test": "mocha --exit --timeout 20000"
},
"dependencies": {
"@astrojs/micromark-extension-mdx-jsx": "^1.0.3",
"@astrojs/prism": "^0.4.1",
"acorn": "^8.7.1",
"acorn-jsx": "^5.3.2",
"assert": "^2.0.0",
"github-slugger": "^1.4.0",
"mdast-util-mdx-expression": "^1.2.0",
"mdast-util-mdx-jsx": "^1.2.0",
"mdast-util-to-string": "^3.1.0",
"micromark-extension-mdx-jsx": "^1.0.3",
"micromark-extension-mdxjs": "^1.0.0",
"micromark-extension-mdx-expression": "^1.0.3",
"micromark-extension-mdx-md": "^1.0.0",
"micromark-util-combine-extensions": "^1.0.0",
"prismjs": "^1.28.0",
"rehype-raw": "^6.1.1",
"rehype-stringify": "^9.0.3",
Expand All @@ -55,6 +59,7 @@
"@types/unist": "^2.0.6",
"astro-scripts": "workspace:*",
"chai": "^4.3.6",
"micromark-util-types": "^1.0.2",
"mocha": "^9.2.2"
}
}
31 changes: 31 additions & 0 deletions packages/markdown/remark/src/mdxjs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Note: The code in this file is based on `micromark-extension-mdxjs`
// and was adapted to use our fork `@astrojs/micromark-extension-mdx-jsx`
// instead of `micromark-extension-mdx-jsx` to allow some extended syntax.
// See `@astrojs/micromark-extension-mdx-jsx` on NPM for more details.
// Also, support for ESM imports & exports in Markdown content was removed.

import { Parser } from 'acorn';
import acornJsx from 'acorn-jsx';
import { combineExtensions } from 'micromark-util-combine-extensions';
import { mdxExpression } from 'micromark-extension-mdx-expression';
import { mdxJsx } from '@astrojs/micromark-extension-mdx-jsx';
import { mdxMd } from 'micromark-extension-mdx-md';
import type { Options } from 'micromark-extension-mdx-expression';
import type { Extension } from 'micromark-util-types';

export function mdxjs(options: Options): Extension {
const settings: any = Object.assign(
{
acorn: Parser.extend(acornJsx()),
acornOptions: { ecmaVersion: 2020, sourceType: 'module' },
addResult: true
},
options
);

return combineExtensions([
mdxExpression(settings),
mdxJsx(settings),
mdxMd
]);
}
2 changes: 1 addition & 1 deletion packages/markdown/remark/src/remark-mdxish.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type * as fromMarkdown from 'mdast-util-from-markdown';
import type { Tag } from 'mdast-util-mdx-jsx';
import { mdxjs } from 'micromark-extension-mdxjs';
import { mdxjs } from './mdxjs.js';
import { mdxFromMarkdown, mdxToMarkdown } from './mdast-util-mdxish.js';

export default function remarkMdxish(this: any, options = {}) {
Expand Down
122 changes: 122 additions & 0 deletions packages/markdown/remark/test/strictness.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,126 @@ describe('strictness', () => {
`<img src="hi.jpg" /></p>`
);
});

it('should allow attribute names starting with ":" after element names', async () => {
const { code } = await renderMarkdown(
`<div :class="open ? '' : 'hidden'">Test</div>`,
{}
);

chai
.expect(code.trim())
.to.equal(`<div :class="open ? '' : 'hidden'">Test</div>`);
});

it('should allow attribute names starting with ":" after local element names', async () => {
const { code } = await renderMarkdown(
`<div.abc :class="open ? '' : 'hidden'">x</div.abc>`,
{}
);

chai
.expect(code.trim())
.to.equal(`<div.abc :class="open ? '' : 'hidden'">x</div.abc>`);
});

it('should allow attribute names starting with ":" after attribute names', async () => {
const { code } = await renderMarkdown(
`<input type="text" disabled :placeholder="hi">`,
{}
);

chai
.expect(code.trim())
.to.equal(`<input type="text" disabled :placeholder="hi" />`);
});

it('should allow attribute names starting with ":" after local attribute names', async () => {
const { code } = await renderMarkdown(
`<input type="text" x-test:disabled :placeholder="hi">`,
{}
);

chai
.expect(code.trim())
.to.equal(`<input type="text" x-test:disabled :placeholder="hi" />`);
});

it('should allow attribute names starting with ":" after attribute values', async () => {
const { code } = await renderMarkdown(
`<input type="text" :placeholder="placeholder">`,
{}
);

chai
.expect(code.trim())
.to.equal(`<input type="text" :placeholder="placeholder" />`);
});

it('should allow attribute names starting with "@" after element names', async () => {
const { code } = await renderMarkdown(
`<button @click="handleClick">Test</button>`,
{}
);

chai
.expect(code.trim())
.to.equal(`<button @click="handleClick">Test</button>`);
});

it('should allow attribute names starting with "@" after local element names', async () => {
const { code } = await renderMarkdown(
`<button.local @click="handleClick">Test</button.local>`,
{}
);

chai
.expect(code.trim())
.to.equal(`<button.local @click="handleClick">Test</button.local>`);
});

it('should allow attribute names starting with "@" after attribute names', async () => {
const { code } = await renderMarkdown(
`<button disabled @click="handleClick">Test</button>`,
{}
);

chai
.expect(code.trim())
.to.equal(`<button disabled @click="handleClick">Test</button>`);
});

it('should allow attribute names starting with "@" after local attribute names', async () => {
const { code } = await renderMarkdown(
`<button x-test:disabled @click="handleClick">Test</button>`,
{}
);

chai
.expect(code.trim())
.to.equal(`<button x-test:disabled @click="handleClick">Test</button>`);
});

it('should allow attribute names starting with "@" after attribute values', async () => {
const { code } = await renderMarkdown(
`<button type="submit" @click="handleClick">Test</button>`,
{}
);

chai
.expect(code.trim())
.to.equal(`<button type="submit" @click="handleClick">Test</button>`);
});

it('should allow attribute names containing dots', async () => {
const { code } = await renderMarkdown(
`<input x-on:input.debounce.500ms="fetchResults">`,
{}
);

chai
.expect(code.trim())
.to.equal(`<input x-on:input.debounce.500ms="fetchResults" />`);
});

});
Loading

0 comments on commit c549f16

Please sign in to comment.