Skip to content

Commit 239641e

Browse files
committed
show code language
1 parent 54aee9b commit 239641e

File tree

3 files changed

+37
-16
lines changed

3 files changed

+37
-16
lines changed

docs/system-guide.html

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,6 @@
55
# Observable Notebooks 2.0 <span style="color: var(--theme-foreground-faint);">System guide</span>
66

77
<link rel="stylesheet" href="./style.css">
8-
9-
<style>
10-
11-
figure img {
12-
border-radius: 6px;
13-
}
14-
15-
.sans {
16-
font-family: var(--sans-serif);
17-
}
18-
19-
</style>
208
</script>
219
<script id="38" type="text/markdown">
2210
<aside>This document is itself a notebook, and this paragraph is a Markdown cell.</aside>
@@ -93,7 +81,7 @@
9381
greeting("world")
9482
</script>
9583
<script id="19" type="module" pinned="">
96-
Plot.lineY(aapl, {x: "Date", y: "Close"}).plot({y: {grid: true}})
84+
Plot.lineY(AMZN, {x: "Date", y: "Close"}).plot({y: {grid: true}})
9785
</script>
9886
<script id="56" type="text/markdown">
9987
When a top-level variable is defined as a promise, referencing cells will implicitly await the promise and only see the resolved value.
@@ -184,12 +172,15 @@
184172
<script id="83" type="text/markdown">
185173
Use dollar-curly <code>$\{}</code> expressions to interpolate dynamic JavaScript values into Markdown, including text, DOM nodes, and bits of dynamic Markdown.
186174
</script>
175+
<script id="84" type="text/markdown" pinned="">
176+
Hello, ${atob("d29ybGQ=")}!
177+
</script>
187178
<script id="5" type="text/markdown">
188179
---
189180

190181
## HTML
191182

192-
HTML cells are used similarly to Markdown cells, and also support dollar-curly `$\{…}` interpolation. Unlike Markdown cells, HTML cells automatically escape any interpolated values, providing additional safety when handling dynamic and user-specified content.
183+
HTML cells are used similarly to Markdown cells, and also support dollar-curly <code>$\{}</code> interpolation. Unlike Markdown cells, HTML cells automatically escape any interpolated values, providing additional safety when handling dynamic and user-specified content.
193184
</script>
194185
<script id="73" type="text/html" pinned="">
195186
Interpolated values are considered text, ${"not <i>HTML</i>"}.

src/styles/global.css

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,20 @@ figcaption code {
7979
font-size: inherit;
8080
}
8181

82+
pre[data-language] {
83+
position: relative;
84+
}
85+
86+
pre[data-language]::before {
87+
content: attr(data-language);
88+
float: right;
89+
margin: -4px -8px -4px -4px;
90+
padding: 4px;
91+
font-size: 12px;
92+
line-height: 21px;
93+
color: var(--theme-foreground-muted);
94+
}
95+
8296
h1 code,
8397
h2 code,
8498
h3 code,

src/vite/observable.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ export function observable({
6565
cells ??= document.body.appendChild(document.createElement("main"));
6666
for (const cell of notebook.cells) {
6767
const {id, mode, pinned, value} = cell;
68-
const div = cells.appendChild(document.createElement("div"));
68+
const contents = document.createDocumentFragment();
69+
const div = contents.appendChild(document.createElement("div"));
6970
div.id = `cell-${id}`;
7071
div.className = "observablehq observablehq--cell";
7172
if (mode === "md") {
@@ -82,12 +83,20 @@ export function observable({
8283
}
8384
collectAssets(assets, div);
8485
if (pinned) {
85-
const pre = cells.appendChild(document.createElement("pre"));
86+
const pre = contents.appendChild(document.createElement("pre"));
8687
const code = pre.appendChild(document.createElement("code"));
8788
code.className = `language-${mode}`;
8889
code.textContent = value;
8990
await highlight(code);
9091
}
92+
for (const pre of contents.querySelectorAll("pre")) {
93+
const child = pre.firstElementChild;
94+
if (child?.tagName !== "CODE") continue;
95+
const language = getLanguage(child);
96+
if (!language) continue;
97+
pre.dataset.language = language;
98+
}
99+
cells.appendChild(contents);
91100
}
92101

93102
// Don’t error if assets are missing (matching Vite’s behavior).
@@ -210,3 +219,10 @@ function isSpaceCode(code: number): boolean {
210219
function escapeScript(script: string): string {
211220
return script.replace(/<\/script>/g, "<\\/script>"); // TODO handle other contexts
212221
}
222+
223+
function getLanguage(code: Element): string | undefined {
224+
return [...code.classList]
225+
.find((c) => c.startsWith("language-"))
226+
?.slice("language-".length)
227+
?.toLowerCase();
228+
}

0 commit comments

Comments
 (0)