Skip to content

Commit

Permalink
Fix: Allow self-closing tags in Markdown (#3516)
Browse files Browse the repository at this point in the history
  • Loading branch information
hippotastic authored Jun 3, 2022
1 parent 939fe15 commit 3057801
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/late-swans-impress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@astrojs/markdown-remark': patch
---

Fix: Allow self-closing tags in Markdown
37 changes: 36 additions & 1 deletion packages/markdown/remark/src/remark-mdxish.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,50 @@
import { mdxjs } from 'micromark-extension-mdxjs';
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 = {}) {
const data = this.data();

add('micromarkExtensions', mdxjs(options));
add('fromMarkdownExtensions', mdxFromMarkdown());
add('fromMarkdownExtensions', makeFromMarkdownLessStrict(mdxFromMarkdown()));
add('toMarkdownExtensions', mdxToMarkdown());

function add(field: string, value: unknown) {
const list = data[field] ? data[field] : (data[field] = []);
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 changes: 16 additions & 0 deletions packages/markdown/remark/test/strictness.test.js
Original file line number Diff line number Diff line change
@@ -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>`
);
});
});

0 comments on commit 3057801

Please sign in to comment.