82 lines
2.0 KiB
Plaintext
82 lines
2.0 KiB
Plaintext
---
|
|
const {code} = Astro.props;
|
|
|
|
let c = trimAndDedent(code as string);
|
|
|
|
/**
|
|
* Performs the following:
|
|
* - Removes the first & last line, if they are empty
|
|
* - Picks the indentation level from the first non-white line
|
|
* - Dedents the following lines
|
|
*/
|
|
function trimAndDedent(input: string): 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.join("\n");
|
|
}
|
|
|
|
---
|
|
|
|
<div>
|
|
Interactive code :D
|
|
<pre class="language-thp" data-disabled><code>{c}</code></pre>
|
|
</div>
|