From 232a0d8df85fb72f67492117e9960653fcd0c5ac Mon Sep 17 00:00:00 2001 From: Zef Hemel Date: Thu, 25 Jan 2024 10:17:42 +0100 Subject: [PATCH] Fixes #98 --- plugs/editor/navigate.ts | 12 ++++ plugs/index/constants.ts | 1 + plugs/index/index.plug.yaml | 19 +++++++ plugs/index/tag_page.ts | 92 +++++++++++++++++++++++++++++++ web/cm_plugins/markdown_widget.ts | 19 +++++++ web/styles/colors.scss | 1 + website/CHANGELOG.md | 1 + 7 files changed, 145 insertions(+) create mode 100644 plugs/index/constants.ts create mode 100644 plugs/index/tag_page.ts diff --git a/plugs/editor/navigate.ts b/plugs/editor/navigate.ts index 272331b..b605dbb 100644 --- a/plugs/editor/navigate.ts +++ b/plugs/editor/navigate.ts @@ -9,6 +9,7 @@ import { } from "$sb/lib/tree.ts"; import { resolveAttachmentPath, resolvePath } from "$sb/lib/resolve.ts"; import { parsePageRef } from "$sb/lib/page.ts"; +import { tagPrefix } from "../index/constants.ts"; async function actionClickOrActionEnter( mdTree: ParseTree | null, @@ -27,6 +28,7 @@ async function actionClickOrActionEnter( "Link", "CommandLink", "PageRef", + "Hashtag", ] .includes( t.type!, @@ -96,6 +98,16 @@ async function actionClickOrActionEnter( } break; } + case "Hashtag": { + console.log("Got myself a hash tag", mdTree); + const hashtag = mdTree.children![0].text!.slice(1); + await editor.navigate( + { page: `${tagPrefix}${hashtag}`, pos: 0 }, + false, + inNewWindow, + ); + break; + } } } diff --git a/plugs/index/constants.ts b/plugs/index/constants.ts new file mode 100644 index 0000000..710befb --- /dev/null +++ b/plugs/index/constants.ts @@ -0,0 +1 @@ +export const tagPrefix = "πŸ“Œ "; diff --git a/plugs/index/index.plug.yaml b/plugs/index/index.plug.yaml index d5583eb..a72cd97 100644 --- a/plugs/index/index.plug.yaml +++ b/plugs/index/index.plug.yaml @@ -167,3 +167,22 @@ functions: path: lint.ts:lintYAML events: - editor:lint + + # Tag file system + readFileTag: + path: tag_page.ts:readFileTag + pageNamespace: + pattern: "πŸ“Œ .+" + operation: readFile + + writePageTag: + path: tag_page.ts:writeFileTag + pageNamespace: + pattern: "πŸ“Œ .+" + operation: readFile + + getPageMetaTag: + path: tag_page.ts:getFileMetaTag + pageNamespace: + pattern: "πŸ“Œ .+" + operation: getFileMeta \ No newline at end of file diff --git a/plugs/index/tag_page.ts b/plugs/index/tag_page.ts new file mode 100644 index 0000000..a4e9ab2 --- /dev/null +++ b/plugs/index/tag_page.ts @@ -0,0 +1,92 @@ +import { FileMeta } from "$sb/types.ts"; +import { markdown, system } from "$sb/syscalls.ts"; +import { renderToText } from "$sb/lib/tree.ts"; +import { tagPrefix } from "./constants.ts"; + +export async function readFileTag( + name: string, +): Promise<{ data: Uint8Array; meta: FileMeta }> { + const tagName = name.substring( + tagPrefix.length, + name.length - ".md".length, + ); + const text = `These are all objects in your space tagged with #${tagName}. +\`\`\`template +template: | + {{#if .}} + # Pages + {{#each .}} + * [[{{name}}]] + {{/each}} + {{/if}} +query: | + page where tags = "${tagName}" +\`\`\` +\`\`\`template +template: | + {{#if .}} + # Tasks + {{#each .}} + * [{{state}}] [[{{ref}}]] {{name}} + {{/each}} + {{/if}} +query: | + task where tags = "${tagName}" +\`\`\` +\`\`\`template +template: | + {{#if .}} + # Items + {{#each .}} + * [[{{ref}}]] {{name}} + {{/each}} + {{/if}} +query: | + item where tags = "${tagName}" +\`\`\` +\`\`\`template +template: | + {{#if .}} + # Paragraphs + {{#each .}} + * [[{{ref}}]] {{text}} + {{/each}} + {{/if}} +query: | + paragraph where tags = "${tagName}" +\`\`\` +`; + + let tree = await markdown.parseMarkdown(text); + tree = await system.invokeFunction("markdown.expandCodeWidgets", tree, name); + + return { + data: new TextEncoder().encode(renderToText(tree)), + meta: { + name, + contentType: "text/markdown", + size: text.length, + created: 0, + lastModified: 0, + perm: "ro", + }, + }; +} + +export function writeFileTag( + name: string, +): FileMeta { + // Never actually writing this + return getFileMetaTag(name); +} + +export function getFileMetaTag(name: string): FileMeta { + return { + name, + contentType: "text/markdown", + size: -1, + created: 0, + lastModified: 0, + perm: "ro", + }; +} diff --git a/web/cm_plugins/markdown_widget.ts b/web/cm_plugins/markdown_widget.ts index 40992e8..fb15c82 100644 --- a/web/cm_plugins/markdown_widget.ts +++ b/web/cm_plugins/markdown_widget.ts @@ -6,6 +6,7 @@ import { resolveAttachmentPath } from "$sb/lib/resolve.ts"; import { parse } from "../../common/markdown_parser/parse_tree.ts"; import { parsePageRef } from "$sb/lib/page.ts"; import { extendedMarkdownLanguage } from "../../common/markdown_parser/parser.ts"; +import { tagPrefix } from "../../plugs/index/constants.ts"; const activeWidgets = new Set(); @@ -157,6 +158,24 @@ export class MarkdownWidget extends WidgetType { }); }); + // Attach click handlers to hash tags + div.querySelectorAll("span.hashtag").forEach((el_) => { + const el = el_ as HTMLElement; + // Override default click behavior with a local navigate (faster) + console.log("Found hashtag", el.innerText); + el.addEventListener("click", (e) => { + console.log("Hashtag clicked", el.innerText); + if (e.ctrlKey || e.metaKey) { + // Don't do anything special for ctrl/meta clicks + return; + } + this.client.navigate({ + page: `${tagPrefix}${el.innerText.slice(1)}`, + pos: 0, + }); + }); + }); + div.querySelectorAll("button[data-onclick]").forEach((el_) => { const el = el_ as HTMLElement; const onclick = el.dataset.onclick!; diff --git a/web/styles/colors.scss b/web/styles/colors.scss index dfee83e..e8e66f9 100644 --- a/web/styles/colors.scss +++ b/web/styles/colors.scss @@ -177,6 +177,7 @@ color: var(--editor-hashtag-color); background-color: var(--editor-hashtag-background-color); border: 1px solid var(--editor-hashtag-border-color); + cursor: pointer; } .sb-line-hr { diff --git a/website/CHANGELOG.md b/website/CHANGELOG.md index 7584df9..02ebfbe 100644 --- a/website/CHANGELOG.md +++ b/website/CHANGELOG.md @@ -6,6 +6,7 @@ release. ## Edge _The changes below are not yet released β€œproperly”. To them out early, check out [the docs on edge](https://community.silverbullet.md/t/living-on-the-edge-builds/27)._ +* Tag pages: when you click on a #tag you will now be directed to a page that shows all pages, tasks, items and paragraphs tagged with that tag. * Bug fixes: * Improved Ctrl/Cmd-click (to open links in a new window) behavior: now actually follow `@pos` and `$anchor` links. * Right-clicking links now opens browser native context menu again