From ccafa8d230f65c9302421a0ce0a0adc5824bfd55 Mon Sep 17 00:00:00 2001 From: 604qgc <130194823+604qgc@users.noreply.github.com> Date: Wed, 10 Apr 2024 18:55:31 +0200 Subject: [PATCH] Adds dataLanguage property to the replacement
 element.
 (#10538)

* Update highlight.ts

* Create cold-snakes-train.md

* Update Code.astro

Solution for use-case described in withastro/roadmap#276 (https://github.com/withastro/roadmap/discussions/276)

* roll-back initial fix

* new fix

* update changeset

* Update packages/markdown/remark/src/rehype-prism.ts

* Update .changeset/cold-snakes-train.md

Co-authored-by: Sarah Rainsberger 

* Update .changeset/cold-snakes-train.md

Co-authored-by: Sarah Rainsberger 

* Update .changeset/cold-snakes-train.md

Co-authored-by: Sarah Rainsberger 

* Update .changeset/cold-snakes-train.md

Co-authored-by: Sarah Rainsberger 

---------

Co-authored-by: Bjorn Lu 
Co-authored-by: Matthew Phillips 
Co-authored-by: Sarah Rainsberger 
---
 .changeset/cold-snakes-train.md              | 42 ++++++++++++++++++++
 packages/markdown/remark/src/rehype-prism.ts |  2 +-
 packages/markdown/remark/src/shiki.ts        |  5 ++-
 3 files changed, 47 insertions(+), 2 deletions(-)
 create mode 100644 .changeset/cold-snakes-train.md

diff --git a/.changeset/cold-snakes-train.md b/.changeset/cold-snakes-train.md
new file mode 100644
index 0000000000..0bab4f40e6
--- /dev/null
+++ b/.changeset/cold-snakes-train.md
@@ -0,0 +1,42 @@
+---
+"@astrojs/markdown-remark": minor
+---
+
+Adds a `data-language` attribute on the rendered `pre` elements to expose the highlighted syntax language.
+
+For example, the following Markdown code block will expose `data-language="python"`:
+```
+\```python
+def func():
+    print('Hello Astro!')
+\```
+```
+
+This allows retrieving the language in a rehype plugin from `node.properties.dataLanguage` by accessing the `
` element using `{ tagName: "pre" }`:
+```js
+// myRehypePre.js
+import { visit } from "unist-util-visit";
+export default function myRehypePre() {
+  return (tree) => {
+    visit(tree, { tagName: "pre" }, (node) => {
+      const lang = node.properties.dataLanguage;
+      [...]
+    });
+  };
+}
+```
+
+Note: The `
` element is not exposed when using Astro's `` component which outputs flattened HTML.
+
+
+The `data-language` attribute may also be used in css rules:
+```css
+pre::before {
+    content: attr(data-language);
+}
+
+pre[data-language="javascript"] {
+  font-size: 2rem;
+}
+```
+
diff --git a/packages/markdown/remark/src/rehype-prism.ts b/packages/markdown/remark/src/rehype-prism.ts
index 2729948ddd..7f713ddf2f 100644
--- a/packages/markdown/remark/src/rehype-prism.ts
+++ b/packages/markdown/remark/src/rehype-prism.ts
@@ -9,7 +9,7 @@ export const rehypePrism: Plugin<[], Root> = () => {
 			let { html, classLanguage } = runHighlighterWithAstro(language, code);
 
 			return Promise.resolve(
-				`
${html}
` + `
${html}
` ); }); }; diff --git a/packages/markdown/remark/src/shiki.ts b/packages/markdown/remark/src/shiki.ts index f3f9d63bf4..798956216d 100644 --- a/packages/markdown/remark/src/shiki.ts +++ b/packages/markdown/remark/src/shiki.ts @@ -102,7 +102,10 @@ export async function createShikiHighlighter({ // Replace "shiki" class naming with "astro-code" node.properties.class = classValue.replace(/shiki/g, 'astro-code'); - + + // Add data-language attribute + node.properties.dataLanguage = lang; + // Handle code wrapping // if wrap=null, do nothing. if (wrap === false) {