diff --git a/index.html b/index.html index 2cdd998..ff1aeff 100644 --- a/index.html +++ b/index.html @@ -25,8 +25,6 @@ - - diff --git a/lib/common.js b/lib/common.js index bdaa500..308a347 100644 --- a/lib/common.js +++ b/lib/common.js @@ -20,6 +20,8 @@ const numMojis = [ "⑧", ]; +const linkRegex = /\[(.*?)\]\((.*?)\)/; + function toTop(div) { const allDivs = document.querySelectorAll("div"); const zs = Array.from(allDivs) diff --git a/lib/linkUtils.js b/lib/linkUtils.js index b31612f..876f49f 100644 --- a/lib/linkUtils.js +++ b/lib/linkUtils.js @@ -1,5 +1,164 @@ +/* +link = { + url: "destination", optional, even if it's "links" it can actually be just text + display: "text to show, can be HTML (is assumed to be HTML)", + shortcut: "One or two letter shortcut to quickly visit this site", + kind: "in general, one of title or normal. Title is larger and has different styling. Used as class", + url2: "additional URL to show to the right, floating of the first", + display2: "additional text to show, can be HTML" + alsoOpen2: true/false, keyboard shortcut also opens secondary link. +} + +kind can also be: +- sep to add an HR +- col to break into a new column +- settings, then display holds a CSS style rule, named as a Javascript property identifier (no dashes, using capitalisation) + +All of this can be written in markdown-like, equivalently. +Use different files for different columns, and prefix secondary URL title by * + +*/ + window.hasKeys = ""; // Store the first key pressed +const linkWithShortcut = /`(.*?)`\s*\[(.*?)\]\((.*?)\)/; + +function textToLinkObjects(text) { + let links = []; + let valid; + let settings = false; + const split = text.split("\n"); + let link = {}; + for (let i = 0; i < split.length; i++) { + const line = split[i].trim(); + // Handle titles and settings + if (line === "---") { + if (link.kind) { + links.push(link); // Store and + link = {}; // clean up the existing link + } + links.push({ + kind: "sep", + }); + continue; + } + let cleaned; + if (line.startsWith("- ")) { + cleaned = line.replace("- ", "").trim(); + if (settings) { + links.push({ + display: cleaned, + kind: "settings", + }); + continue; + } else { + const matchLink = cleaned.match(linkRegex); + if (matchLink) { + link.display2 = matchLink[1]; + if (link.display2.startsWith("*")) { + link.alsoOpen2 = true; + link.display2 = link.display2.slice(1); + } + link.url2 = matchLink[2]; + continue; + } + } + } + if (line.startsWith("# ")) { + if (settings) { + settings = false; + } + if (link.kind) { + links.push(link); // Store and + link = {}; // clean up the existing link + } + + cleaned = line.replace("# ", "").trim(); + if (cleaned == "Settings") { + settings = true; + continue; + } else { + link.kind = "title"; + } + valid = true; + } + if (line.startsWith("## ")) { + if (settings) { + settings = false; + } + if (link.kind) { + links.push(link); // Store and + link = {}; // clean up the existing link + } + cleaned = line.replace("## ", "").trim(); + link.kind = "normal"; + valid = true; + } + if (!valid) { + console.log("Invalid?"); + console.log(line); + continue; + } + if (!cleaned) { + continue; + } + const matchShortcut = cleaned.match(linkWithShortcut); + if (matchShortcut) { + link.shortcut = matchShortcut[1]; + link.display = matchShortcut[2]; + link.url = matchShortcut[3]; + continue; + } + const matchLink = cleaned.match(linkRegex); + if (matchLink) { + link.display = matchLink[1]; + link.url = matchLink[2]; + continue; + } else { + link.display = cleaned; + } + } + if (link.display) { + links.push(link); + } + return links; +} + +function linksFromMarkdown(paths, cb) { + const promises = []; + + // Handle single string or array of strings + if (typeof paths === "string") { + paths = [paths]; + } + + paths.forEach((path) => { + promises.push( + fetch(path) + .then((response) => response.text()) + .then((markdown) => { + console.log(markdown); + return textToLinkObjects(markdown); + }), + ); + }); + + Promise.all(promises) + .then((results) => { + // Flatten the array of arrays into a single array of tasks + let allLinks = []; + for (let block of results) { + console.log(block); + allLinks = allLinks.concat({ kind: "col" }); + allLinks.push(block); + } + const flattened = allLinks.slice(1).flat(); + window._links = flattened; + cb(flattened); + }) + .catch((error) => console.error("Error loading markdown file:", error)); +} + function addLinksToDiv(links, targetDivId) { const targetDiv = document.getElementById(targetDivId); if (!targetDiv) { diff --git a/lib/taskUtils.js b/lib/taskUtils.js index 1ca2752..752e4db 100644 --- a/lib/taskUtils.js +++ b/lib/taskUtils.js @@ -99,9 +99,7 @@ prio: 12 */ -const linkRegex = /\[(.*?)\]\((.*?)\)/; - -function textToObject(text) { +function textToTaskObject(text) { const lines = text.split("\n"); let obj = {}; let settings = false; @@ -218,7 +216,7 @@ function tasksFromMarkdown(paths, cb) { const blocks = markdown.split(/---/); for (let i = 0; i < blocks.length; i++) { const block = blocks[i]; - const obj = textToObject(block); + const obj = textToTaskObject(block); if (!obj._valid) { tasks.push({ text: `Error loading task ${i} from file ${path}`, diff --git a/links.js b/links.js index 855e34d..fa26a38 100644 --- a/links.js +++ b/links.js @@ -1,19 +1,3 @@ -/* -link = { - url: "destination", optional, even if it's "links" it can actually be just text - display: "text to show, can be HTML (is assumed to be HTML)", - shortcut: "One or two letter shortcut to quickly visit this site", - kind: "in general, one of title or normal. Title is larger and has different styling. Used as class", - url2: "additional URL to show to the right, floating of the first", - display2: "additional text to show, can be HTML" -} - -kind can also be: -- sep to add an HR -- col to break into a new column -- settings, then display holds a CSS style rule, named as a Javascript property identifier (no dashes, using capitalisation) -*/ - const gemini = { url: "https://gemini.google.com", display: "Gemini", @@ -99,3 +83,35 @@ const links = [ vscodeLinks, vscodeTasks, ]; + +/* + +Equivalent markdown file: + +# Settings + +- fontSize: 20px + +## `j` [jellyfin](http://localhost:8096/web) + +## `gg` [Gemini](https://gemini.google.com) +- [Gem manager](https://gemini.google.com/gems/view) + +## `u` [usenix SRE](https://www.usenix.org/publications/loginonline?field_lv2_article_type_tid=All&field_lv2_tags_tid=1102) + + +# Github + +## `gr` [Repo list](https://github.com/rberenguel?tab=repositories) + +## `gw` [Weave](https://github.com/rberenguel/weave) + +--- + +# VSCode + +## `.l` [Edit links](vscode://file/Users/ruben/fromsource/nt/links.js) + +## `.t` [Edit tasks](vscode://file//Users/ruben/Library/Mobile%20Documents/com~apple~CloudDocs/_nt/tasks.js) + +*/ diff --git a/main.js b/main.js index b48466d..8a32915 100644 --- a/main.js +++ b/main.js @@ -2,7 +2,8 @@ // Open each file called somethingUtils.js for a brief description of features -addLinksToDiv(links, "center"); +linksFromMarkdown(["links.md"], (ls) => addLinksToDiv(ls, "center")); + addTimesToDiv(timezones, "upper-left"); randomBackground(backgrounds); diff --git a/ttasks.js b/ttasks.js deleted file mode 120000 index 900d7df..0000000 --- a/ttasks.js +++ /dev/null @@ -1 +0,0 @@ -/Users/ruben/Library/Mobile Documents/com~apple~CloudDocs/_nt/tasks.js \ No newline at end of file