* Fixes #1033 - Markdown with applied scopedStyles doesn't run Prism syntax highlight * Removed the incorrect lang attribute to indicate language syntax * Fixed UT for scopedStyles + markdown * Update packages/astro/test/astro-markdown.test.js Co-authored-by: Caleb Jasik <calebjasik@jasik.xyz> * Added changeset for PR #1037 * Update curly-queens-pay.md Changing from a `minor` release to a `patch` since we're pre-v1.0.0! This Co-authored-by: Vitor Calejuri <vitor.cajuleri@gmail.com> Co-authored-by: Caleb Jasik <calebjasik@jasik.xyz> Co-authored-by: Nate Moore <natemoo-re@users.noreply.github.com>
This commit is contained in:
parent
3f093fa830
commit
2321b577ee
6 changed files with 50 additions and 5 deletions
5
.changeset/curly-queens-pay.md
Normal file
5
.changeset/curly-queens-pay.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
- Allow Markdown with scoped styles to coexist happily with code syntax highlighting via Prism
|
|
@ -3,7 +3,8 @@ import Prism from 'prismjs';
|
|||
import { addAstro } from '@astrojs/prism';
|
||||
import loadLanguages from 'prismjs/components/index.js';
|
||||
|
||||
const { lang, code } = Astro.props;
|
||||
const { class: className, lang, code } = Astro.props;
|
||||
let classLanguage = `language-${lang}`
|
||||
|
||||
const languageMap = new Map([
|
||||
['ts', 'typescript']
|
||||
|
@ -39,7 +40,6 @@ if (grammar) {
|
|||
html = Prism.highlight(code, grammar, lang);
|
||||
}
|
||||
|
||||
let className = lang ? `language-${lang}` : '';
|
||||
---
|
||||
|
||||
<pre class={className}><code class={className}>{html}</code></pre>
|
||||
<pre class={className}><code class={classLanguage}>{html}</code></pre>
|
||||
|
|
|
@ -4,6 +4,7 @@ import { getAttrValue } from '../../ast.js';
|
|||
|
||||
export const PRISM_IMPORT = `import Prism from 'astro/components/Prism.astro';`;
|
||||
const prismImportExp = /import Prism from ['"]astro\/components\/Prism.astro['"]/;
|
||||
|
||||
/** escaping code samples that contain template string replacement parts, ${foo} or example. */
|
||||
function escape(code: string) {
|
||||
return code
|
||||
|
@ -22,6 +23,7 @@ function unescapeCode(code: TemplateNode) {
|
|||
return child;
|
||||
});
|
||||
}
|
||||
|
||||
/** default export - Transform prism */
|
||||
export default function (module: Script): Transformer {
|
||||
let usesPrism = false;
|
||||
|
@ -43,15 +45,17 @@ export default function (module: Script): Transformer {
|
|||
const className = getAttrValue(codeEl.attributes, 'class') || '';
|
||||
const classes = className.split(' ');
|
||||
|
||||
let lang;
|
||||
let lang: string | undefined;
|
||||
for (let cn of classes) {
|
||||
const matches = /language-(.+)/.exec(cn);
|
||||
if (matches) {
|
||||
lang = matches[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!lang) return;
|
||||
let classesWithoutLang = classes.filter((cn) => cn !== `language-${lang}`);
|
||||
|
||||
let codeData = codeEl.children && codeEl.children[0];
|
||||
if (!codeData) return;
|
||||
|
@ -74,6 +78,17 @@ export default function (module: Script): Transformer {
|
|||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'Attribute',
|
||||
name: 'class',
|
||||
value: [
|
||||
{
|
||||
type: 'Text',
|
||||
raw: classesWithoutLang.join(' '),
|
||||
data: classesWithoutLang.join(' '),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'Attribute',
|
||||
name: 'code',
|
||||
|
|
|
@ -35,6 +35,16 @@ Markdown('Runs code blocks through syntax highlighter', async ({ runtime }) => {
|
|||
assert.ok($el.length > 0, 'There are child spans in code blocks');
|
||||
});
|
||||
|
||||
Markdown('Scoped styles should not break syntax highlight', async ({ runtime }) => {
|
||||
const result = await runtime.load('/scopedStyles-code');
|
||||
assert.ok(!result.error, `build error: ${result.error}`);
|
||||
|
||||
const $ = doc(result.contents);
|
||||
assert.ok($('pre').is('[class]'), 'Pre tag has scopedStyle class passed down');
|
||||
assert.ok($('code').hasClass('language-js'), 'Code tag has correct language');
|
||||
assert.ok($('code span').length > 0, 'There are child spans in code blocks');
|
||||
});
|
||||
|
||||
Markdown('Bundles client-side JS for prod', async (context) => {
|
||||
await context.build();
|
||||
|
||||
|
|
14
packages/astro/test/fixtures/astro-markdown/src/pages/scopedStyles-code.astro
vendored
Normal file
14
packages/astro/test/fixtures/astro-markdown/src/pages/scopedStyles-code.astro
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
import { Markdown } from 'astro/components';
|
||||
import Layout from '../layouts/content.astro';
|
||||
|
||||
---
|
||||
<Markdown>
|
||||
<Layout>
|
||||
## Interesting Topic
|
||||
|
||||
```js
|
||||
const thing = () => {};
|
||||
```
|
||||
</Layout>
|
||||
</Markdown>
|
|
@ -4,7 +4,7 @@ import createCollectHeaders from './rehype-collect-headers.js';
|
|||
import scopedStyles from './remark-scoped-styles.js';
|
||||
import remarkExpressions from './remark-expressions.js';
|
||||
import rehypeExpressions from './rehype-expressions.js';
|
||||
import { rehypeCodeBlock } from './codeblock.js';
|
||||
import { remarkCodeBlock, rehypeCodeBlock } from './codeblock.js';
|
||||
import { loadPlugins } from './load-plugins.js';
|
||||
import raw from 'rehype-raw';
|
||||
|
||||
|
@ -56,6 +56,7 @@ export async function renderMarkdown(content: string, opts?: MarkdownRenderingOp
|
|||
parser.use(scopedStyles(scopedClassName));
|
||||
}
|
||||
|
||||
parser.use(remarkCodeBlock());
|
||||
parser.use(markdownToHtml, { allowDangerousHtml: true, passThrough: ['raw', 'mdxTextExpression'] });
|
||||
parser.use(rehypeExpressions);
|
||||
|
||||
|
|
Loading…
Reference in a new issue