more markdown
This commit is contained in:
parent
e3c8ab0abb
commit
02cacc9a82
40
public/code_highlighter.js
Normal file
40
public/code_highlighter.js
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
const highlight = (map, source) => {
|
||||||
|
let output = source;
|
||||||
|
|
||||||
|
output = output.replace(/("[^"]+")/g, `<span class="string">$1</span>`)
|
||||||
|
|
||||||
|
for (let keyword of map.keywords) {
|
||||||
|
output = output.replaceAll(keyword, `<span class="keyword">${keyword}</span>`)
|
||||||
|
}
|
||||||
|
|
||||||
|
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",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
};
|
43
public/colours.css
Normal file
43
public/colours.css
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
:root {
|
||||||
|
--background: #2e3440;
|
||||||
|
--background-text: #3b4252;
|
||||||
|
--border: #5e81ac;
|
||||||
|
--border2: #b48ead;
|
||||||
|
--text: #eceff4;
|
||||||
|
--link: #88c0d0;
|
||||||
|
--link-visited: #81a1c1;
|
||||||
|
|
||||||
|
--padding: 10px 20px;
|
||||||
|
--margin: 4px;
|
||||||
|
--gap: 10px;
|
||||||
|
|
||||||
|
--radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre.codeblock {
|
||||||
|
--keyword: #ebcb8b;
|
||||||
|
--keyword-alt: #bf616a;
|
||||||
|
--string: #a3be8c;
|
||||||
|
--function: #b48ead;
|
||||||
|
--number: #81a1c1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre.codeblock span.keyword {
|
||||||
|
color: var(--keyword);
|
||||||
|
}
|
||||||
|
|
||||||
|
pre.codeblock span.keyword-alt {
|
||||||
|
color: var(--keyword-alt);
|
||||||
|
}
|
||||||
|
|
||||||
|
pre.codeblock span.string {
|
||||||
|
color: var(--string)
|
||||||
|
}
|
||||||
|
|
||||||
|
pre.codeblock span.function {
|
||||||
|
color: var(--function)
|
||||||
|
}
|
||||||
|
|
||||||
|
pre.codeblock span.number {
|
||||||
|
color: var(--number)
|
||||||
|
}
|
|
@ -1,20 +1,5 @@
|
||||||
@import url(https://fonts.bunny.net/css?family=chivo-mono:500);
|
@import url(https://fonts.bunny.net/css?family=chivo-mono:500);
|
||||||
|
@import url(/colours.css);
|
||||||
:root {
|
|
||||||
--background: #2e3440;
|
|
||||||
--background-text: #3b4252;
|
|
||||||
--border: #5e81ac;
|
|
||||||
--border2: #b48ead;
|
|
||||||
--text: #eceff4;
|
|
||||||
--link: #88c0d0;
|
|
||||||
--link-visited: #81a1c1;
|
|
||||||
|
|
||||||
--padding: 10px 20px;
|
|
||||||
--margin: 4px;
|
|
||||||
--gap: 10px;
|
|
||||||
|
|
||||||
--radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
code {
|
code {
|
||||||
background: var(--background-text);
|
background: var(--background-text);
|
||||||
|
@ -23,6 +8,14 @@ code {
|
||||||
border-radius: var(--radius);
|
border-radius: var(--radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pre.codeblock {
|
||||||
|
background: var(--background-text);
|
||||||
|
color: var(--text);
|
||||||
|
padding: 2px 4px;
|
||||||
|
border-radius: var(--radius);
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
color: var(--text);
|
color: var(--text);
|
||||||
background-color: var(--background);
|
background-color: var(--background);
|
||||||
|
@ -31,6 +24,7 @@ html {
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background-color: initial !important;
|
background-color: initial !important;
|
||||||
|
font-variant-ligatures: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
|
|
|
@ -16,6 +16,10 @@ const md2tokens = (markdown, newline) => {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let peek = (a) => {
|
||||||
|
return markdown[i + a];
|
||||||
|
}
|
||||||
|
|
||||||
let advance = () => {
|
let advance = () => {
|
||||||
i++;
|
i++;
|
||||||
if (i < markdown.length)
|
if (i < markdown.length)
|
||||||
|
@ -25,8 +29,12 @@ const md2tokens = (markdown, newline) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
let capture_until = (c) => {
|
let capture_until = (c) => {
|
||||||
|
return capture_until_predicate((i) => markdown[i] == c);
|
||||||
|
}
|
||||||
|
|
||||||
|
let capture_until_predicate = (f) => {
|
||||||
let capture = "";
|
let capture = "";
|
||||||
while (markdown[i] != c && markdown.length > i) {
|
while (!f(i) && markdown.length > i) {
|
||||||
capture += markdown[i];
|
capture += markdown[i];
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
@ -95,7 +103,6 @@ const md2tokens = (markdown, newline) => {
|
||||||
let depth_he = 0;
|
let depth_he = 0;
|
||||||
do {
|
do {
|
||||||
depth_he++;
|
depth_he++;
|
||||||
|
|
||||||
} while (match("#"));
|
} while (match("#"));
|
||||||
|
|
||||||
while (markdown[i] != "\n" && markdown.length > i) {
|
while (markdown[i] != "\n" && markdown.length > i) {
|
||||||
|
@ -124,17 +131,19 @@ const md2tokens = (markdown, newline) => {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let url = capture_until("\"");
|
let url = capture_until_predicate((i) => markdown[i] == "\"" || markdown[i] == ")");
|
||||||
advance();
|
let title = "";
|
||||||
let title = capture_until("\"");
|
if (match("\"")) { // has title
|
||||||
advance();
|
title = capture_until("\"");
|
||||||
|
advance();
|
||||||
|
}
|
||||||
if (!match(")")) {
|
if (!match(")")) {
|
||||||
current_string = `;
|
def();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
tokens.push({type:"image", alt: alt_text, url: url, title: title})
|
tokens.push({ type: "image", alt: alt_text, url: url, title: title })
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '-':
|
case '-':
|
||||||
|
@ -153,25 +162,54 @@ const md2tokens = (markdown, newline) => {
|
||||||
items.push(md2tokens(text, false));
|
items.push(md2tokens(text, false));
|
||||||
} while (match("-"));
|
} while (match("-"));
|
||||||
|
|
||||||
tokens.push({type:"ul", items: items});
|
tokens.push({ type: "ul", items: items });
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '\n':
|
case '\n':
|
||||||
if (newline_count > 2)
|
if (newline_count > 2)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
newline = true;
|
newline = true;
|
||||||
newline_count++;
|
newline_count++;
|
||||||
finish();
|
finish();
|
||||||
tokens.push({ type: "newline" })
|
tokens.push({ type: "newline" })
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case '[':
|
||||||
|
finish();
|
||||||
|
advance();
|
||||||
|
let text = capture_until("]");
|
||||||
|
advance();
|
||||||
|
|
||||||
|
if (!match("(")) {
|
||||||
|
current_string = `[${text}]`;
|
||||||
|
def();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let link = capture_until(")");
|
||||||
|
|
||||||
|
tokens.push({ type: "link", link: link, text: text });
|
||||||
|
break;
|
||||||
|
|
||||||
case '`':
|
case '`':
|
||||||
finish();
|
finish();
|
||||||
advance();
|
advance();
|
||||||
current_string = capture_until("`");
|
let stop = (i) => markdown[i] == "`";
|
||||||
finish("inlinecode");
|
let type_c = "inlinecode";
|
||||||
|
let language = "";
|
||||||
|
if (peek(0) == "`" && peek(1) == "`") { // multiline code block
|
||||||
|
advance(); advance();
|
||||||
|
language = capture_until("\n");
|
||||||
|
let f = (i) => markdown[i] == "`";
|
||||||
|
stop = (i) => f(i) && f(i + 1) && f(i + 2);
|
||||||
|
type_c = "codeblock";
|
||||||
|
}
|
||||||
|
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 `
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -187,6 +225,14 @@ const md2tokens = (markdown, newline) => {
|
||||||
return tokens;
|
return tokens;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const highlight_code = (language, code) => {
|
||||||
|
let map = maps[language];
|
||||||
|
if (map == undefined)
|
||||||
|
return code;
|
||||||
|
|
||||||
|
return highlight(map, code);
|
||||||
|
}
|
||||||
|
|
||||||
const tokens2html = (tokens) => {
|
const tokens2html = (tokens) => {
|
||||||
let output = "";
|
let output = "";
|
||||||
|
|
||||||
|
@ -208,7 +254,7 @@ const tokens2html = (tokens) => {
|
||||||
output += "<br>"
|
output += "<br>"
|
||||||
break;
|
break;
|
||||||
case "image":
|
case "image":
|
||||||
output += `<p style="text-align:center"><img src="${token.url}" alt="${token.alt}"></p>`;
|
output += `<p style="text-align:center"><img src="${token.url}" alt="${token.alt}"><br>${token.title}</p>`;
|
||||||
break
|
break
|
||||||
case "ul":
|
case "ul":
|
||||||
console.log(token);
|
console.log(token);
|
||||||
|
@ -221,6 +267,12 @@ const tokens2html = (tokens) => {
|
||||||
case "inlinecode":
|
case "inlinecode":
|
||||||
output += `<code>${token.content}</code>`;
|
output += `<code>${token.content}</code>`;
|
||||||
break;
|
break;
|
||||||
|
case "codeblock":
|
||||||
|
output += `<pre class="codeblock" data-language="${token.language}">${highlight_code(token.language, token.content)}</pre>`
|
||||||
|
break;
|
||||||
|
case "link":
|
||||||
|
output += `<a href="${token.link}">${token.text}</a>`;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
<a href="/" style="color: inherit; text-decoration: inherit"><h1>SpoodyThe<span style="color:var(--background-text)">.</span>One</h1></a>
|
<a href="/" style="color: inherit; text-decoration: inherit"><h1>SpoodyThe<span style="color:var(--background-text)">.</span>One</h1></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="content" style="grid-area: content; text-align: left">
|
<div class="content" style="grid-area: content; text-align: left">
|
||||||
|
<h2>Loading...</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="footer" style="grid-area: footer; text-align: center">
|
<div class="footer" style="grid-area: footer; text-align: center">
|
||||||
<a href="#">Back to the top</a>
|
<a href="#">Back to the top</a>
|
||||||
|
@ -33,12 +34,10 @@
|
||||||
|
|
||||||
<div id="background"></div>
|
<div id="background"></div>
|
||||||
<script src="/main.js"></script>
|
<script src="/main.js"></script>
|
||||||
|
<script src="/code_highlighter.js"></script>
|
||||||
<script src="/md2html.js"></script>
|
<script src="/md2html.js"></script>
|
||||||
<script>
|
<script>
|
||||||
(async () => {
|
(async () => {
|
||||||
// let terms = "Functions Vectors Evaluate Isolate Solve Matrix Tensor Calculus Derivation Limit Procedures Scopes Statements Interpreter Parser Lexer".split(" ");
|
|
||||||
// generate_background(terms);
|
|
||||||
// document.querySelector(".header").innerHTML = md2html({{}});
|
|
||||||
try {
|
try {
|
||||||
let post = new URLSearchParams(window.location.search).get("post");
|
let post = new URLSearchParams(window.location.search).get("post");
|
||||||
let response = await fetch(`/posts/${post}.md`);
|
let response = await fetch(`/posts/${post}.md`);
|
||||||
|
|
|
@ -1,13 +1,5 @@
|
||||||
Functions Vectors Evaluate Isolate Solve Matrix Tensor Calculus Derivation Limit Procedures Scopes Statements Interpreter Parser Lexer
|
Functions Vectors Evaluate Isolate Solve Matrix Tensor Calculus Derivation Limit Procedures Scopes Statements Interpreter Parser Lexer
|
||||||
# Openbirch
|
# Openbirch
|
||||||
Openbirch is a programming language that I made together with my friend from school.
|
Cool fucking cas tool.
|
||||||
It was an attempt at making a CAS tool to use instead of Maple (the UX is terrible).
|
|
||||||
|
|
||||||
The biggest challenge besides creating a programming language was creating a programming language
|

|
||||||
where any variable could be undefined at runtime, but still used to define other variables.
|
|
||||||
|
|
||||||
An example of this would be `x := 2*y`. Here `y` is not defined, but it is still used to define `x`.
|
|
||||||
|
|
||||||
This was a unique challenge that was solved by representing everything as a *tree*
|
|
||||||
|
|
||||||

|
|
||||||
|
|
Loading…
Reference in a new issue