From 8463a27ca83603ef496855bec37bb8e34e5b1ef7 Mon Sep 17 00:00:00 2001 From: windingwind <33902321+windingwind@users.noreply.github.com> Date: Sat, 20 Jul 2024 17:31:19 +0800 Subject: [PATCH] add: update content from template --- addon/locale/en-US/addon.ftl | 1 + addon/locale/it-IT/addon.ftl | 1 + addon/locale/ru-RU/addon.ftl | 1 + addon/locale/tr-TR/addon.ftl | 1 + addon/locale/zh-CN/addon.ftl | 1 + docs/about-note-template.md | 8 +++ src/api.ts | 2 + src/elements/workspace/workspace.ts | 7 ++- src/hooks.ts | 4 ++ src/modules/editor/toolbar.ts | 8 +++ src/modules/template/api.ts | 31 +++++++++++- src/modules/template/refresh.ts | 78 +++++++++++++++++++++++++++++ src/utils/editor.ts | 5 ++ src/utils/str.ts | 13 +++-- 14 files changed, 155 insertions(+), 6 deletions(-) create mode 100644 src/modules/template/refresh.ts diff --git a/addon/locale/en-US/addon.ftl b/addon/locale/en-US/addon.ftl index 3b8e05b..33f00c3 100644 --- a/addon/locale/en-US/addon.ftl +++ b/addon/locale/en-US/addon.ftl @@ -65,6 +65,7 @@ editor-toolbar-settings-openAsTab = Open as tab editor-toolbar-settings-openAsWindow = Open as window editor-toolbar-settings-showInLibrary = Show in Library editor-toolbar-settings-insertTemplate = Insert template +editor-toolbar-settings-refreshTemplates = Update content from templates (Beta) editor-toolbar-settings-copyLink = Copy link (L{ $line }) editor-toolbar-settings-copyLinkAtSection = Copy link (Sec. { $section }) editor-toolbar-settings-openParent = Open Attachment diff --git a/addon/locale/it-IT/addon.ftl b/addon/locale/it-IT/addon.ftl index e67809e..8ea0c3d 100644 --- a/addon/locale/it-IT/addon.ftl +++ b/addon/locale/it-IT/addon.ftl @@ -61,6 +61,7 @@ editor-toolbar-settings-openAsTab = Open as tab editor-toolbar-settings-openAsWindow = Open as window editor-toolbar-settings-showInLibrary = Show in Library editor-toolbar-settings-insertTemplate = Inserisci template +editor-toolbar-settings-refreshTemplates = Update content from templates (Beta) editor-toolbar-settings-copyLink = Copia link (L{ $line }) editor-toolbar-settings-copyLinkAtSection = Copia link (Sec. { $section }) editor-toolbar-settings-openParent = Apri allegato diff --git a/addon/locale/ru-RU/addon.ftl b/addon/locale/ru-RU/addon.ftl index 654318b..bbaefa0 100644 --- a/addon/locale/ru-RU/addon.ftl +++ b/addon/locale/ru-RU/addon.ftl @@ -65,6 +65,7 @@ editor-toolbar-settings-openAsTab = Open as tab editor-toolbar-settings-openAsWindow = Open as window editor-toolbar-settings-showInLibrary = Show in Library editor-toolbar-settings-insertTemplate=Вставить шаблон +editor-toolbar-settings-refreshTemplates = Update content from templates (Beta) editor-toolbar-settings-copyLink = Копировать Ссылку (L{ $line }) editor-toolbar-settings-copyLinkAtSection = Копировать Ссылку (Sec. { $section }) editor-toolbar-settings-openParent=Открыть вложение diff --git a/addon/locale/tr-TR/addon.ftl b/addon/locale/tr-TR/addon.ftl index 2db6aed..826d747 100644 --- a/addon/locale/tr-TR/addon.ftl +++ b/addon/locale/tr-TR/addon.ftl @@ -65,6 +65,7 @@ editor-toolbar-settings-openAsTab = Open as tab editor-toolbar-settings-openAsWindow = Open as window editor-toolbar-settings-showInLibrary = Show in Library editor-toolbar-settings-insertTemplate = Insert template +editor-toolbar-settings-refreshTemplates = Update content from templates (Beta) editor-toolbar-settings-copyLink = Copy link (L{ $line }) editor-toolbar-settings-copyLinkAtSection =Copy link (Sec. { $section }) editor-toolbar-settings-openParent = Eki Aç diff --git a/addon/locale/zh-CN/addon.ftl b/addon/locale/zh-CN/addon.ftl index 847c9e4..e2516ce 100644 --- a/addon/locale/zh-CN/addon.ftl +++ b/addon/locale/zh-CN/addon.ftl @@ -65,6 +65,7 @@ editor-toolbar-settings-openAsTab = 在标签页中打开 editor-toolbar-settings-openAsWindow = 在窗口中打开 editor-toolbar-settings-showInLibrary = 在文库中显示 editor-toolbar-settings-insertTemplate=插入模板 +editor-toolbar-settings-refreshTemplates = 更新模板生成内容 (Beta) editor-toolbar-settings-copyLink=复制行(L{ $line }) editor-toolbar-settings-copyLinkAtSection=复制节(Sec. { $section }) editor-toolbar-settings-openParent=打开附件 diff --git a/docs/about-note-template.md b/docs/about-note-template.md index c66179c..923f96b 100644 --- a/docs/about-note-template.md +++ b/docs/about-note-template.md @@ -83,6 +83,14 @@ Pragmas are lines start with `// @`. They have special effect and will not be re Let the compiler know you are using markdown. Otherwise the template will be processed as HTML. +### `// @use-update` + +Allow the generated content to be updated using the `Update content from templates` in the note editor. +The generated content will be wrapped in separators with a YAML metadata section for update. +This is a beta feature and can be changed/removed in the future. + +> The template with this pragma should not contain any separator (`---` or `
${yamlContent}${str}
+") &&
+ lines[index + 1].includes("template: ")
+ );
+ }
+
+ function isTemplateWrapperEnd(index: number) {
+ return startIndex >= 0 && lines[index].trim() === "
";
+ }
+
+ for (let i = 0; i < lines.length; i++) {
+ // Match: 1. current line is
; 2. next line is and contains template key; 3. then contains any number of lines; until end with
line
+ if (isTemplateWrapperStart(i)) {
+ startIndex = i;
+ continue;
+ }
+ if (isTemplateWrapperEnd(i)) {
+ matchedIndexPairs.push({ from: startIndex, to: i });
+ startIndex = -1;
+ }
+ }
+
+ let indexOffset = 0;
+ for (const { from, to } of matchedIndexPairs) {
+ const yamlContent = htmlUnescape(
+ lines[from + 1].replace("", "").replace("", ""),
+ { excludeLineBreak: true },
+ );
+ const { template, items } = YAML.parse(yamlContent) as {
+ template: string;
+ items?: string[];
+ };
+ let html = "";
+ if (template.toLowerCase().startsWith("[item]")) {
+ html = await addon.api.template.runItemTemplate(template, {
+ targetNoteId: editor._item.id,
+ itemIds: items
+ ?.map((id) => {
+ const [libraryID, key] = id.split("/");
+ return Zotero.Items.getIDFromLibraryAndKey(Number(libraryID), key);
+ })
+ .filter((id) => !!id) as number[],
+ });
+ } else {
+ html = await addon.api.template.runTextTemplate(template, {
+ targetNoteId: editor._item.id,
+ });
+ }
+ const currentLineCount = addon.api.editor.getLineCount(editor);
+ addon.api.editor.del(
+ editor,
+ addon.api.editor.getPositionAtLine(editor, from + indexOffset, "start"),
+ addon.api.editor.getPositionAtLine(editor, to + indexOffset + 1, "start"),
+ );
+ const position = addon.api.editor.getPositionAtLine(
+ editor,
+ from + indexOffset,
+ "start",
+ );
+ addon.api.editor.insert(editor, html, position);
+
+ const newLineCount = addon.api.editor.getLineCount(editor);
+ indexOffset -= currentLineCount - newLineCount;
+ }
+}
diff --git a/src/utils/editor.ts b/src/utils/editor.ts
index 3334ed6..0b60c71 100644
--- a/src/utils/editor.ts
+++ b/src/utils/editor.ts
@@ -19,6 +19,7 @@ export {
getSectionAtCursor,
getPositionAtLine,
getPositionAtCursor,
+ getLineCount,
getURLAtCursor,
updateImageDimensionsAtCursor,
updateURLAtCursor,
@@ -251,6 +252,10 @@ function getPositionAtLine(
);
}
+function getLineCount(editor: Zotero.EditorInstance) {
+ return getEditorCore(editor).view.docView.children.length;
+}
+
function getURLAtCursor(editor: Zotero.EditorInstance) {
const core = getEditorCore(editor);
return core.pluginState.link.getHref(core.view.state);
diff --git a/src/utils/str.ts b/src/utils/str.ts
index a356ba5..eb2750e 100644
--- a/src/utils/str.ts
+++ b/src/utils/str.ts
@@ -127,13 +127,20 @@ export function htmlEscape(doc: Document, str: string) {
return div.innerHTML.replace(/"/g, """).replace(/'/g, "'");
}
-export function htmlUnescape(str: string) {
- const map = {
+export function htmlUnescape(
+ str: string,
+ options: {
+ excludeLineBreak?: boolean;
+ } = {},
+) {
+ const map: Record = {
" ": " ",
""": '"',
"'": "'",
- "\n": "",
};
+ if (!options.excludeLineBreak) {
+ map["\n"] = "";
+ }
const re = new RegExp(Object.keys(map).join("|"), "g");
return str.replace(re, function (match) {
return map[match as keyof typeof map];