From 02cacc9a8277a67ca7f6a8e26a17cb63465e1181 Mon Sep 17 00:00:00 2001 From: Snorre Date: Wed, 5 Feb 2025 14:46:34 +0100 Subject: [PATCH] more markdown --- public/code_highlighter.js | 40 ++++++++++++++++++++ public/colours.css | 43 +++++++++++++++++++++ public/css.css | 26 +++++-------- public/md2html.js | 76 ++++++++++++++++++++++++++++++++------ public/posts/index.html | 5 +-- public/posts/openbirch.md | 12 +----- 6 files changed, 161 insertions(+), 41 deletions(-) create mode 100644 public/code_highlighter.js create mode 100644 public/colours.css diff --git a/public/code_highlighter.js b/public/code_highlighter.js new file mode 100644 index 0000000..c8ee430 --- /dev/null +++ b/public/code_highlighter.js @@ -0,0 +1,40 @@ +const highlight = (map, source) => { + let output = source; + + output = output.replace(/("[^"]+")/g, `$1`) + + for (let keyword of map.keywords) { + output = output.replaceAll(keyword, `${keyword}`) + } + + for (let keyword of map.altkeywords) { + output = output.replaceAll(keyword, `${keyword}`) + } + + // TODO: predicate for function calls to be replaced + // for (let func in map.functions) { + // output = output.replace(func, `${func}`) + // } + + output = output.replace(/(\d+)/g, `$1`) + + return output; +} + +const maps = { + cpp: { + keywords: [ + "auto", + "void", + "struct" + ], + altkeywords: [ + "const", + "static", + "int", + "std::string", + "std::unique_ptr", + "char", + ], + } +}; diff --git a/public/colours.css b/public/colours.css new file mode 100644 index 0000000..e43956c --- /dev/null +++ b/public/colours.css @@ -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) +} diff --git a/public/css.css b/public/css.css index bb9fba4..c256e10 100644 --- a/public/css.css +++ b/public/css.css @@ -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 { diff --git a/public/md2html.js b/public/md2html.js index 5d3e2a2..df197c6 100644 --- a/public/md2html.js +++ b/public/md2html.js @@ -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 = `![${alt_text}](${url} "${title}"`; def(); 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 += "
" break; case "image": - output += `

${token.alt}

`; + output += `

${token.alt}
${token.title}

`; break case "ul": console.log(token); @@ -221,6 +267,12 @@ const tokens2html = (tokens) => { case "inlinecode": output += `${token.content}`; break; + case "codeblock": + output += `
${highlight_code(token.language, token.content)}
` + break; + case "link": + output += `${token.text}`; + break; } } diff --git a/public/posts/index.html b/public/posts/index.html index 5168d8f..1323957 100644 --- a/public/posts/index.html +++ b/public/posts/index.html @@ -25,6 +25,7 @@

SpoodyThe.One

+

Loading...