feat: configure syntax highlighting

This commit is contained in:
Max Richter
2025-09-30 21:01:26 +02:00
parent 2a1572f99d
commit c2179c6d22
8 changed files with 72 additions and 11 deletions

View File

@@ -45,9 +45,13 @@
"@codemirror/lang-javascript": "^6.2.4", "@codemirror/lang-javascript": "^6.2.4",
"@codemirror/lang-json": "^6.0.2", "@codemirror/lang-json": "^6.0.2",
"@codemirror/lang-markdown": "^6.3.4", "@codemirror/lang-markdown": "^6.3.4",
"@codemirror/lang-yaml": "^6.1.2",
"@codemirror/language": "^6.11.3",
"@codemirror/state": "^6.5.2", "@codemirror/state": "^6.5.2",
"@codemirror/view": "^6.38.3", "@codemirror/view": "^6.38.3",
"@fsegurai/codemirror-theme-github-light": "^6.2.2",
"codemirror": "^6.0.2", "codemirror": "^6.0.2",
"codemirror-theme-github": "^1.1.0",
"lucide-svelte": "^0.544.0", "lucide-svelte": "^0.544.0",
"svelte-codemirror-editor": "^2.0.0" "svelte-codemirror-editor": "^2.0.0"
} }

View File

@@ -17,15 +17,27 @@ importers:
'@codemirror/lang-markdown': '@codemirror/lang-markdown':
specifier: ^6.3.4 specifier: ^6.3.4
version: 6.3.4 version: 6.3.4
'@codemirror/lang-yaml':
specifier: ^6.1.2
version: 6.1.2
'@codemirror/language':
specifier: ^6.11.3
version: 6.11.3
'@codemirror/state': '@codemirror/state':
specifier: ^6.5.2 specifier: ^6.5.2
version: 6.5.2 version: 6.5.2
'@codemirror/view': '@codemirror/view':
specifier: ^6.38.3 specifier: ^6.38.3
version: 6.38.3 version: 6.38.3
'@fsegurai/codemirror-theme-github-light':
specifier: ^6.2.2
version: 6.2.2(@codemirror/language@6.11.3)(@codemirror/state@6.5.2)(@codemirror/view@6.38.3)(@lezer/highlight@1.2.1)
codemirror: codemirror:
specifier: ^6.0.2 specifier: ^6.0.2
version: 6.0.2 version: 6.0.2
codemirror-theme-github:
specifier: ^1.1.0
version: 1.1.0
lucide-svelte: lucide-svelte:
specifier: ^0.544.0 specifier: ^0.544.0
version: 0.544.0(svelte@5.39.6) version: 0.544.0(svelte@5.39.6)
@@ -120,6 +132,9 @@ packages:
'@codemirror/lang-markdown@6.3.4': '@codemirror/lang-markdown@6.3.4':
resolution: {integrity: sha512-fBm0BO03azXnTAsxhONDYHi/qWSI+uSEIpzKM7h/bkIc9fHnFp9y7KTMXKON0teNT97pFhc1a9DQTtWBYEZ7ug==} resolution: {integrity: sha512-fBm0BO03azXnTAsxhONDYHi/qWSI+uSEIpzKM7h/bkIc9fHnFp9y7KTMXKON0teNT97pFhc1a9DQTtWBYEZ7ug==}
'@codemirror/lang-yaml@6.1.2':
resolution: {integrity: sha512-dxrfG8w5Ce/QbT7YID7mWZFKhdhsaTNOYjOkSIMt1qmC4VQnXSDSYVHHHn8k6kJUfIhtLo8t1JJgltlxWdsITw==}
'@codemirror/language@6.11.3': '@codemirror/language@6.11.3':
resolution: {integrity: sha512-9HBM2XnwDj7fnu0551HkGdrUrrqmYq/WC5iv6nbY2WdicXdGbhR/gfbZOH73Aqj4351alY1+aoG9rCNfiwS1RA==} resolution: {integrity: sha512-9HBM2XnwDj7fnu0551HkGdrUrrqmYq/WC5iv6nbY2WdicXdGbhR/gfbZOH73Aqj4351alY1+aoG9rCNfiwS1RA==}
@@ -342,6 +357,14 @@ packages:
resolution: {integrity: sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==} resolution: {integrity: sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@fsegurai/codemirror-theme-github-light@6.2.2':
resolution: {integrity: sha512-YQr5MbhMlhRlAQcSCSbet4NDDkMvd5sbUyk9JmM0vfZhQbatvw4c56gNG/54JKGM0kWY5zRWzgLtFuz6D7yEsw==}
peerDependencies:
'@codemirror/language': ^6.0.0
'@codemirror/state': ^6.0.0
'@codemirror/view': ^6.0.0
'@lezer/highlight': ^1.0.0
'@humanfs/core@0.19.1': '@humanfs/core@0.19.1':
resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==}
engines: {node: '>=18.18.0'} engines: {node: '>=18.18.0'}
@@ -402,6 +425,9 @@ packages:
'@lezer/markdown@1.4.3': '@lezer/markdown@1.4.3':
resolution: {integrity: sha512-kfw+2uMrQ/wy/+ONfrH83OkdFNM0ye5Xq96cLlaCy7h5UT9FO54DU4oRoIc0CSBh5NWmWuiIJA7NGLMJbQ+Oxg==} resolution: {integrity: sha512-kfw+2uMrQ/wy/+ONfrH83OkdFNM0ye5Xq96cLlaCy7h5UT9FO54DU4oRoIc0CSBh5NWmWuiIJA7NGLMJbQ+Oxg==}
'@lezer/yaml@1.0.3':
resolution: {integrity: sha512-GuBLekbw9jDBDhGur82nuwkxKQ+a3W5H0GfaAthDXcAu+XdpS43VlnxA9E9hllkpSP5ellRDKjLLj7Lu9Wr6xA==}
'@marijn/find-cluster-break@1.0.2': '@marijn/find-cluster-break@1.0.2':
resolution: {integrity: sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==} resolution: {integrity: sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==}
@@ -798,6 +824,9 @@ packages:
resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
engines: {node: '>=6'} engines: {node: '>=6'}
codemirror-theme-github@1.1.0:
resolution: {integrity: sha512-05qv2eBNdrLvkXx6gdW4IFnRQN0NbUOew8/x4/B62I5UfnIDaPUnoGzqQUluwsBhWTMM7EpFSXSPNCqvcwB89g==}
codemirror@6.0.2: codemirror@6.0.2:
resolution: {integrity: sha512-VhydHotNW5w1UGK0Qj96BwSk/Zqbp9WbnyK2W/eVMv4QyF41INRGpjUhFJY7/uDNuudSc33a/PKr4iDqRduvHw==} resolution: {integrity: sha512-VhydHotNW5w1UGK0Qj96BwSk/Zqbp9WbnyK2W/eVMv4QyF41INRGpjUhFJY7/uDNuudSc33a/PKr4iDqRduvHw==}
@@ -1621,6 +1650,16 @@ snapshots:
'@lezer/common': 1.2.3 '@lezer/common': 1.2.3
'@lezer/markdown': 1.4.3 '@lezer/markdown': 1.4.3
'@codemirror/lang-yaml@6.1.2':
dependencies:
'@codemirror/autocomplete': 6.18.7
'@codemirror/language': 6.11.3
'@codemirror/state': 6.5.2
'@lezer/common': 1.2.3
'@lezer/highlight': 1.2.1
'@lezer/lr': 1.4.2
'@lezer/yaml': 1.0.3
'@codemirror/language@6.11.3': '@codemirror/language@6.11.3':
dependencies: dependencies:
'@codemirror/state': 6.5.2 '@codemirror/state': 6.5.2
@@ -1785,6 +1824,13 @@ snapshots:
'@eslint/core': 0.15.2 '@eslint/core': 0.15.2
levn: 0.4.1 levn: 0.4.1
'@fsegurai/codemirror-theme-github-light@6.2.2(@codemirror/language@6.11.3)(@codemirror/state@6.5.2)(@codemirror/view@6.38.3)(@lezer/highlight@1.2.1)':
dependencies:
'@codemirror/language': 6.11.3
'@codemirror/state': 6.5.2
'@codemirror/view': 6.38.3
'@lezer/highlight': 1.2.1
'@humanfs/core@0.19.1': {} '@humanfs/core@0.19.1': {}
'@humanfs/node@0.16.7': '@humanfs/node@0.16.7':
@@ -1858,6 +1904,12 @@ snapshots:
'@lezer/common': 1.2.3 '@lezer/common': 1.2.3
'@lezer/highlight': 1.2.1 '@lezer/highlight': 1.2.1
'@lezer/yaml@1.0.3':
dependencies:
'@lezer/common': 1.2.3
'@lezer/highlight': 1.2.1
'@lezer/lr': 1.4.2
'@marijn/find-cluster-break@1.0.2': {} '@marijn/find-cluster-break@1.0.2': {}
'@nodelib/fs.scandir@2.1.5': '@nodelib/fs.scandir@2.1.5':
@@ -2221,6 +2273,8 @@ snapshots:
clsx@2.1.1: {} clsx@2.1.1: {}
codemirror-theme-github@1.1.0: {}
codemirror@6.0.2: codemirror@6.0.2:
dependencies: dependencies:
'@codemirror/autocomplete': 6.18.7 '@codemirror/autocomplete': 6.18.7

View File

@@ -1 +1,6 @@
@import 'tailwindcss'; @import 'tailwindcss';
.cm-foldGutter + .cm-foldGutter {
display: none !important;
}

View File

@@ -3,6 +3,7 @@
import MinusCircleIcon from '$lib/icons/MinusCircleIcon.svelte'; import MinusCircleIcon from '$lib/icons/MinusCircleIcon.svelte';
import XCircleIcon from '$lib/icons/XCircleIcon.svelte'; import XCircleIcon from '$lib/icons/XCircleIcon.svelte';
import type { Extension } from '@codemirror/state'; import type { Extension } from '@codemirror/state';
import { githubLight } from '@fsegurai/codemirror-theme-github-light';
import { basicSetup } from 'codemirror'; import { basicSetup } from 'codemirror';
import type { Snippet } from 'svelte'; import type { Snippet } from 'svelte';
import CodeMirror from 'svelte-codemirror-editor'; import CodeMirror from 'svelte-codemirror-editor';
@@ -48,7 +49,7 @@
<MinusCircleIcon class="mr-2 h-5 w-5 text-gray-400" /> <MinusCircleIcon class="mr-2 h-5 w-5 text-gray-400" />
{/if} {/if}
<div class="flex-1"> <div class="flex-1">
<h2 class="flex items-center text-sm font-semibold uppercase tracking-wide text-gray-900"> <h2 class="flex items-center text-sm font-semibold tracking-wide text-gray-900 uppercase">
{title} {title}
{#if pillText} {#if pillText}
<span <span
@@ -81,6 +82,7 @@
<CodeMirror <CodeMirror
bind:value bind:value
extensions={[basicSetup, langExtension].filter(Boolean) as Extension[]} extensions={[basicSetup, langExtension].filter(Boolean) as Extension[]}
theme={githubLight}
{placeholder} {placeholder}
{readonly} {readonly}
class="text-sm" class="text-sm"

View File

@@ -92,7 +92,6 @@ My favourite baguette recipe
const result = templateValue const result = templateValue
? parseMarkdownWithTemplate(markdownValue, templateValue) ? parseMarkdownWithTemplate(markdownValue, templateValue)
: parseMarkdown(markdownValue); : parseMarkdown(markdownValue);
console.log({ result });
if ('error' in result) { if ('error' in result) {
jsonOutput = ''; jsonOutput = '';
@@ -107,12 +106,13 @@ My favourite baguette recipe
} }
} else { } else {
templateError = undefined; templateError = undefined;
jsonOutput = JSON.stringify(result.data, null, 2); jsonOutput = JSON.stringify(result, null, 2);
timings = result.timings; timings = result.timings;
templateStatus = 'success'; templateStatus = 'success';
dataStatus = 'success'; dataStatus = 'success';
} }
} catch (e: unknown) { } catch (e: unknown) {
console.log({ e });
jsonOutput = (e as Error).message; jsonOutput = (e as Error).message;
timings = null; timings = null;
if (jsonOutput.startsWith('failed to compile template')) { if (jsonOutput.startsWith('failed to compile template')) {
@@ -154,7 +154,7 @@ My favourite baguette recipe
{#snippet headerActions()} {#snippet headerActions()}
<select <select
onchange={(e) => loadTemplate(e.currentTarget.value)} onchange={(e) => loadTemplate(e.currentTarget.value)}
class="rounded border border-gray-300 bg-white px-2 py-1 text-xs text-gray-700 shadow-sm focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500" class="rounded border border-gray-300 bg-white px-2 py-1 text-xs text-gray-700 shadow-sm focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 focus:outline-none"
> >
<option value="">Load a template</option> <option value="">Load a template</option>
{#each templates as template (template)} {#each templates as template (template)}
@@ -175,7 +175,7 @@ My favourite baguette recipe
{#snippet headerActions()} {#snippet headerActions()}
<button <button
onclick={resetMarkdown} onclick={resetMarkdown}
class="rounded border border-gray-300 bg-white px-2 py-1 text-xs text-gray-700 shadow-sm focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500" class="rounded border border-gray-300 bg-white px-2 py-1 text-xs text-gray-700 shadow-sm focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 focus:outline-none"
> >
Reset Reset
</button> </button>

Binary file not shown.

View File

@@ -8,7 +8,7 @@ export default defineConfig({
exclude: [ exclude: [
"svelte-codemirror-editor", "svelte-codemirror-editor",
"codemirror", "codemirror",
"@codemirror/language-javascript", /* ... */ "@codemirror/language",
], ],
}, },
}); });

View File

@@ -8,15 +8,11 @@ OUT_WASM="$OUT_DIR/main.wasm"
mkdir -p "$OUT_DIR" mkdir -p "$OUT_DIR"
tinygo build -target=wasm \ tinygo build -target=wasm \
-opt=z -no-debug -panic=print -gc=leaking \ -no-debug -panic=print -gc=leaking \
-o "$OUT_WASM" "$SCRIPT_DIR" -o "$OUT_WASM" "$SCRIPT_DIR"
# Optional post-process (run only if tools exist)
command -v wasm-opt >/dev/null && wasm-opt -Oz --strip-debug --strip-dwarf --strip-producers \ command -v wasm-opt >/dev/null && wasm-opt -Oz --strip-debug --strip-dwarf --strip-producers \
-o "$OUT_WASM.tmp" "$OUT_WASM" && mv "$OUT_WASM.tmp" "$OUT_WASM" -o "$OUT_WASM.tmp" "$OUT_WASM" && mv "$OUT_WASM.tmp" "$OUT_WASM"
# command -v wasm-strip >/dev/null && wasm-strip "$OUT_WASM" # command -v wasm-strip >/dev/null && wasm-strip "$OUT_WASM"
# command -v brotli >/dev/null && brotli -f -q 11 "$OUT_WASM" -o "$OUT_WASM.br"
# command -v gzip >/dev/null && gzip -c -9 "$OUT_WASM" > "$OUT_WASM.gz"
# Copy TinyGo runtime
cp -f "$(tinygo env TINYGOROOT)/targets/wasm_exec.js" "$OUT_DIR/wasm_exec.js" cp -f "$(tinygo env TINYGOROOT)/targets/wasm_exec.js" "$OUT_DIR/wasm_exec.js"