2021-10-17 02:00:24 +00:00
|
|
|
"use strict";
|
|
|
|
|
2024-10-01 23:55:24 +00:00
|
|
|
import crypto from "crypto";
|
2021-10-05 01:02:53 +00:00
|
|
|
|
2024-10-01 23:55:24 +00:00
|
|
|
import htmlentities from "html-entities";
|
|
|
|
import MarkdownIt from "markdown-it";
|
|
|
|
import chroma from "chroma-js";
|
|
|
|
|
|
|
|
import markdown_prism from "markdown-it-prism";
|
|
|
|
import markdown_alerts from "markdown-it-github-alerts";
|
|
|
|
|
|
|
|
const markdown = new MarkdownIt({
|
2021-06-20 00:51:55 +00:00
|
|
|
xhtmlOut: true
|
|
|
|
});
|
2021-10-05 01:02:53 +00:00
|
|
|
|
2021-07-06 01:47:45 +00:00
|
|
|
markdown.use(markdown_prism, {
|
|
|
|
init: (Prism) => {
|
|
|
|
Prism.languages.weacmd = {
|
|
|
|
"string": /\<[^>]+?\>/,
|
|
|
|
"function": /^(?:\/\/\S+)\b/m,
|
|
|
|
"number": /\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?%?/i,
|
|
|
|
"operator": /[<>:=\[\]|{}]/,
|
|
|
|
"keyword": /\b(?:[-+]?[zyx])\b/
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2024-10-01 23:55:24 +00:00
|
|
|
markdown.use(markdown_alerts);
|
2023-12-20 00:40:35 +00:00
|
|
|
|
2021-10-05 01:02:53 +00:00
|
|
|
function extract_title(line) {
|
|
|
|
return line.match(/#+\s+(.+)\s*/)[1].replace(/^`*|`*$/g, "")
|
|
|
|
}
|
|
|
|
|
|
|
|
function make_section(acc, cat_current, cats) {
|
2024-10-02 00:03:09 +00:00
|
|
|
const title = extract_title(acc[0]);
|
2021-10-04 20:45:15 +00:00
|
|
|
return {
|
2021-10-05 01:02:53 +00:00
|
|
|
category: cat_current,
|
|
|
|
category_colour: cats.get(cat_current),
|
|
|
|
category_colour_dark: chroma(cats.get(cat_current))
|
|
|
|
.set("hsl.s", 0.8)
|
|
|
|
.set("hsl.l", "*0.6")
|
|
|
|
.css("hsl"),
|
2021-10-04 20:45:15 +00:00
|
|
|
title: htmlentities.encode(title),
|
|
|
|
slug: title.toLowerCase().replace(/[^a-z0-9-_\s]+/gi, "")
|
|
|
|
.replace(/\s+/g, "-")
|
|
|
|
.replace(/-.*$/, ""),
|
|
|
|
content: markdown.render(acc.slice(1).join("\n"))
|
2023-12-19 23:41:37 +00:00
|
|
|
.replace(/<(\/?)h4>/g, "<$1h3>")
|
|
|
|
.replace(/<(\/?)h5>/g, "<$1h4>")
|
2021-10-04 20:45:15 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2024-10-01 23:55:24 +00:00
|
|
|
export default function parse_sections(source) {
|
2021-10-05 01:02:53 +00:00
|
|
|
const cats = new Map();
|
|
|
|
source.match(/^##\s+.*$/gm)
|
|
|
|
.map(extract_title)
|
|
|
|
.map((item, i, all) => cats.set(
|
|
|
|
item,
|
|
|
|
chroma(`hsl(${i/all.length*(360-360/all.length)}, 60%, 90%)`).css("hsl")
|
|
|
|
));
|
2021-06-20 00:51:55 +00:00
|
|
|
const lines = source.split(/\r?\n/gi);
|
|
|
|
const result = [];
|
|
|
|
let acc = [];
|
2021-10-05 01:02:53 +00:00
|
|
|
let cat_current = null;
|
2024-10-02 00:03:09 +00:00
|
|
|
for(const line of lines) {
|
2021-10-05 01:02:53 +00:00
|
|
|
|
|
|
|
if(line.startsWith(`#`)) {
|
2024-10-02 00:03:09 +00:00
|
|
|
const heading_level = line.match(/^#+/)[0].length;
|
2021-10-05 01:02:53 +00:00
|
|
|
|
|
|
|
// 1: Deal with the previous section
|
|
|
|
if(acc.length > 0) {
|
2024-10-02 00:03:09 +00:00
|
|
|
const heading_level_prev = acc[0].match(/^#+/)[0].length;
|
2022-06-11 15:58:25 +00:00
|
|
|
if(heading_level_prev === 3 && acc.length > 0 && heading_level <= 3) {
|
2021-10-05 01:02:53 +00:00
|
|
|
result.push(make_section(acc, cat_current, cats));
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// 2: Deal with the new line
|
|
|
|
|
|
|
|
if(heading_level === 2)
|
|
|
|
cat_current = extract_title(line);
|
|
|
|
|
2022-06-11 15:58:25 +00:00
|
|
|
if(heading_level > 3)
|
|
|
|
acc.push(line)
|
|
|
|
else
|
|
|
|
acc = [ line ];
|
2021-06-20 00:51:55 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
acc.push(line);
|
|
|
|
}
|
2021-10-04 20:45:15 +00:00
|
|
|
|
|
|
|
if(acc.length > 0)
|
2021-10-05 01:02:53 +00:00
|
|
|
result.push(make_section(acc, cat_current, cats));
|
2021-10-04 20:45:15 +00:00
|
|
|
|
2021-10-05 01:02:53 +00:00
|
|
|
return { sections: result, categories: cats };
|
2021-06-20 00:51:55 +00:00
|
|
|
}
|