[ci] format

This commit is contained in:
natemoo-re 2022-05-24 22:03:29 +00:00 committed by github-actions[bot]
parent cfae9760b2
commit cb039219ef
11 changed files with 134 additions and 115 deletions

View file

@ -125,9 +125,15 @@ export default function markdown({ config }: AstroPluginOptions): Plugin {
let { data: frontmatter, content: markdownContent } = matter(source); let { data: frontmatter, content: markdownContent } = matter(source);
// Turn HTML comments into JS comments // Turn HTML comments into JS comments
markdownContent = markdownContent.replace(/<\s*!--([^-->]*)(.*?)-->/gs, (whole) => `{/*${whole}*/}`) markdownContent = markdownContent.replace(
/<\s*!--([^-->]*)(.*?)-->/gs,
(whole) => `{/*${whole}*/}`
);
let renderResult = await renderMarkdown(markdownContent, { ...renderOpts, fileURL: fileUrl } as any); let renderResult = await renderMarkdown(markdownContent, {
...renderOpts,
fileURL: fileUrl,
} as any);
let { code: astroResult, metadata } = renderResult; let { code: astroResult, metadata } = renderResult;
const { layout = '', components = '', setup = '', ...content } = frontmatter; const { layout = '', components = '', setup = '', ...content } = frontmatter;
content.astro = metadata; content.astro = metadata;

View file

@ -39,7 +39,7 @@ describe('Astro Markdown', () => {
const html = await fixture.readFile('/slug/index.html'); const html = await fixture.readFile('/slug/index.html');
const $ = cheerio.load(html); const $ = cheerio.load(html);
expect($('h1').attr("id")).to.equal('my-blog-post'); expect($('h1').attr('id')).to.equal('my-blog-post');
}); });
it('Can handle code elements without extra spacing', async () => { it('Can handle code elements without extra spacing', async () => {
@ -47,7 +47,7 @@ describe('Astro Markdown', () => {
const $ = cheerio.load(html); const $ = cheerio.load(html);
$('code').each((_, el) => { $('code').each((_, el) => {
expect($(el).html()).to.equal($(el).html().trim()) expect($(el).html()).to.equal($(el).html().trim());
}); });
}); });
@ -76,7 +76,7 @@ describe('Astro Markdown', () => {
it('Can handle scripts in markdown pages', async () => { it('Can handle scripts in markdown pages', async () => {
const html = await fixture.readFile('/script/index.html'); const html = await fixture.readFile('/script/index.html');
console.log(html); console.log(html);
expect(html).not.to.match(new RegExp("\/src\/scripts\/test\.js")); expect(html).not.to.match(new RegExp('/src/scripts/test.js'));
}); });
it('Can load more complex jsxy stuff', async () => { it('Can load more complex jsxy stuff', async () => {

View file

@ -36,8 +36,15 @@ export async function renderMarkdown(
content: string, content: string,
opts: MarkdownRenderingOptions = {} opts: MarkdownRenderingOptions = {}
): Promise<MarkdownRenderingResult> { ): Promise<MarkdownRenderingResult> {
let { fileURL, mode = 'mdx', syntaxHighlight = 'shiki', shikiConfig = {}, remarkPlugins = [], rehypePlugins = [] } = opts; let {
const input = new VFile({ value: content, path: fileURL }) fileURL,
mode = 'mdx',
syntaxHighlight = 'shiki',
shikiConfig = {},
remarkPlugins = [],
rehypePlugins = [],
} = opts;
const input = new VFile({ value: content, path: fileURL });
const scopedClassName = opts.$?.scopedClassName; const scopedClassName = opts.$?.scopedClassName;
const isMDX = mode === 'mdx'; const isMDX = mode === 'mdx';
const { headers, rehypeCollectHeaders } = createCollectHeaders(); const { headers, rehypeCollectHeaders } = createCollectHeaders();

View file

@ -1,18 +1,12 @@
import { import { mdxExpressionFromMarkdown, mdxExpressionToMarkdown } from 'mdast-util-mdx-expression';
mdxExpressionFromMarkdown, import { mdxJsxFromMarkdown, mdxJsxToMarkdown } from 'mdast-util-mdx-jsx';
mdxExpressionToMarkdown
} from 'mdast-util-mdx-expression'
import {mdxJsxFromMarkdown, mdxJsxToMarkdown} from 'mdast-util-mdx-jsx'
export function mdxFromMarkdown(): any { export function mdxFromMarkdown(): any {
return [mdxExpressionFromMarkdown, mdxJsxFromMarkdown] return [mdxExpressionFromMarkdown, mdxJsxFromMarkdown];
} }
export function mdxToMarkdown(): any { export function mdxToMarkdown(): any {
return { return {
extensions: [ extensions: [mdxExpressionToMarkdown, mdxJsxToMarkdown],
mdxExpressionToMarkdown, };
mdxJsxToMarkdown,
]
}
} }

View file

@ -31,21 +31,22 @@ export default function createCollectHeaders() {
return; return;
} }
} }
if (child.type === 'text' || child.type === 'raw') { if (child.type === 'text' || child.type === 'raw') {
raw += child.value; raw += child.value;
text += child.value; text += child.value;
isJSX = isJSX || child.value.includes('{'); isJSX = isJSX || child.value.includes('{');
} }
}); });
node.properties = node.properties || {}; node.properties = node.properties || {};
if (typeof node.properties.id !== 'string') { if (typeof node.properties.id !== 'string') {
if (isJSX) { if (isJSX) {
// HACK: for ids that have JSX content, use $$slug helper to generate slug at runtime // HACK: for ids that have JSX content, use $$slug helper to generate slug at runtime
node.properties.id = `$$slug(\`${text.replace(/\{/g, '${')}\`)`; node.properties.id = `$$slug(\`${text.replace(/\{/g, '${')}\`)`;
(node as any).type = 'raw'; (node as any).type = 'raw';
(node as any).value = `<${node.tagName} id={${node.properties.id}}>${raw}</${node.tagName}>`; (
node as any
).value = `<${node.tagName} id={${node.properties.id}}>${raw}</${node.tagName}>`;
} else { } else {
node.properties.id = slugger.slug(text); node.properties.id = slugger.slug(text);
} }

View file

@ -9,36 +9,36 @@ export default function rehypeJsx(): any {
} }
if (MDX_ELEMENTS.has(child.type)) { if (MDX_ELEMENTS.has(child.type)) {
const attrs = child.attributes.reduce((acc: any[], entry: any) => { const attrs = child.attributes.reduce((acc: any[], entry: any) => {
let attr = entry.value; let attr = entry.value;
if (attr && typeof attr === 'object') { if (attr && typeof attr === 'object') {
attr = `{${attr.value}}`; attr = `{${attr.value}}`;
} else if (attr && entry.type === 'mdxJsxExpressionAttribute') { } else if (attr && entry.type === 'mdxJsxExpressionAttribute') {
attr = `{${attr}}` attr = `{${attr}}`;
} else if (attr === null) { } else if (attr === null) {
attr = ""; attr = '';
} else if (typeof attr === 'string') { } else if (typeof attr === 'string') {
attr = `"${attr}"`; attr = `"${attr}"`;
} }
if (!entry.name) { if (!entry.name) {
return acc + ` ${attr}`; return acc + ` ${attr}`;
} }
return acc + ` ${entry.name}${attr ? '=' : ''}${attr}`; return acc + ` ${entry.name}${attr ? '=' : ''}${attr}`;
}, ''); }, '');
if (child.children.length === 0) { if (child.children.length === 0) {
return { return {
type: 'raw', type: 'raw',
value: `<${child.name}${attrs} />` value: `<${child.name}${attrs} />`,
}; };
} }
child.children.splice(0, 0, { child.children.splice(0, 0, {
type: 'raw', type: 'raw',
value: `\n<${child.name}${attrs}>` value: `\n<${child.name}${attrs}>`,
}) });
child.children.push({ child.children.push({
type: 'raw', type: 'raw',
value: `</${child.name}>\n` value: `</${child.name}>\n`,
}) });
return { return {
...child, ...child,
type: 'element', type: 'element',

View file

@ -8,7 +8,7 @@
* @typedef {import('remark-mdx')} DoNotTouchAsThisImportItIncludesMdxInTree * @typedef {import('remark-mdx')} DoNotTouchAsThisImportItIncludesMdxInTree
*/ */
import {visit} from 'unist-util-visit' import { visit } from 'unist-util-visit';
/** /**
* A tiny plugin that unravels `<p><h1>x</h1></p>` but also * A tiny plugin that unravels `<p><h1>x</h1></p>` but also
@ -19,63 +19,54 @@ import {visit} from 'unist-util-visit'
* @type {import('unified').Plugin<Array<void>, Root>} * @type {import('unified').Plugin<Array<void>, Root>}
*/ */
export default function remarkMarkAndUnravel() { export default function remarkMarkAndUnravel() {
return (tree: any) => { return (tree: any) => {
visit(tree, (node, index, parent_) => { visit(tree, (node, index, parent_) => {
const parent = /** @type {Parent} */ (parent_) const parent = /** @type {Parent} */ parent_;
let offset = -1 let offset = -1;
let all = true let all = true;
/** @type {boolean|undefined} */ /** @type {boolean|undefined} */
let oneOrMore let oneOrMore;
if (parent && typeof index === 'number' && node.type === 'paragraph') { if (parent && typeof index === 'number' && node.type === 'paragraph') {
const children = node.children const children = node.children;
while (++offset < children.length) { while (++offset < children.length) {
const child = children[offset] const child = children[offset];
if ( if (child.type === 'mdxJsxTextElement' || child.type === 'mdxTextExpression') {
child.type === 'mdxJsxTextElement' || oneOrMore = true;
child.type === 'mdxTextExpression' } else if (child.type === 'text' && /^[\t\r\n ]+$/.test(String(child.value))) {
) { // Empty.
oneOrMore = true } else {
} else if ( all = false;
child.type === 'text' && break;
/^[\t\r\n ]+$/.test(String(child.value)) }
) { }
// Empty.
} else {
all = false
break
}
}
if (all && oneOrMore) { if (all && oneOrMore) {
offset = -1 offset = -1;
while (++offset < children.length) { while (++offset < children.length) {
const child = children[offset] const child = children[offset];
if (child.type === 'mdxJsxTextElement') { if (child.type === 'mdxJsxTextElement') {
child.type = 'mdxJsxFlowElement' child.type = 'mdxJsxFlowElement';
} }
if (child.type === 'mdxTextExpression') { if (child.type === 'mdxTextExpression') {
child.type = 'mdxFlowExpression' child.type = 'mdxFlowExpression';
} }
} }
parent.children.splice(index, 1, ...children) parent.children.splice(index, 1, ...children);
return index return index;
} }
} }
if ( if (node.type === 'mdxJsxFlowElement' || node.type === 'mdxJsxTextElement') {
node.type === 'mdxJsxFlowElement' || const data = node.data || (node.data = {});
node.type === 'mdxJsxTextElement' data._mdxExplicitJsx = true;
) { }
const data = node.data || (node.data = {}) });
data._mdxExplicitJsx = true };
}
})
}
} }

View file

@ -1,15 +1,15 @@
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';
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', mdxFromMarkdown());
add('toMarkdownExtensions', mdxToMarkdown()) add('toMarkdownExtensions', mdxToMarkdown());
function add(field: string, value: unknown) { function add(field: string, value: unknown) {
const list = data[field] ? data[field] : (data[field] = []) const list = data[field] ? data[field] : (data[field] = []);
list.push(value) list.push(value);
} }
} }

View file

@ -49,14 +49,23 @@ describe('components', () => {
it('should normalize children', async () => { it('should normalize children', async () => {
const { code } = await renderMarkdown(`<Component bool={true}>Hello world!</Component>`, {}); const { code } = await renderMarkdown(`<Component bool={true}>Hello world!</Component>`, {});
chai.expect(code).to.equal(`<Fragment>\n<Component bool={true}>Hello world!</Component>\n</Fragment>`); chai
.expect(code)
.to.equal(`<Fragment>\n<Component bool={true}>Hello world!</Component>\n</Fragment>`);
}); });
it('should allow markdown without many spaces', async () => { it('should allow markdown without many spaces', async () => {
const { code } = await renderMarkdown(`<Component> const { code } = await renderMarkdown(
`<Component>
# Hello world! # Hello world!
</Component>`, {}); </Component>`,
{}
);
chai.expect(code).to.equal(`<Fragment>\n<Component><h1 id="hello-world">Hello world!</h1></Component>\n</Fragment>`); chai
.expect(code)
.to.equal(
`<Fragment>\n<Component><h1 id="hello-world">Hello world!</h1></Component>\n</Fragment>`
);
}); });
}); });

View file

@ -17,24 +17,35 @@ describe('expressions', () => {
it('should be able to serialize expression inside markdown', async () => { it('should be able to serialize expression inside markdown', async () => {
const { code } = await renderMarkdown(`# {frontmatter.title}`, {}); const { code } = await renderMarkdown(`# {frontmatter.title}`, {});
chai.expect(code).to.equal(`<h1 id={$$slug(\`\${frontmatter.title}\`)}>{frontmatter.title}</h1>`); chai
.expect(code)
.to.equal(`<h1 id={$$slug(\`\${frontmatter.title}\`)}>{frontmatter.title}</h1>`);
}); });
it('should be able to serialize complex expression inside markdown', async () => { it('should be able to serialize complex expression inside markdown', async () => {
const { code } = await renderMarkdown(`# Hello {frontmatter.name}`, {}); const { code } = await renderMarkdown(`# Hello {frontmatter.name}`, {});
chai.expect(code).to.equal(`<h1 id={$$slug(\`Hello \${frontmatter.name}\`)}>Hello {frontmatter.name}</h1>`); chai
.expect(code)
.to.equal(`<h1 id={$$slug(\`Hello \${frontmatter.name}\`)}>Hello {frontmatter.name}</h1>`);
}); });
it('should be able to serialize complex expression with markup inside markdown', async () => { it('should be able to serialize complex expression with markup inside markdown', async () => {
const { code } = await renderMarkdown(`# Hello <span>{frontmatter.name}</span>`, {}); const { code } = await renderMarkdown(`# Hello <span>{frontmatter.name}</span>`, {});
chai.expect(code).to.equal(`<h1 id={$$slug(\`Hello \${frontmatter.name}\`)}>Hello <span>{frontmatter.name}</span></h1>`); chai
.expect(code)
.to.equal(
`<h1 id={$$slug(\`Hello \${frontmatter.name}\`)}>Hello <span>{frontmatter.name}</span></h1>`
);
}); });
it('should be able to serialize function expression', async () => { it('should be able to serialize function expression', async () => {
const { code } = await renderMarkdown(`{frontmatter.list.map(item => <p id={item}>{item}</p>)}` , {}); const { code } = await renderMarkdown(
`{frontmatter.list.map(item => <p id={item}>{item}</p>)}`,
{}
);
chai.expect(code).to.equal(`{frontmatter.list.map(item => <p id={item}>{item}</p>)}`); chai.expect(code).to.equal(`{frontmatter.list.map(item => <p id={item}>{item}</p>)}`);
}) });
}); });

View file

@ -16,11 +16,11 @@ describe('plugins', () => {
}; };
return transformer; return transformer;
} },
] ],
}); });
chai.expect(typeof context).to.equal('object'); chai.expect(typeof context).to.equal('object');
chai.expect(context.path).to.equal(fileURLToPath(new URL('virtual.md', import.meta.url))); chai.expect(context.path).to.equal(fileURLToPath(new URL('virtual.md', import.meta.url)));
}); });
}) });