diff --git a/apps/cory/docs.json b/apps/cory/docs.json index 094c2a12..9c6a4e62 100644 --- a/apps/cory/docs.json +++ b/apps/cory/docs.json @@ -1 +1 @@ -{"type":"tildefriends-app","files":{"app.js":"&rLwYqurncmnUyGeWY+FLEGS2EIJmqw2cutl1gyGiVSk=.sha256","index.md":"&082vPjenwI6mL2vXwQDVEFquyl2jW9t767sGuCFvVNA=.sha256","todo.md":"&ehX+cfsiYWwe3Pjg2QW7Gqa5bsQTFBehJVxQnlxv+P4=.sha256","structure.md":"&T+CBfT9XP6ooKFvD1ZCI9hsutqsNIamfBxtAho0HtlU=.sha256","guide.md":"&SgnGL0+rjetY2o9A2+lVRbNvHIkqKwMnZr9gXWneIlc=.sha256","id_refactor.md":"&8yoYd14gX2Z3ppktVrPYf4qR78fuwAlvrtsWkSCkWUA=.sha256","ssb.md":"&WMvYIpp4CMZACwXJlX8HMDplJ+XeJB04BYf8zasrL4g=.sha256"}} \ No newline at end of file +{"type":"tildefriends-app","files":{"app.js":"&WEvJYebSMi5d2eXgUwJJmvR/Q4slFg3zHYB8Q2mXJII=.sha256","index.md":"&Pi0NTJn9/w76yIUKqRRuSvUPSpqkxdYynmjeOBbF3K8=.sha256","todo.md":"&ehX+cfsiYWwe3Pjg2QW7Gqa5bsQTFBehJVxQnlxv+P4=.sha256","structure.md":"&T+CBfT9XP6ooKFvD1ZCI9hsutqsNIamfBxtAho0HtlU=.sha256","guide.md":"&SgnGL0+rjetY2o9A2+lVRbNvHIkqKwMnZr9gXWneIlc=.sha256","ssb.md":"&ouqT3XzTGfBNpOP/uEdOw7K1F9BeLZgQCx24XTvhyXU=.sha256"}} \ No newline at end of file diff --git a/apps/cory/docs/app.js b/apps/cory/docs/app.js index 28b7f6a0..fbbbd7e8 100644 --- a/apps/cory/docs/app.js +++ b/apps/cory/docs/app.js @@ -8,7 +8,7 @@ async function loadDocument(name) { `; var md = utf8Decode(await getFile(name + '.md')); if (!md) { - md = "File not found."; + md = `File not found: ${JSON.stringify(name)}.`; } var parsed = new commonmark.Parser().parse(md); var html = new commonmark.HtmlRenderer().render(parsed); @@ -22,7 +22,7 @@ async function main() { core.register('message', function(message) { if (message.event == 'hashChange') { - loadDocument(message.hash.substring(1)); + loadDocument((message.hash || '#index').substring(1)); } }); diff --git a/apps/cory/docs/index.md b/apps/cory/docs/index.md index 61a39084..703c6aeb 100644 --- a/apps/cory/docs/index.md +++ b/apps/cory/docs/index.md @@ -8,5 +8,4 @@ and run code. - [Secure Scuttlebutt from Scratch](#ssb) - [Structure](#structure) - [Guide](#guide) -- [TODO](#todo) -- [ID Refactor](#id_refactor) \ No newline at end of file +- [TODO](#todo) \ No newline at end of file diff --git a/apps/cory/docs/ssb.md b/apps/cory/docs/ssb.md index b81a74c7..a6371f3f 100644 --- a/apps/cory/docs/ssb.md +++ b/apps/cory/docs/ssb.md @@ -30,4 +30,8 @@ So now you're discovering other clients on the local network, connecting, perfor a secret handshake, and making remote procedure calls over box streams. The next step is to start synchronizing feeds over the network. The goal, after all, is to author messages in your local append-only log and have them show up in distant clients, or -vice versa. \ No newline at end of file +vice versa. + +## References +* [https://ssbc.github.io/scuttlebutt-protocol-guide/](https://ssbc.github.io/scuttlebutt-protocol-guide/) +* [https://dev.planetary.social/](https://dev.planetary.social/) \ No newline at end of file diff --git a/apps/cory/ssblit.json b/apps/cory/ssblit.json index 10135e6a..0277eeec 100644 --- a/apps/cory/ssblit.json +++ b/apps/cory/ssblit.json @@ -1 +1 @@ -{"type":"tildefriends-app","files":{"app.js":"&jLRr14wP54BEkzBMIf1vCdeylqYExD8+jnHwgsqV9a4=.sha256","lit-all.min.js":"&N4A12AsifdQgwdpII0SFtG513BfoLpmPjdJ9VTDftpg=.sha256","index.html":"&4uvb7ESTRYeImX1lsIQOWRec6HmMBaYipGgYf0EFVPY=.sha256","script.js":"&G8puK9Q4MngHy3D4ppcKyT49WKbHD2OCeUcAw2ghTDE=.sha256","lit-all.min.js.map":"&oFY9wO4MnujgfGNGv4VggHc5V5JwX4C8csqKZ6KJYbE=.sha256","tf-id-picker.js":"&9BDffV4HY9FqhL7XI4it+UQJB4cYwbDNsY3S1cxy2vw=.sha256","tf-app.js":"&fEqRRoyD6C7oNGcveWy02XRdymmTgAVwFHvkTC1xOjU=.sha256","tf-message.js":"&6/9GXDUOB0KvKZMEgY8CEU2gqSUB0yZWEVWkRV9VSLM=.sha256","tf-user.js":"&bXTedgBudTQLXEBPY9R8OLfQ/ZLpo8YRU9Oq/wuGG3Y=.sha256","tf-utils.js":"&N2yKZwFnb2GbPeipgQtu6xFvezENNOgud9G7EhCQ/K0=.sha256","commonmark.min.js":"&bfBaMLU19d1p/vPBF9hlARqDX002KXG/UOfxOahZhe4=.sha256","tf-compose.js":"&ZGWHQZPTUl4QU5++WkGwGbyj+hxhQrTg9nLmZCrl/1g=.sha256","emojis.json":"&h3P4pez+AI4aYdsN0dJ3pbUEFR0276t9AM20caj/W/s=.sha256","emojis.js":"&pqYLDE/13PyEt2ceeFqvnwZ8NqWfPfpDBt4vP8SeHbs=.sha256","tf-styles.js":"&Zw90HptAvGwX/vBnEhRVfNrYjMSssFnnKpp8bzwXQH0=.sha256","tf-profile.js":"&vRKjsnYvOiHCQahzEfznCvP5YDwUPtltlpWf+pxwZ1Y=.sha256","commonmark-linkify.js":"&X+hNNkmSRvKY86khyAun+cXksquXbMakZdINbGbx30g=.sha256","tf-tab-search.js":"&ESt2vMG19sH5j6ungKua/ZuvIGslyuWyb3juXdOCecg=.sha256","tf-tab-news.js":"&SSHoFxBG2DiKUbfMNxiBjxqtAccQDSAEUTSN/IN/MlY=.sha256","tf-tab-connections.js":"&PjreVhTR/vxlGHVKQbY0P9BuD6udtPMHDUv9HPCHuKw=.sha256","tf-news.js":"&/Ij0SaBTohV2myuA1gQAPlgmyq/AmmvYIhSCm3wfmow=.sha256","tribute.css":"&9FogMzZHKXCfGb7mlh7z+/wiNZzBsOB/tKoh6MfYJno=.sha256","tribute.esm.js":"&P1wKqCfYULpR/ahSB98JP8xaxfikuZwwtT6I/SAo7/Y=.sha256"}} \ No newline at end of file +{"type":"tildefriends-app","files":{"app.js":"&jLRr14wP54BEkzBMIf1vCdeylqYExD8+jnHwgsqV9a4=.sha256","lit-all.min.js":"&N4A12AsifdQgwdpII0SFtG513BfoLpmPjdJ9VTDftpg=.sha256","index.html":"&TxhFekB9ov7tf/fmkAg7x5797i27oLidhgxEfDKC0T0=.sha256","script.js":"&G8puK9Q4MngHy3D4ppcKyT49WKbHD2OCeUcAw2ghTDE=.sha256","lit-all.min.js.map":"&oFY9wO4MnujgfGNGv4VggHc5V5JwX4C8csqKZ6KJYbE=.sha256","tf-id-picker.js":"&9BDffV4HY9FqhL7XI4it+UQJB4cYwbDNsY3S1cxy2vw=.sha256","tf-app.js":"&fEqRRoyD6C7oNGcveWy02XRdymmTgAVwFHvkTC1xOjU=.sha256","tf-message.js":"&6/9GXDUOB0KvKZMEgY8CEU2gqSUB0yZWEVWkRV9VSLM=.sha256","tf-user.js":"&bXTedgBudTQLXEBPY9R8OLfQ/ZLpo8YRU9Oq/wuGG3Y=.sha256","tf-utils.js":"&6RQUuxB3PkOhYEJr9+89Ptx7uijczjn0r035yCcQOQQ=.sha256","commonmark.min.js":"&bfBaMLU19d1p/vPBF9hlARqDX002KXG/UOfxOahZhe4=.sha256","tf-compose.js":"&ZGWHQZPTUl4QU5++WkGwGbyj+hxhQrTg9nLmZCrl/1g=.sha256","emojis.json":"&h3P4pez+AI4aYdsN0dJ3pbUEFR0276t9AM20caj/W/s=.sha256","emojis.js":"&pqYLDE/13PyEt2ceeFqvnwZ8NqWfPfpDBt4vP8SeHbs=.sha256","tf-styles.js":"&Zw90HptAvGwX/vBnEhRVfNrYjMSssFnnKpp8bzwXQH0=.sha256","tf-profile.js":"&vRKjsnYvOiHCQahzEfznCvP5YDwUPtltlpWf+pxwZ1Y=.sha256","commonmark-linkify.js":"&X+hNNkmSRvKY86khyAun+cXksquXbMakZdINbGbx30g=.sha256","tf-tab-search.js":"&ESt2vMG19sH5j6ungKua/ZuvIGslyuWyb3juXdOCecg=.sha256","tf-tab-news.js":"&SSHoFxBG2DiKUbfMNxiBjxqtAccQDSAEUTSN/IN/MlY=.sha256","tf-tab-connections.js":"&PjreVhTR/vxlGHVKQbY0P9BuD6udtPMHDUv9HPCHuKw=.sha256","tf-news.js":"&/Ij0SaBTohV2myuA1gQAPlgmyq/AmmvYIhSCm3wfmow=.sha256","tribute.css":"&9FogMzZHKXCfGb7mlh7z+/wiNZzBsOB/tKoh6MfYJno=.sha256","tribute.esm.js":"&P1wKqCfYULpR/ahSB98JP8xaxfikuZwwtT6I/SAo7/Y=.sha256","commonmark-hashtag.js":"&H+V1OLA9GDdzycKclz276zAtSZLpT3rlNVa4+qQmp4o=.sha256"}} \ No newline at end of file diff --git a/apps/cory/ssblit/commonmark-hashtag.js b/apps/cory/ssblit/commonmark-hashtag.js new file mode 100644 index 00000000..76d0e8bc --- /dev/null +++ b/apps/cory/ssblit/commonmark-hashtag.js @@ -0,0 +1,90 @@ +function textNode(text) { + const node = new commonmark.Node("text", undefined); + node.literal = text; + return node; +} + +function linkNode(text, link) { + const linkNode = new commonmark.Node("link", undefined); + linkNode.destination = `#q=${encodeURIComponent(link)}`; + linkNode.appendChild(textNode(text)); + return linkNode; +} + +function splitMatches(text, regexp) { + // Regexp must be sticky. + regexp = new RegExp(regexp, "gm"); + + let i = 0; + const result = []; + + let match = regexp.exec(text); + while (match) { + const matchText = match[0]; + + if (match.index > i) { + result.push([text.substring(i, match.index), false]); + } + + result.push([matchText, true]); + i = match.index + matchText.length; + + match = regexp.exec(text); + } + + if (i < text.length) { + result.push([text.substring(i, text.length), false]); + } + + return result; +} + +const regex = new RegExp("#[\\w-]+"); + +function split(textNodes) { + const text = textNodes.map(n => n.literal).join(""); + const parts = splitMatches(text, regex); + + return parts.map(part => { + if (part[1]) { + return linkNode(part[0], part[0]); + } else { + return textNode(part[0]); + } + }); +} + +export function transform(parsed) { + const walker = parsed.walker(); + let event; + + let nodes = []; + while ((event = walker.next())) { + const node = event.node; + if (event.entering && node.type === "text") { + nodes.push(node); + } else { + if (nodes.length > 0) { + split(nodes) + .reverse() + .forEach(newNode => { + nodes[0].insertAfter(newNode); + }); + + nodes.forEach(n => n.unlink()); + nodes = []; + } + } + } + + if (nodes.length > 0) { + split(nodes) + .reverse() + .forEach(newNode => { + nodes[0].insertAfter(newNode); + }); + nodes.forEach(n => n.unlink()); + } + + return parsed; +} diff --git a/apps/cory/ssblit/index.html b/apps/cory/ssblit/index.html index 60ed1b59..4aa22a60 100644 --- a/apps/cory/ssblit/index.html +++ b/apps/cory/ssblit/index.html @@ -15,6 +15,7 @@ + \ No newline at end of file diff --git a/apps/cory/ssblit/tf-utils.js b/apps/cory/ssblit/tf-utils.js index b6eb55ba..a25bf80e 100644 --- a/apps/cory/ssblit/tf-utils.js +++ b/apps/cory/ssblit/tf-utils.js @@ -1,9 +1,11 @@ import * as linkify from './commonmark-linkify.js'; +import * as hashtagify from './commonmark-hashtag.js'; export function markdown(md) { var reader = new commonmark.Parser({safe: true}); var writer = new commonmark.HtmlRenderer(); var parsed = reader.parse(md || ''); + parsed = hashtagify.transform(parsed); parsed = linkify.transform(parsed); var walker = parsed.walker(); var event, node;