1
0
silverbullet/plugs/core/template.ts

241 lines
7.0 KiB
TypeScript
Raw Normal View History

2022-10-14 13:11:33 +00:00
import { editor, markdown, space } from "$sb/silverbullet-syscall/mod.ts";
2022-11-24 11:04:00 +00:00
import { extractFrontmatter } from "$sb/lib/frontmatter.ts";
2022-10-14 13:11:33 +00:00
import { renderToText } from "$sb/lib/tree.ts";
import { niceDate } from "$sb/lib/dates.ts";
import { readSettings } from "$sb/lib/settings_page.ts";
export async function instantiateTemplateCommand() {
2022-10-14 13:11:33 +00:00
const allPages = await space.listPages();
const { pageTemplatePrefix } = await readSettings({
pageTemplatePrefix: "template/page/",
});
2022-10-14 13:11:33 +00:00
const selectedTemplate = await editor.filterBox(
"Template",
2022-08-08 11:56:04 +00:00
allPages
.filter((pageMeta) => pageMeta.name.startsWith(pageTemplatePrefix))
.map((pageMeta) => ({
...pageMeta,
name: pageMeta.name.slice(pageTemplatePrefix.length),
})),
`Select the template to create a new page from (listing any page starting with <tt>${pageTemplatePrefix}</tt>)`,
);
if (!selectedTemplate) {
return;
}
console.log("Selected template", selectedTemplate);
2022-10-14 13:11:33 +00:00
const text = await space.readPage(
`${pageTemplatePrefix}${selectedTemplate.name}`,
2022-08-08 11:56:04 +00:00
);
2022-10-14 13:11:33 +00:00
const parseTree = await markdown.parseMarkdown(text);
2022-11-24 11:04:00 +00:00
const additionalPageMeta = extractFrontmatter(parseTree, [
2022-08-09 13:37:47 +00:00
"$name",
"$disableDirectives",
]);
2022-10-14 13:11:33 +00:00
const pageName = await editor.prompt(
"Name of new page",
additionalPageMeta.$name,
);
if (!pageName) {
return;
}
const pageText = replaceTemplateVars(renderToText(parseTree), pageName);
2022-10-14 13:11:33 +00:00
await space.writePage(pageName, pageText);
await editor.navigate(pageName);
}
export async function insertSnippet() {
2022-10-14 13:11:33 +00:00
const allPages = await space.listPages();
const { snippetPrefix } = await readSettings({
snippetPrefix: "snippet/",
});
2022-10-14 13:11:33 +00:00
const cursorPos = await editor.getCursor();
const page = await editor.getCurrentPage();
const allSnippets = allPages
.filter((pageMeta) => pageMeta.name.startsWith(snippetPrefix))
.map((pageMeta) => ({
...pageMeta,
name: pageMeta.name.slice(snippetPrefix.length),
}));
2022-10-14 13:11:33 +00:00
const selectedSnippet = await editor.filterBox(
"Snippet",
allSnippets,
`Select the snippet to insert (listing any page starting with <tt>${snippetPrefix}</tt>)`,
);
if (!selectedSnippet) {
return;
}
2022-10-14 13:11:33 +00:00
const text = await space.readPage(`${snippetPrefix}${selectedSnippet.name}`);
let templateText = replaceTemplateVars(text, page);
2022-10-14 13:11:33 +00:00
const carretPos = templateText.indexOf("|^|");
templateText = templateText.replace("|^|", "");
templateText = replaceTemplateVars(templateText, page);
2022-10-14 13:11:33 +00:00
await editor.insertAtCursor(templateText);
if (carretPos !== -1) {
2022-10-14 13:11:33 +00:00
await editor.moveCursor(cursorPos + carretPos);
}
}
2022-05-06 16:55:04 +00:00
// TODO: This should probably be replaced with handlebards somehow?
export function replaceTemplateVars(s: string, pageName: string): string {
return s.replaceAll(/\{\{([^\}]+)\}\}/g, (match, v) => {
switch (v) {
case "today":
return niceDate(new Date());
2022-10-14 13:11:33 +00:00
case "tomorrow": {
const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
return niceDate(tomorrow);
2022-10-14 13:11:33 +00:00
}
case "yesterday": {
const yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
return niceDate(yesterday);
2022-10-14 13:11:33 +00:00
}
case "lastWeek": {
const lastWeek = new Date();
lastWeek.setDate(lastWeek.getDate() - 7);
return niceDate(lastWeek);
2022-10-14 13:11:33 +00:00
}
2022-11-03 12:14:43 +00:00
case "nextWeek": {
const nextWeek = new Date();
nextWeek.setDate(nextWeek.getDate() + 7);
return niceDate(nextWeek);
}
case "page":
return pageName;
}
return match;
});
}
2022-05-06 16:55:04 +00:00
export async function quickNoteCommand() {
2022-10-14 13:11:33 +00:00
const { quickNotePrefix } = await readSettings({
2022-08-08 11:56:04 +00:00
quickNotePrefix: "📥 ",
});
2022-10-14 13:11:33 +00:00
const isoDate = new Date().toISOString();
2022-05-06 16:55:04 +00:00
let [date, time] = isoDate.split("T");
time = time.split(".")[0];
2022-10-14 13:11:33 +00:00
const pageName = `${quickNotePrefix}${date} ${time}`;
await editor.navigate(pageName);
2022-05-06 16:55:04 +00:00
}
2022-07-06 10:18:47 +00:00
export async function dailyNoteCommand() {
2022-10-14 13:11:33 +00:00
const { dailyNoteTemplate, dailyNotePrefix } = await readSettings({
2022-08-08 11:56:04 +00:00
dailyNoteTemplate: "template/page/Daily Note",
dailyNotePrefix: "📅 ",
});
let dailyNoteTemplateText = "";
try {
dailyNoteTemplateText = await space.readPage(dailyNoteTemplate);
2022-08-08 11:56:04 +00:00
} catch {
console.warn(`No daily note template found at ${dailyNoteTemplate}`);
}
2022-10-14 13:11:33 +00:00
const date = niceDate(new Date());
const pageName = `${dailyNotePrefix}${date}`;
2022-08-08 11:56:04 +00:00
if (dailyNoteTemplateText) {
try {
2022-10-14 13:11:33 +00:00
await space.getPageMeta(pageName);
2022-08-08 11:56:04 +00:00
} catch {
// Doesn't exist, let's create
2022-10-14 13:11:33 +00:00
await space.writePage(
2022-08-08 11:56:04 +00:00
pageName,
replaceTemplateVars(dailyNoteTemplateText, pageName),
2022-08-08 11:56:04 +00:00
);
}
2022-10-14 13:11:33 +00:00
await editor.navigate(pageName);
2022-08-08 11:56:04 +00:00
} else {
2022-10-14 13:11:33 +00:00
await editor.navigate(pageName);
2022-08-08 11:56:04 +00:00
}
2022-07-06 10:18:47 +00:00
}
2022-11-02 08:06:30 +00:00
function getWeekStartDate(monday = false) {
const d = new Date();
const day = d.getDay();
let diff = d.getDate() - day;
if (monday) {
diff += day == 0 ? -6 : 1;
}
return new Date(d.setDate(diff));
}
export async function weeklyNoteCommand() {
const { weeklyNoteTemplate, weeklyNotePrefix, weeklyNoteMonday } =
await readSettings({
weeklyNoteTemplate: "template/page/Weekly Note",
weeklyNotePrefix: "🗓️ ",
weeklyNoteMonday: false,
});
let weeklyNoteTemplateText = "";
try {
weeklyNoteTemplateText = await space.readPage(weeklyNoteTemplate);
} catch {
console.warn(`No weekly note template found at ${weeklyNoteTemplate}`);
}
const date = niceDate(getWeekStartDate(weeklyNoteMonday));
const pageName = `${weeklyNotePrefix}${date}`;
if (weeklyNoteTemplateText) {
try {
await space.getPageMeta(pageName);
} catch {
// Doesn't exist, let's create
await space.writePage(
pageName,
replaceTemplateVars(weeklyNoteTemplateText, pageName),
);
}
await editor.navigate(pageName);
} else {
await editor.navigate(pageName);
}
}
export async function insertTemplateText(cmdDef: any) {
2022-10-14 13:11:33 +00:00
const cursorPos = await editor.getCursor();
const page = await editor.getCurrentPage();
let templateText: string = cmdDef.value;
2022-10-14 13:11:33 +00:00
const carretPos = templateText.indexOf("|^|");
templateText = templateText.replace("|^|", "");
templateText = replaceTemplateVars(templateText, page);
2022-10-14 13:11:33 +00:00
await editor.insertAtCursor(templateText);
if (carretPos !== -1) {
2022-10-14 13:11:33 +00:00
await editor.moveCursor(cursorPos + carretPos);
}
2022-05-06 16:55:04 +00:00
}
export async function applyLineReplace(cmdDef: any) {
const cursorPos = await editor.getCursor();
const text = await editor.getText();
const matchRegex = new RegExp(cmdDef.match);
let startOfLine = cursorPos;
while (startOfLine > 0 && text[startOfLine - 1] !== "\n") {
startOfLine--;
}
let currentLine = text.slice(startOfLine, cursorPos);
const emptyLine = !currentLine;
currentLine = currentLine.replace(matchRegex, cmdDef.replace);
await editor.dispatch({
changes: {
from: startOfLine,
to: cursorPos,
insert: currentLine,
},
selection: emptyLine
? {
anchor: startOfLine + currentLine.length,
}
: undefined,
});
}