Fix: Allow self-closing tags in Markdown (#3516)
This commit is contained in:
parent
939fe15925
commit
3057801591
3 changed files with 57 additions and 1 deletions
5
.changeset/late-swans-impress.md
Normal file
5
.changeset/late-swans-impress.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'@astrojs/markdown-remark': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fix: Allow self-closing tags in Markdown
|
|
@ -1,11 +1,13 @@
|
||||||
import { mdxjs } from 'micromark-extension-mdxjs';
|
import { mdxjs } from 'micromark-extension-mdxjs';
|
||||||
import { mdxFromMarkdown, mdxToMarkdown } from './mdast-util-mdxish.js';
|
import { mdxFromMarkdown, mdxToMarkdown } from './mdast-util-mdxish.js';
|
||||||
|
import type * as fromMarkdown from 'mdast-util-from-markdown';
|
||||||
|
import type { Tag } from 'mdast-util-mdx-jsx';
|
||||||
|
|
||||||
export default function remarkMdxish(this: any, options = {}) {
|
export default function remarkMdxish(this: any, options = {}) {
|
||||||
const data = this.data();
|
const data = this.data();
|
||||||
|
|
||||||
add('micromarkExtensions', mdxjs(options));
|
add('micromarkExtensions', mdxjs(options));
|
||||||
add('fromMarkdownExtensions', mdxFromMarkdown());
|
add('fromMarkdownExtensions', makeFromMarkdownLessStrict(mdxFromMarkdown()));
|
||||||
add('toMarkdownExtensions', mdxToMarkdown());
|
add('toMarkdownExtensions', mdxToMarkdown());
|
||||||
|
|
||||||
function add(field: string, value: unknown) {
|
function add(field: string, value: unknown) {
|
||||||
|
@ -13,3 +15,36 @@ export default function remarkMdxish(this: any, options = {}) {
|
||||||
list.push(value);
|
list.push(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function makeFromMarkdownLessStrict(extensions: fromMarkdown.Extension[]) {
|
||||||
|
extensions.forEach(extension => {
|
||||||
|
// Fix exit handlers that are too strict
|
||||||
|
['mdxJsxFlowTag', 'mdxJsxTextTag'].forEach(exitHandler => {
|
||||||
|
if (!extension.exit || !extension.exit[exitHandler])
|
||||||
|
return;
|
||||||
|
extension.exit[exitHandler] = chainHandlers(
|
||||||
|
fixSelfClosing,
|
||||||
|
extension.exit[exitHandler]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return extensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
const selfClosingTags = new Set([
|
||||||
|
'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'source',
|
||||||
|
'track', 'wbr'
|
||||||
|
]);
|
||||||
|
|
||||||
|
function fixSelfClosing(this: fromMarkdown.CompileContext) {
|
||||||
|
const tag = this.getData('mdxJsxTag') as Tag;
|
||||||
|
if (tag.name && selfClosingTags.has(tag.name))
|
||||||
|
tag.selfClosing = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function chainHandlers(...handlers: fromMarkdown.Handle[]) {
|
||||||
|
return function handlerChain (this: fromMarkdown.CompileContext, token: fromMarkdown.Token) {
|
||||||
|
handlers.forEach(handler => handler.call(this, token));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
16
packages/markdown/remark/test/strictness.test.js
Normal file
16
packages/markdown/remark/test/strictness.test.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import { renderMarkdown } from '../dist/index.js';
|
||||||
|
import chai from 'chai';
|
||||||
|
|
||||||
|
describe('strictness', () => {
|
||||||
|
it('should allow self-closing HTML tags (void elements)', async () => {
|
||||||
|
const { code } = await renderMarkdown(
|
||||||
|
`Use self-closing void elements<br>like word<wbr>break and images: <img src="hi.jpg">`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
|
||||||
|
chai.expect(code).to.equal(
|
||||||
|
`<p>Use self-closing void elements<br />like word<wbr />break and images: ` +
|
||||||
|
`<img src="hi.jpg" /></p>`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in a new issue