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;
--function: #b48ead;
--number: #81a1c1;
--comment: #8fbcbb;
}
pre.codeblock span.keyword {
@ -43,3 +44,7 @@ pre.codeblock span.function {
pre.codeblock span.number {
color: var(--number)
}
pre.codeblock span.comment {
color: var(--comment)
}

View file

@ -1,43 +1,141 @@
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) {
output = output.replaceAll(keyword, `<span class="keyword">${keyword}</span>`)
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++];
}
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;
}
const maps = {
cpp: {
keywords: [
"auto",
"void",
"struct"
],
altkeywords: [
"const",
"static",
"int",
"std::string",
"std::unique_ptr",
"char",
"public",
"private",
"protected"
],
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 take_until = (p) => (peek, take) => {
let b = "";
while (!p()) {
b += peek(0);
take(1);
}
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 '*':
finish();
advance();
newline=false;
newline_count=0;
let depth_em = 1;
let type = "em";
if (match("*")) {
type = "bold";
depth_em = 2;
}
let found_match = () => {
for (let j = 0; j < depth_em; j++) {
if (markdown[i + j] != "*")
return false
if (match("*")) {
type = "embold";
depth_em = 3;
}
return true
}
while (!found_match()) {
current_string += markdown[i];
if (!advance())
break;
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; })
for (let j=0;j<depth_em-1;j++) {
// console.log(markdown[i] == "\n");
advance();
}
advance();
finish(type);
break;
@ -196,6 +194,8 @@ const md2tokens = (markdown, newline) => {
case '`':
finish();
advance();
newline=false;
newline_count=0;
let stop = (i) => markdown[i] == "`";
let type_c = "inlinecode";
let language = "";
@ -209,7 +209,7 @@ const md2tokens = (markdown, newline) => {
current_string = capture_until_predicate(stop);
tokens.push({ type: type_c, content: current_string, language: language });
current_string = "";
if (type_c == "codeblock") { advance(); advance(); } // remove trailing `
if (type_c == "codeblock") { advance(); advance(); newline_count=2; } // remove trailing `
break;
default:
@ -247,6 +247,9 @@ const tokens2html = (tokens) => {
case "em":
output += `<i>${token.content}</i>`
break;
case "embold":
output += `<b><i>${token.content}</i></b>`
break;
case "header":
output += `<h${token.level}>${token.content}</h${token.level}>`
break;
@ -273,6 +276,9 @@ const tokens2html = (tokens) => {
case "link":
output += `<a href="${token.link}">${token.text}</a>`;
break;
default:
throw "Unknown token type " + token.type;
}
}

View file

@ -19,6 +19,10 @@
text-justify: auto;
}
ul,ol {
margin-top:0;
}
img {
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")