website/public/js/code_highlighter.js
Snorre Ettrup Altschul 5f0d70011a
All checks were successful
Restart Website Service / restart_service (push) Successful in 30s
removed all posts
2025-04-01 21:56:55 +02:00

207 lines
4 KiB
JavaScript

const highlight = (map, source) => {
let output = "";
let i = 0;
while (i < source.length) {
for (f of map.rules) {
let p = f((j) => source[i + j], (j) => { i += j });
if (p != undefined)
output += p;
}
output += source[i++];
}
return output;
}
const match = (m) => (peek, take) => {
for (let i = 0; i < m.length; i++)
if (peek(i) != m[i])
return false;
take(m.length);
return true;
}
const match_identifier = (m) => (peek, take) => {
try {
if (peek(-1).match(/[0-9a-z_]/))
return false;
} catch {}
if (match(m)(peek, take)) {
if (peek(0).match(/[0-9a-z]/)) {
take(-m.length);
return false
}
return true;
}
return false;
}
const take_until = (p) => (peek, take) => {
let b = "";
while (!p()) {
b += peek(0);
take(1);
}
return b;
}
const simpleHighlight = (c) => (keyword) => (peek, take) => {
if (match_identifier(keyword)(peek, take))
return `<span class="${c}">${keyword}</span>`;
}
const keyword = simpleHighlight("keyword");
const altKeyword = simpleHighlight("keyword-alt");
const comment = (prefix) => (peek, take) => {
if (match(prefix)(peek, take)) {
let b = prefix;
b += take_until(() => peek(0) == "\n")(peek, take);
return `<span class="comment">${b}</span>`
}
}
const multiline_comment = (prefix, suffix) => (peek, take) => {
if (match(prefix)(peek, take)) {
let b = prefix;
b += take_until(() => match(suffix)(peek, take))(peek, take);
b += suffix;
return `<span class="comment">${b}</span>`
}
}
const string = (c) => (peek, take) => {
if (match(c)(peek, take)) {
let b = c;
b += take_until(() => match(c)(peek, take))(peek, take);
b += c;
return `<span class="string">${b}</span>`
}
}
// keywords: [
// "auto",
// "void",
// "struct"
// ],
// altkeywords: [
// "const",
// "static",
// "int",
// "std::string",
// "std::unique_ptr",
// "char",
// "public",
// "private",
// "protected"
// ],
const maps = {
cpp: {
rules: [
comment("//"),
multiline_comment("/*", "*/"),
string("\""),
// single char
(peek, take) => {
if (peek(0) == "'") {
let b = peek(1);
take(3);
return `<span class="string">'${b}'</span>`;
}
},
keyword("auto"),
keyword("void"),
keyword("class"),
keyword("struct"),
keyword("std::string"),
altKeyword("const"),
altKeyword("static"),
altKeyword("int"),
altKeyword("char"),
altKeyword("private"),
altKeyword("public"),
altKeyword("protected"),
altKeyword("abstract"),
altKeyword("override"),
altKeyword("return"),
],
},
nix: {
rules: [
comment("#"),
string("\""),
string("''"),
keyword("@"),
keyword("nixpkgs"),
keyword("builtins"),
altKeyword("let"),
altKeyword("in"),
altKeyword("with"),
altKeyword("inherit"),
altKeyword("import"),
],
},
rust: {
rules: [
comment("//"),
string("\""),
// single char
(peek, take) => {
if (peek(0) == "'") {
let b = peek(1);
take(3);
return `<span class="string">'${b}'</span>`;
}
},
keyword("fn"),
keyword("struct"),
keyword("enum"),
keyword("trait"),
keyword("Option"),
keyword("Some"),
keyword("None"),
keyword("Result"),
keyword("Ok"),
keyword("Err"),
keyword("in"),
keyword("Self"),
keyword("mut"),
altKeyword("if"),
altKeyword("else"),
altKeyword("match"),
altKeyword("loop"),
altKeyword("for"),
altKeyword("while"),
altKeyword("return"),
altKeyword("async"),
altKeyword("await"),
altKeyword("mod"),
altKeyword("use"),
altKeyword("pub"),
altKeyword("impl"),
altKeyword("crate"),
altKeyword("let"),
altKeyword("const"),
altKeyword("static"),
]
}
};