Fixes #1033 - Markdown with applied scopedStyles doesn't run Prism syntax highlight (#1037)

* 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:
Barrabin ⚑ 2021-08-11 18:52:27 -03:00 committed by GitHub
parent 3f093fa830
commit 2321b577ee
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 50 additions and 5 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
- Allow Markdown with scoped styles to coexist happily with code syntax highlighting via Prism

View file

@ -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>

View file

@ -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',

View file

@ -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();

View 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>

View file

@ -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);