Remove client side syntax highlighting
This commit is contained in:
parent
631acc8122
commit
ebf62bcd5c
@ -1,7 +1,11 @@
|
||||
---
|
||||
import { leftTrimDedent } from "./utils";
|
||||
import { thp_highlighter } from "../lexer/highlighter";
|
||||
|
||||
const { thpcode } = Astro.props;
|
||||
const html_code = thp_highlighter(leftTrimDedent(thpcode).join("\n"));
|
||||
---
|
||||
|
||||
<pre class="language-thp" data-language="thp"><code class="language-thp">{leftTrimDedent(thpcode).join("\n")}</code></pre>
|
||||
<pre
|
||||
class="language-thp"
|
||||
data-language="thp"><code class="language-thp" set:html={html_code} /><span class="absolute top-2 right-2 inline-block text-sm select-none opacity-75">thp</span></pre>
|
||||
|
@ -1,13 +1,11 @@
|
||||
---
|
||||
import { trimAndDedent } from "./utils";
|
||||
import Code from "./Code.astro"
|
||||
|
||||
const { thpcode } = Astro.props;
|
||||
---
|
||||
|
||||
<div class="flex h-full py-8 items-center">
|
||||
<div class="p-4 w-full">
|
||||
<pre
|
||||
class="language-thp"
|
||||
data-language="thp"><code class="language-thp">{trimAndDedent(thpcode).join("\n")}</code></pre>
|
||||
<Code thpcode={thpcode} />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -2,7 +2,7 @@
|
||||
import { lex } from "../lexer/lexer";
|
||||
import type { Instruction } from "../thp_machine/machine_parser";
|
||||
import { parse_str } from "../thp_machine/machine_parser";
|
||||
import { trimAndDedent } from "./utils";
|
||||
import { leftTrimDedent } from "./utils";
|
||||
const { code, steps } = Astro.props;
|
||||
|
||||
function highlightCode(lines: Array<string>): string {
|
||||
@ -31,7 +31,7 @@ function highlightCode(lines: Array<string>): string {
|
||||
return outLines.join("\n");
|
||||
}
|
||||
|
||||
const codeHtml = highlightCode(trimAndDedent(code));
|
||||
const codeHtml = highlightCode(leftTrimDedent(code));
|
||||
let instructionSet: Array<Array<Instruction>>;
|
||||
try {
|
||||
instructionSet = parse_str(steps);
|
||||
|
@ -5,70 +5,6 @@
|
||||
* - Picks the indentation level from the first non-white line
|
||||
* - Dedents the following lines
|
||||
*/
|
||||
export function trimAndDedent(input: string): Array<string> {
|
||||
let lines = input.split("\n");
|
||||
|
||||
// Remove empty lines at the start
|
||||
while (lines[0] === "") {
|
||||
lines = lines.slice(1);
|
||||
}
|
||||
|
||||
// Get indentation level
|
||||
let indentationLevel = 0;
|
||||
for (const char of lines[0]!) {
|
||||
if (char === " ") {
|
||||
indentationLevel += 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Enforce indentation, or trim
|
||||
for (let i = 0; i < lines.length; i += 1) {
|
||||
// If the line is empty, continue
|
||||
const characters = lines[i]!.split("");
|
||||
if (characters.length === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If all characters are whitespace, append just a newline
|
||||
const nonWhitespace = characters.find((x) => x !== " ");
|
||||
if (nonWhitespace === undefined) {
|
||||
lines[i] = "";
|
||||
continue;
|
||||
}
|
||||
|
||||
// Enforce indentation
|
||||
if (characters.length < indentationLevel) {
|
||||
throw new Error("Invalid indentation while parsing THP code: " + lines[i]);
|
||||
}
|
||||
let currentIndentation = 0;
|
||||
for (const c of characters) {
|
||||
if (c === " ") { currentIndentation += 1 }
|
||||
else { break; }
|
||||
}
|
||||
if (currentIndentation < indentationLevel) {
|
||||
throw new Error("Invalid indentation while parsing THP code: " + lines[i]);
|
||||
}
|
||||
|
||||
lines[i] = characters.slice(4).join("");
|
||||
}
|
||||
|
||||
|
||||
// Remove empty lines at the end
|
||||
let endPosition = lines.length - 1;
|
||||
while (true) {
|
||||
if (lines[endPosition] === "") {
|
||||
lines = lines.slice(0, -1);
|
||||
endPosition -= 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
export function leftTrimDedent(input: string): Array<string> {
|
||||
let lines = input.split("\n");
|
||||
let output: Array<string> = [];
|
||||
|
@ -1,48 +1,4 @@
|
||||
import { thp_highlighter, CodeJar } from "../lexer/highlighter";
|
||||
|
||||
/**
|
||||
* Highlights all THP code snippets mounted in the DOM with class .language-thp
|
||||
*
|
||||
* It assumes that the code is inside: <pre class="language-thp"><code>...
|
||||
*/
|
||||
export function highlightOnDom() {
|
||||
const code_elements = document.querySelectorAll("code.language-thp");
|
||||
|
||||
for (const e of [...code_elements]) {
|
||||
const el = e as HTMLElement;
|
||||
// Some elements with .language-thp don't want to be processed
|
||||
if (e.getAttribute("data-disabled") !== null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const pre_parent = el.parentElement!;
|
||||
const new_div = document.createElement("div");
|
||||
let code = el.innerHTML;
|
||||
|
||||
// Replace all < with < and all > with >
|
||||
code = code.replace(/</g, "<").replace(/>/g, ">");
|
||||
|
||||
el.parentElement!.className = "language-thp";
|
||||
pre_parent.removeChild(el);
|
||||
pre_parent.appendChild(new_div);
|
||||
|
||||
// Create and append a language name indicator
|
||||
|
||||
CodeJar(new_div, thp_highlighter, {
|
||||
tab: " ",
|
||||
}).updateCode(code);
|
||||
}
|
||||
|
||||
const pre_elements = document.querySelectorAll("pre");
|
||||
for (const pre_el of pre_elements) {
|
||||
const language = pre_el.getAttribute("data-language");
|
||||
if (language === null) { continue; }
|
||||
|
||||
// Create a visual indicador
|
||||
const indicator = document.createElement("span");
|
||||
indicator.className = "absolute top-2 right-2 inline-block text-sm select-none opacity-75";
|
||||
indicator.innerText = language;
|
||||
pre_el.appendChild(indicator);
|
||||
}
|
||||
}
|
||||
export function highlightOnDom() {}
|
||||
|
||||
|
@ -1,9 +1,6 @@
|
||||
import { lex } from "./lexer";
|
||||
import {CodeJar as Codejar} from "codejar";
|
||||
|
||||
export function thp_highlighter(editor: any) {
|
||||
let code: string = editor.textContent;
|
||||
|
||||
export function thp_highlighter(code: string) {
|
||||
let tokens = lex(code);
|
||||
|
||||
let highlighted_code = "";
|
||||
@ -12,7 +9,5 @@ export function thp_highlighter(editor: any) {
|
||||
highlighted_code += `<span class="token ${token.token_type}">${token.v}</span>`;
|
||||
}
|
||||
|
||||
editor.innerHTML = highlighted_code;
|
||||
return highlighted_code;
|
||||
}
|
||||
|
||||
export const CodeJar = Codejar;
|
||||
|
@ -2,6 +2,28 @@
|
||||
import BaseLayout from "../layouts/BaseLayout.astro";
|
||||
import Navbar from "../components/Navbar.astro";
|
||||
import HeroSection from "../components/HeroSection.astro";
|
||||
import { thp_highlighter } from "../lexer/highlighter";
|
||||
import { leftTrimDedent } from "../components/utils";
|
||||
|
||||
const thpcode = `union Animal {
|
||||
Dog(String),
|
||||
Cat(String, Int),
|
||||
}
|
||||
|
||||
val cat_name = Post::get("cat_name") ?? "Michifu"
|
||||
val my_cat = Animal::Cat(cat_name, 9)
|
||||
|
||||
try change_fur_color(cat) else die("Not a cat")
|
||||
|
||||
match random_animal()
|
||||
case Dog(name)
|
||||
{
|
||||
print("{name} has 1 live ")
|
||||
}
|
||||
case Cat(name, lives)
|
||||
{
|
||||
print("{name} has {lives}")
|
||||
}`;
|
||||
---
|
||||
|
||||
<BaseLayout>
|
||||
@ -95,7 +117,9 @@ import HeroSection from "../components/HeroSection.astro";
|
||||
</g>
|
||||
</svg>
|
||||
<div class="h-1"></div>
|
||||
<div id="editor" class="font-mono language-thp"></div>
|
||||
<div id="editor" class="font-mono language-thp">
|
||||
<pre set:html={thp_highlighter(leftTrimDedent(thpcode).join("\n"))}></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -194,38 +218,4 @@ import HeroSection from "../components/HeroSection.astro";
|
||||
<br>
|
||||
Nullable types must be explicitly checked before using them.
|
||||
</HeroSection>
|
||||
|
||||
<script>
|
||||
import { thp_highlighter, CodeJar } from "../lexer/highlighter";
|
||||
|
||||
let jar = CodeJar(document.getElementById("editor")!, thp_highlighter, {
|
||||
tab: " ",
|
||||
});
|
||||
|
||||
jar.updateCode(
|
||||
`union Animal {
|
||||
Dog(String),
|
||||
Cat(String, Int),
|
||||
}
|
||||
|
||||
val cat_name = Post::get("cat_name") ?? "Michifu"
|
||||
val my_cat = Animal::Cat(cat_name, 9)
|
||||
|
||||
try change_fur_color(cat) else die("Not a cat")
|
||||
|
||||
match random_animal()
|
||||
case Dog(name)
|
||||
{
|
||||
print("{name} has 1 live ")
|
||||
}
|
||||
case Cat(name, lives)
|
||||
{
|
||||
print("{name} has {lives}")
|
||||
}`,
|
||||
);
|
||||
</script>
|
||||
<script>
|
||||
import { highlightOnDom } from "../layouts/thpHighlighter";
|
||||
document.addEventListener("DOMContentLoaded", highlightOnDom);
|
||||
</script>
|
||||
</BaseLayout>
|
||||
|
@ -101,6 +101,3 @@ fun TransactionItem(Transaction t) {
|
||||
`} />
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user