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);
|
||||
|
||||
: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;
|
||||
}
|
||||
@import url(/colours.css);
|
||||
|
||||
code {
|
||||
background: var(--background-text);
|
||||
|
@ -23,6 +8,14 @@ code {
|
|||
border-radius: var(--radius);
|
||||
}
|
||||
|
||||
pre.codeblock {
|
||||
background: var(--background-text);
|
||||
color: var(--text);
|
||||
padding: 2px 4px;
|
||||
border-radius: var(--radius);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
html {
|
||||
color: var(--text);
|
||||
background-color: var(--background);
|
||||
|
@ -31,6 +24,7 @@ html {
|
|||
|
||||
body {
|
||||
background-color: initial !important;
|
||||
font-variant-ligatures: none;
|
||||
}
|
||||
|
||||
a {
|
||||
|
|
|
@ -16,6 +16,10 @@ const md2tokens = (markdown, newline) => {
|
|||
return false;
|
||||
}
|
||||
|
||||
let peek = (a) => {
|
||||
return markdown[i + a];
|
||||
}
|
||||
|
||||
let advance = () => {
|
||||
i++;
|
||||
if (i < markdown.length)
|
||||
|
@ -25,8 +29,12 @@ const md2tokens = (markdown, newline) => {
|
|||
}
|
||||
|
||||
let capture_until = (c) => {
|
||||
return capture_until_predicate((i) => markdown[i] == c);
|
||||
}
|
||||
|
||||
let capture_until_predicate = (f) => {
|
||||
let capture = "";
|
||||
while (markdown[i] != c && markdown.length > i) {
|
||||
while (!f(i) && markdown.length > i) {
|
||||
capture += markdown[i];
|
||||
i++;
|
||||
}
|
||||
|
@ -95,7 +103,6 @@ const md2tokens = (markdown, newline) => {
|
|||
let depth_he = 0;
|
||||
do {
|
||||
depth_he++;
|
||||
|
||||
} while (match("#"));
|
||||
|
||||
while (markdown[i] != "\n" && markdown.length > i) {
|
||||
|
@ -124,17 +131,19 @@ const md2tokens = (markdown, newline) => {
|
|||
break;
|
||||
}
|
||||
|
||||
let url = capture_until("\"");
|
||||
advance();
|
||||
let title = capture_until("\"");
|
||||
advance();
|
||||
let url = capture_until_predicate((i) => markdown[i] == "\"" || markdown[i] == ")");
|
||||
let title = "";
|
||||
if (match("\"")) { // has title
|
||||
title = capture_until("\"");
|
||||
advance();
|
||||
}
|
||||
if (!match(")")) {
|
||||
current_string = `;
|
||||
break;
|
||||
}
|
||||
|
||||
tokens.push({type:"image", alt: alt_text, url: url, title: title})
|
||||
tokens.push({ type: "image", alt: alt_text, url: url, title: title })
|
||||
break;
|
||||
|
||||
case '-':
|
||||
|
@ -153,25 +162,54 @@ const md2tokens = (markdown, newline) => {
|
|||
items.push(md2tokens(text, false));
|
||||
} while (match("-"));
|
||||
|
||||
tokens.push({type:"ul", items: items});
|
||||
tokens.push({ type: "ul", items: items });
|
||||
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
if (newline_count > 2)
|
||||
break;
|
||||
|
||||
|
||||
newline = true;
|
||||
newline_count++;
|
||||
finish();
|
||||
tokens.push({ type: "newline" })
|
||||
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 '`':
|
||||
finish();
|
||||
advance();
|
||||
current_string = capture_until("`");
|
||||
finish("inlinecode");
|
||||
let stop = (i) => markdown[i] == "`";
|
||||
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;
|
||||
|
||||
default:
|
||||
|
@ -187,6 +225,14 @@ const md2tokens = (markdown, newline) => {
|
|||
return tokens;
|
||||
};
|
||||
|
||||
const highlight_code = (language, code) => {
|
||||
let map = maps[language];
|
||||
if (map == undefined)
|
||||
return code;
|
||||
|
||||
return highlight(map, code);
|
||||
}
|
||||
|
||||
const tokens2html = (tokens) => {
|
||||
let output = "";
|
||||
|
||||
|
@ -208,7 +254,7 @@ const tokens2html = (tokens) => {
|
|||
output += "<br>"
|
||||
break;
|
||||
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
|
||||
case "ul":
|
||||
console.log(token);
|
||||
|
@ -221,6 +267,12 @@ const tokens2html = (tokens) => {
|
|||
case "inlinecode":
|
||||
output += `<code>${token.content}</code>`;
|
||||
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>
|
||||
</div>
|
||||
<div class="content" style="grid-area: content; text-align: left">
|
||||
<h2>Loading...</h2>
|
||||
</div>
|
||||
<div class="footer" style="grid-area: footer; text-align: center">
|
||||
<a href="#">Back to the top</a>
|
||||
|
@ -33,12 +34,10 @@
|
|||
|
||||
<div id="background"></div>
|
||||
<script src="/main.js"></script>
|
||||
<script src="/code_highlighter.js"></script>
|
||||
<script src="/md2html.js"></script>
|
||||
<script>
|
||||
(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 {
|
||||
let post = new URLSearchParams(window.location.search).get("post");
|
||||
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
|
||||
# Openbirch
|
||||
Openbirch is a programming language that I made together with my friend from school.
|
||||
It was an attempt at making a CAS tool to use instead of Maple (the UX is terrible).
|
||||
Cool fucking cas tool.
|
||||
|
||||
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