From 719be35dca6a3edf4bcc1ae1e1daecd6d79dc6c4 Mon Sep 17 00:00:00 2001 From: windingwind <33902321+windingwind@users.noreply.github.com> Date: Sun, 19 Jan 2025 00:50:28 +0100 Subject: [PATCH] doc: update readme and template doc chore: remove deprecated template chore: lint --- .../DISCUSSION_TEMPLATE/note-templates.yml | 1 - .vscode/toolkit.code-snippets | 12 ++++---- README.md | 30 ++++++++++++++++++- docs/about-note-template.md | 13 ++++---- src/modules/template/editorWindow.ts | 5 ++-- src/modules/template/preview.ts | 19 ------------ src/utils/note.ts | 11 ++++--- test/tests/template.spec.ts | 2 +- 8 files changed, 53 insertions(+), 40 deletions(-) diff --git a/.github/DISCUSSION_TEMPLATE/note-templates.yml b/.github/DISCUSSION_TEMPLATE/note-templates.yml index 29f9b1f..878bd56 100644 --- a/.github/DISCUSSION_TEMPLATE/note-templates.yml +++ b/.github/DISCUSSION_TEMPLATE/note-templates.yml @@ -43,7 +43,6 @@ body: - Item - Text - QuickInsert - - QuickBackLink - QuickImport - QuickNote - ExportMDFileName diff --git a/.vscode/toolkit.code-snippets b/.vscode/toolkit.code-snippets index 425b7dd..c7034e6 100644 --- a/.vscode/toolkit.code-snippets +++ b/.vscode/toolkit.code-snippets @@ -18,13 +18,13 @@ "\tremoveIfExists: ${13:true},", "\tcustomCheck: (doc: Document, options: ElementOptions) => ${14:true},", "\tchildren: [$15]", - "}, ${16:container});" - ] + "}, ${16:container});", + ], }, "appendElement - minimum": { "scope": "javascript,typescript", "prefix": "appendElement", - "body": "appendElement({ tag: '$1' }, $2);" + "body": "appendElement({ tag: '$1' }, $2);", }, "register Notifier": { "scope": "javascript,typescript", @@ -39,7 +39,7 @@ "\t) => {", "\t\t$0", "\t}", - "});" - ] - } + "});", + ], + }, } diff --git a/README.md b/README.md index 3022ec7..104dda3 100644 --- a/README.md +++ b/README.md @@ -240,6 +240,17 @@ BN provides APIs for other plugin developers in `Zotero.BetterNotes.api.${API_MO - `$export`: Export note - `$import`: Import note - `editor`: Note editor APIs. Give your script full control of contents in the note editor. +- `note`: Note APIs. Parse and manipulate note content. +- `relation`: Note relation APIs. Get and set note relations. +- `utils`: Utility functions. + +### Concepts about Note-Related APIs + +In Zotero, the content of a note is stored as rich text, while when a note is opened in the note editor, it is rendered by ProseMirror as HTML. + +Most of the time, it is recommended to use the `editor` API to interact with the content of the note, as it supports undo/redo and other features provided by editor. The `editor` API provides a set of powerful functions to analyze and manipulate the content in the note editor. Most of them needs an `editor` instance as the input, you can get the instance by calling `Zotero.BetterNotes.api.editor.getEditorInstance(noteId)`. + +However, if note is not opened in the editor, you cannot get the `editor` instance. In this case, you can use the `note` API to interact with the content of the note. ## 🔧 Development @@ -256,14 +267,31 @@ npm run build The plugin is built to `./builds/*.xpi`. +To debug, run + +```bash +npm run start +``` + +This will open a new Zotero instance with the plugin installed. + +To test the plugin, run + +```bash +npm run test +``` + +This will run the tests in the `./test` directory. + ## 🔔 Disclaimer Use this code under AGPL. No warranties are provided. Keep the laws of your locality in mind! ## 🔎 My Zotero Plugins -- [Translate for Zotero](https://github.com/windingwind/zotero-pdf-translate): PDF translation for Zotero +- [Translate for Zotero](https://github.com/windingwind/zotero-pdf-translate): Translate PDF, EPub, webpage, metadata, annotations, notes to the target language. - [Actions & Tags for Zotero](https://github.com/windingwind/zotero-tag): Customize your Zotero workflow. +- [Bionic for Zotero](https://github.com/windingwind/bionic-for-zotero): Bionic reading experience with Zotero. ## 🙌 Sponsors diff --git a/docs/about-note-template.md b/docs/about-note-template.md index 46c9e26..c461ef8 100644 --- a/docs/about-note-template.md +++ b/docs/about-note-template.md @@ -13,7 +13,7 @@ One-click to import. ```yaml # This template is specifically for importing/sharing, using better # notes 'import from clipboard': copy the content and -# goto Zotero menu bar, click Edit->New Template from Clipboard. +# goto Zotero menu bar, click Tools->New Template from Clipboard. # Do not copy-paste this to better notes template editor directly. name: "[Text] Current Time" content: |- @@ -32,7 +32,7 @@ content: |- -2. Goto Zotero menubar, click `Edit`->`New Template from Clipboard`. +2. Goto Zotero menubar, click `Tools`->`New Template from Clipboard`. 3. Click OK. Now you can open a note/the workspace and in editor toolbar, click `Insert Template to cursor line`. Select the template, it is inserted to the note. @@ -88,7 +88,9 @@ Let the compiler know you are using markdown. Otherwise the template will be pro 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. -> The template with this pragma should not contain any separator (`---` or `
`) in the content. +The template with this pragma should not contain any separator (`---` or `
`) in the content. + +> Since the first line of the content is a separator, the note generated from a template with this pragma will have a blank note title. See the solution [here](https://github.com/windingwind/zotero-better-notes/issues/1247#issuecomment-2573739339). ### `// @author` @@ -148,7 +150,7 @@ If no stage pragma is given, the whole template will be processed on the default ```yaml # This template is specifically for importing/sharing, using better # notes 'import from clipboard': copy the content and -# goto Zotero menu bar, click Edit->New Template from Clipboard. +# goto Zotero menu bar, click Tools->New Template from Clipboard. # Do not copy-paste this to better notes template editor directly. name: "[Item] Example Item Template" content: |- @@ -214,7 +216,6 @@ The name of builtin templates are not allowed to be modified. | Name | Description | Variables | | ------------------- | -------------------------------------------------------- | ------------------------------------- | | QuickInsert | For forward link. | link, linkText, subNoteItem, noteItem | -| QuickBackLink | For back link. | link, linkText, subNoteItem, noteItem | | QuickImport | For importing note link content. | link, noteItem | | QuickNote | For generating note from annotation. | annotationItem, topItem, noteItem | | ExportMDFileName | For generating Markdown file name when exporting. | noteItem | @@ -408,7 +409,7 @@ A template snippet should be in YAML format (YAML has better support for multi-l ```yaml # This template is specifically for importing/sharing, using better # notes 'import from clipboard': copy the content and -# goto Zotero menu bar, click Edit->New Template from Clipboard. +# goto Zotero menu bar, click Tools->New Template from Clipboard. # Do not copy-paste this to better notes template editor directly. name: "[TYPE] TEMPLATE NAME" content: |- diff --git a/src/modules/template/editorWindow.ts b/src/modules/template/editorWindow.ts index be52ce4..011c407 100644 --- a/src/modules/template/editorWindow.ts +++ b/src/modules/template/editorWindow.ts @@ -199,8 +199,9 @@ export async function showTemplateEditor() { const editorWin = (_window.document.querySelector("#editor") as any) .contentWindow; await waitUtilAsync(() => editorWin?.loadMonaco); - const isDark = editorWin?.matchMedia("(prefers-color-scheme: dark)") - .matches; + const isDark = editorWin?.matchMedia( + "(prefers-color-scheme: dark)", + ).matches; const { monaco, editor } = await editorWin.loadMonaco({ language: "javascript", theme: "vs-" + (isDark ? "dark" : "light"), diff --git a/src/modules/template/preview.ts b/src/modules/template/preview.ts index bdb6d73..607186b 100644 --- a/src/modules/template/preview.ts +++ b/src/modules/template/preview.ts @@ -93,25 +93,6 @@ async function renderTemplatePreview( }, ); } - } else if (templateName.includes("QuickBackLink")) { - // link, linkText, subNoteItem, noteItem - const data = inputItems?.find((item) => item.isNote()); - if (!data) { - html = messages.noNoteItem; - } else { - const link = getNoteLink(data); - const noteItem = new Zotero.Item("note"); - const linkText = noteItem.getNoteTitle().trim() || "Workspace Note"; - const subNoteItem = data; - html = await addon.api.template.runTemplate( - templateName, - "link, linkText, subNoteItem, noteItem", - [link, linkText, subNoteItem, noteItem], - { - dryRun: true, - }, - ); - } } else if (templateName.includes("QuickImport")) { // link, noteItem const data = inputItems?.find((item) => item.isNote()); diff --git a/src/utils/note.ts b/src/utils/note.ts index 98f7cb6..b524ea1 100644 --- a/src/utils/note.ts +++ b/src/utils/note.ts @@ -88,7 +88,11 @@ async function addLineToNote( if (editor && !forceMetadata) { // The note is opened. Add line via note editor // If the lineIndex is out of range, the line will be inserted at the end (after the last line) - const pos = getPositionAtLine(editor, lineIndex, lineIndex >= noteLines.length ? "end" : "start"); + const pos = getPositionAtLine( + editor, + lineIndex, + lineIndex >= noteLines.length ? "end" : "start", + ); ztoolkit.log("Add note line via note editor", pos); insert(editor, html, pos); // The selection is automatically moved to the next line @@ -386,9 +390,8 @@ async function copyEmbeddedImagesInHTML( if (!copiedAttachment) { continue; } - nodes.forEach( - (node) => - node?.setAttribute("data-attachment-key", copiedAttachment!.key), + nodes.forEach((node) => + node?.setAttribute("data-attachment-key", copiedAttachment!.key), ); } } diff --git a/test/tests/template.spec.ts b/test/tests/template.spec.ts index 7d5351a..41f3156 100644 --- a/test/tests/template.spec.ts +++ b/test/tests/template.spec.ts @@ -357,7 +357,7 @@ This should not be italic.

Title: ]Title 2

6

> Done! But Markdown is not rendered correctly. Try to add -` +`; assert.equal(html, expected); for (const item of items) { await Zotero.Items.erase(item.id);