Oops, more languages

This commit is contained in:
Snorre 2025-02-06 15:00:38 +01:00
parent de72f2fa7d
commit 56d8a28c0a
5 changed files with 224 additions and 46 deletions

View file

@ -22,6 +22,7 @@ pre.codeblock {
--string: #a3be8c; --string: #a3be8c;
--function: #b48ead; --function: #b48ead;
--number: #81a1c1; --number: #81a1c1;
--comment: #8fbcbb;
} }
pre.codeblock span.keyword { pre.codeblock span.keyword {
@ -43,3 +44,7 @@ pre.codeblock span.function {
pre.codeblock span.number { pre.codeblock span.number {
color: var(--number) color: var(--number)
} }
pre.codeblock span.comment {
color: var(--comment)
}

View file

@ -1,43 +1,141 @@
const highlight = (map, source) => { const highlight = (map, source) => {
let output = source; let output = "";
output = output.replace(/("[^"]+")/g, `<span class="string">$1</span>`) let i = 0;
for (let keyword of map.keywords) { while (i < source.length) {
output = output.replaceAll(keyword, `<span class="keyword">${keyword}</span>`) for (f of map.rules) {
let p = f((j) => source[i + j], (j) => { i += j });
if (p != undefined)
output += p;
}
output += source[i++];
} }
for (let keyword of map.altkeywords) {
output = output.replaceAll(keyword, `<span class="keyword-alt">${keyword}</span>`)
}
// TODO: predicate for function calls to be replaced
// for (let func in map.functions) {
// output = output.replace(func, `<span class="function">${func}</span>`)
// }
output = output.replace(/(\d+)/g, `<span class="number">$1</span>`)
return output; return output;
} }
const maps = { const match = (m) => (peek, take) => {
cpp: { for (let i = 0; i < m.length; i++)
keywords: [ if (peek(i) != m[i])
"auto", return false;
"void", take(m.length);
"struct" return true;
], }
altkeywords: [ const take_until = (p) => (peek, take) => {
"const", let b = "";
"static", while (!p()) {
"int", b += peek(0);
"std::string", take(1);
"std::unique_ptr",
"char",
"public",
"private",
"protected"
],
} }
return b;
}
const simpleHighlight = (c) => (keyword) => (peek, take) => {
if (match(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"),
],
},
}; };

View file

@ -67,29 +67,27 @@ const md2tokens = (markdown, newline) => {
case '*': case '*':
finish(); finish();
advance(); advance();
newline=false;
newline_count=0;
let depth_em = 1; let depth_em = 1;
let type = "em"; let type = "em";
if (match("*")) { if (match("*")) {
type = "bold"; type = "bold";
depth_em = 2; depth_em = 2;
}
let found_match = () => { if (match("*")) {
for (let j = 0; j < depth_em; j++) { type = "embold";
if (markdown[i + j] != "*") depth_em = 3;
return false
} }
return true
} }
while (!found_match()) { current_string = capture_until_predicate((i) => { let found = true; for (let j = 0; j < depth_em; j++) { if (markdown[i + j] != "*") { found = false; break; } } return found; })
current_string += markdown[i];
if (!advance()) for (let j=0;j<depth_em-1;j++) {
break; // console.log(markdown[i] == "\n");
advance();
} }
advance();
finish(type); finish(type);
break; break;
@ -196,6 +194,8 @@ const md2tokens = (markdown, newline) => {
case '`': case '`':
finish(); finish();
advance(); advance();
newline=false;
newline_count=0;
let stop = (i) => markdown[i] == "`"; let stop = (i) => markdown[i] == "`";
let type_c = "inlinecode"; let type_c = "inlinecode";
let language = ""; let language = "";
@ -209,7 +209,7 @@ const md2tokens = (markdown, newline) => {
current_string = capture_until_predicate(stop); current_string = capture_until_predicate(stop);
tokens.push({ type: type_c, content: current_string, language: language }); tokens.push({ type: type_c, content: current_string, language: language });
current_string = ""; current_string = "";
if (type_c == "codeblock") { advance(); advance(); } // remove trailing ` if (type_c == "codeblock") { advance(); advance(); newline_count=2; } // remove trailing `
break; break;
default: default:
@ -247,6 +247,9 @@ const tokens2html = (tokens) => {
case "em": case "em":
output += `<i>${token.content}</i>` output += `<i>${token.content}</i>`
break; break;
case "embold":
output += `<b><i>${token.content}</i></b>`
break;
case "header": case "header":
output += `<h${token.level}>${token.content}</h${token.level}>` output += `<h${token.level}>${token.content}</h${token.level}>`
break; break;
@ -273,6 +276,9 @@ const tokens2html = (tokens) => {
case "link": case "link":
output += `<a href="${token.link}">${token.text}</a>`; output += `<a href="${token.link}">${token.text}</a>`;
break; break;
default:
throw "Unknown token type " + token.type;
} }
} }

View file

@ -19,6 +19,10 @@
text-justify: auto; text-justify: auto;
} }
ul,ol {
margin-top:0;
}
img { img {
background-color: var(--background-text); background-color: var(--background-text);

65
public/posts/test.md Normal file
View file

@ -0,0 +1,65 @@
0
Test
# H1
## H2
### H3
#### H4
##### H5
This is regular text
[This is a link](#)
*italic text*
**bold text**
***bold italic***
`this is an inline code block`
```
this is a code block
```
```cpp
/*
* TEST CPP CODEBLOCK
*/
void main(int argc, char** argv) {
std::string this = "c++ code block";
return 0;
}
class TestClass : AbstractTestClass {
public:
TestClass();
~TestClass();
private:
void DoStuff() override {
// do some stuff
}
};
```
```nix
{ ... }:
let
this = "a nix code block";
in
{
posts.test.content = ''
multiline string
'';
website.backend = (pkgs.callPackage (import gitlab:SpoodyTheOne/webbisitey) {});
}
```
- List
- Test
- here
![test broken image](broken_image.png)
![test image](/test.png)
![test image](/test.png "Image with caption")