Added new "tasks" built-in plug
This commit is contained in:
parent
66c21c4c6b
commit
d0431bbd99
@ -1,17 +1,5 @@
|
||||
name: core
|
||||
syntax:
|
||||
HashTag:
|
||||
firstCharacters:
|
||||
- "#"
|
||||
regex: "#[A-Za-z\\.]+"
|
||||
styles:
|
||||
color: blue
|
||||
AtMention:
|
||||
firstCharacters:
|
||||
- "@"
|
||||
regex: "@[A-Za-z\\.]+"
|
||||
styles:
|
||||
color: blue
|
||||
NakedURL:
|
||||
firstCharacters:
|
||||
- "h"
|
||||
|
@ -7,6 +7,7 @@ import {
|
||||
queryPrefix,
|
||||
} from "@silverbulletmd/plugos-silverbullet-syscall";
|
||||
import {
|
||||
addParentPointers,
|
||||
collectNodesOfType,
|
||||
findNodeOfType,
|
||||
ParseTree,
|
||||
@ -67,7 +68,22 @@ export function extractMeta(
|
||||
removeKeys: string[] = []
|
||||
): any {
|
||||
let data: any = {};
|
||||
addParentPointers(parseTree);
|
||||
replaceNodesMatching(parseTree, (t) => {
|
||||
if (t.type === "Hashtag") {
|
||||
// Check if if nested directly into a Paragraph
|
||||
if (t.parent && t.parent.type === "Paragraph") {
|
||||
let tagname = t.children![0].text;
|
||||
if (!data.tags) {
|
||||
data.tags = [];
|
||||
}
|
||||
if (!data.tags.includes(tagname)) {
|
||||
data.tags.push(tagname);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Find a fenced code block
|
||||
if (t.type !== "FencedCode") {
|
||||
return;
|
||||
}
|
||||
|
17
packages/plugs/tags/tags.plug.yaml
Normal file
17
packages/plugs/tags/tags.plug.yaml
Normal file
@ -0,0 +1,17 @@
|
||||
name: tags
|
||||
syntax:
|
||||
Hashtag:
|
||||
firstCharacters:
|
||||
- "#"
|
||||
regex: "#[^#\\s]+"
|
||||
styles:
|
||||
color: blue
|
||||
functions:
|
||||
indexTags:
|
||||
path: "./tags.ts:indexTags"
|
||||
events:
|
||||
- page:index
|
||||
tagComplete:
|
||||
path: "./tags.ts:tagComplete"
|
||||
events:
|
||||
- page:complete
|
39
packages/plugs/tags/tags.ts
Normal file
39
packages/plugs/tags/tags.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import { collectNodesOfType } from "@silverbulletmd/common/tree";
|
||||
import {
|
||||
batchSet,
|
||||
queryPrefix,
|
||||
} from "@silverbulletmd/plugos-silverbullet-syscall";
|
||||
import { matchBefore } from "@silverbulletmd/plugos-silverbullet-syscall/editor";
|
||||
import type { IndexTreeEvent } from "@silverbulletmd/web/app_event";
|
||||
import { removeQueries } from "../query/util";
|
||||
|
||||
// Key space
|
||||
// ht:TAG => true (for completion)
|
||||
|
||||
export async function indexTags({ name, tree }: IndexTreeEvent) {
|
||||
removeQueries(tree);
|
||||
let allTags = new Set<string>();
|
||||
collectNodesOfType(tree, "Hashtag").forEach((n) => {
|
||||
allTags.add(n.children![0].text!);
|
||||
});
|
||||
batchSet(
|
||||
name,
|
||||
[...allTags].map((t) => ({ key: `ht:${t}`, value: t }))
|
||||
);
|
||||
}
|
||||
|
||||
export async function tagComplete() {
|
||||
let prefix = await matchBefore("#[^#\\s]+");
|
||||
// console.log("Running tag complete", prefix);
|
||||
if (!prefix) {
|
||||
return null;
|
||||
}
|
||||
let allTags = await queryPrefix(`ht:${prefix.text}`);
|
||||
return {
|
||||
from: prefix.from,
|
||||
options: allTags.map((tag) => ({
|
||||
label: tag.value,
|
||||
type: "tag",
|
||||
})),
|
||||
};
|
||||
}
|
@ -23,6 +23,7 @@ import {
|
||||
nodeAtPos,
|
||||
ParseTree,
|
||||
renderToText,
|
||||
replaceNodesMatching,
|
||||
} from "@silverbulletmd/common/tree";
|
||||
import { removeQueries } from "../query/util";
|
||||
import { applyQuery, QueryProviderEvent, renderQuery } from "../query/engine";
|
||||
@ -32,6 +33,7 @@ export type Task = {
|
||||
name: string;
|
||||
done: boolean;
|
||||
deadline?: string;
|
||||
tags?: string[];
|
||||
nested?: string;
|
||||
// Not saved in DB, just added when pulled out (from key)
|
||||
pos?: number;
|
||||
@ -47,28 +49,40 @@ export async function indexTasks({ name, tree }: IndexTreeEvent) {
|
||||
let tasks: { key: string; value: Task }[] = [];
|
||||
removeQueries(tree);
|
||||
collectNodesOfType(tree, "Task").forEach((n) => {
|
||||
let task = n.children!.slice(1).map(renderToText).join("").trim();
|
||||
let complete = n.children![0].children![0].text! !== "[ ]";
|
||||
let value: Task = {
|
||||
name: task,
|
||||
let task: Task = {
|
||||
name: "",
|
||||
done: complete,
|
||||
};
|
||||
|
||||
let deadlineNode = findNodeOfType(n, "DeadlineDate");
|
||||
if (deadlineNode) {
|
||||
value.deadline = getDeadline(deadlineNode);
|
||||
}
|
||||
replaceNodesMatching(n, (tree) => {
|
||||
if (tree.type === "DeadlineDate") {
|
||||
task.deadline = getDeadline(tree);
|
||||
// Remove this node from the tree
|
||||
return null;
|
||||
}
|
||||
if (tree.type === "Hashtag") {
|
||||
if (!task.tags) {
|
||||
task.tags = [];
|
||||
}
|
||||
task.tags.push(tree.children![0].text!);
|
||||
// Remove this node from the tree
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
task.name = n.children!.slice(1).map(renderToText).join("").trim();
|
||||
|
||||
let taskIndex = n.parent!.children!.indexOf(n);
|
||||
let nestedItems = n.parent!.children!.slice(taskIndex + 1);
|
||||
if (nestedItems.length > 0) {
|
||||
value.nested = nestedItems.map(renderToText).join("").trim();
|
||||
task.nested = nestedItems.map(renderToText).join("").trim();
|
||||
}
|
||||
tasks.push({
|
||||
key: `task:${n.from}`,
|
||||
value,
|
||||
value: task,
|
||||
});
|
||||
// console.log("Task", value);
|
||||
console.log("Task", task);
|
||||
});
|
||||
|
||||
console.log("Found", tasks.length, "task(s)");
|
||||
|
Loading…
Reference in New Issue
Block a user