/* eslint-disable no-useless-escape */ /* eslint-disable no-irregular-whitespace */ import { ClipboardHelper } from "zotero-plugin-toolkit"; import { getAddon } from "../utils/global"; import { resetAll } from "../utils/status"; import { getNoteContent, parseTemplateString } from "../utils/note"; describe("Template", function () { const addon = getAddon(); this.beforeAll(async function () { await resetAll(); }); this.afterEach(async function () {}); it("hooks.onImportTemplateFromClipboard", async function () { const key = importTemplate(); assert.isNotEmpty(key); addon.api.template.removeTemplate(key); }); it("api.template.getTemplateText", async function () { const key = importTemplate(); assert.isNotEmpty(addon.api.template.getTemplateText(key!)); addon.api.template.removeTemplate(key); }); it("api.template.getTemplateText", async function () { const key = importTemplate(); assert.isTrue(addon.api.template.getTemplateKeys().includes(key!)); addon.api.template.removeTemplate(key); }); it("api.template.removeTemplate", async function () { const key = importTemplate(); assert.isNotEmpty(key); addon.api.template.removeTemplate(key!); assert.isFalse(addon.api.template.getTemplateKeys().includes(key!)); }); it("api.template.renderTemplatePreview", async function () { const key = importTemplate(); const preview = await addon.api.template.renderTemplatePreview(key!); const expected = `

Markdown Test Document

Headers

H1 Header

H2 Header

H3 Header

H4 Header

H5 Header
H6 Header

Emphasis

This text is italicized. This text is also italicized.

This text is bold. This text is also bold.

This text is bold and italicized. This text is also bold and italicized.

Links

Link with title Link without title

Images

Blockquotes

This is a blockquote.

Nested blockquote.

Back to the outer blockquote.

Lists

Unordered List

Ordered List

  1. First item

    1. Subitem 1.1

      1. Subitem 1.1.1
  2. Second item

Code

Inline Code

Here is some inline code.

Code Block

def hello_world():
    print("Hello, world!")

Horizontal Rules


This is text between horizontal rules


Tables

Header 1

Header 2

Header 3

Row 1

Data 1.2

Data 1.3

Row 2

Data 2.2

Data 2.3

Math

Inline Math

This is an inline math equation: E=mc2E = mc^2.

Block Math

Below is a block math equation:

abf(x)dx=F(b)F(a)\\int_a^b f(x) \\, dx = F(b) - F(a)

Complex Math

Solve the quadratic equation:

x=b±b24ac2ax = \\frac\{-b \\pm \\sqrt\{b^2 - 4ac\}\}\{2a\}

Nested Elements

Nested Code and Lists

  1. Ordered list item

    • Unordered subitem

      console.log("Nested code block");
      
  2. This is a nested math

    y=x2y=x^2
  3. This is a inline math123123
  4. This is a line table

    1

    2

    3

    4

    5

    6

    7

    8

    9

Special Characters

Escape sequences for special characters: * _ \` [ ] ( ) # + - .

HTML in Markdown

This is a HTML block inside Markdown.

Highlight Text

Highlight text is here

Colored Text

Colored text is here

Task Lists

Strikethrough

This text is strikethrough.

Recursive Elements

Recursive Links and Emphasis

Bold link

Recursive Emphasis

Bold and nested italic within bold.

Image

IMAGE_PLACEHOLDER

Citation

CITATION_PLACEHOLDER

Edge Cases

Empty Link

Link

Zotero Link

Zotero Link

Lone Asterisk

Broken Lists

Long Text Wrapping

This is a very long paragraph that does not have any line breaks and is intended to test how the Markdown engine handles text wrapping when there are no explicit line breaks within the text.


Conclusion

This document contains a wide range of Markdown elements, including headers, lists, blockquotes, inline and block code, tables, images, links, math, and special characters. It also tests recursive and edge cases to ensure the Markdown engine is robust.

`; // debug(preview); // If the template changes, update the expected value by copying the expected value // new ClipboardHelper().addText(parseTemplateString(preview)).copy(); assert.equal(preview, expected); addon.api.template.removeTemplate(key); }); it("api.template.runTextTemplate", async function () { addon.api.template.setTemplate({ name: "[text]Test", text: "

Test

\n

${targetNoteItem.id}

", }); const note = new Zotero.Item("note"); await note.saveTx(); const html = await addon.api.template.runTextTemplate("[text]Test", { targetNoteId: note.id, }); assert.equal(html, `

Test

\n

${note.id}

`); await Zotero.Items.erase(note.id); addon.api.template.removeTemplate("[text]Test"); }); it("api.template.runItemTemplate", async function () { // Also test the use of Markdown pragma addon.api.template.setTemplate({ name: "[item]Test", text: ` // @beforeloop-begin // @use-markdown # Hi! This only renders once // @beforeloop-end // @default-begin

Title: ]\${topItem.getField("title")}

\${{ const note = Zotero.Items.get(targetNoteItem.id); return "

" + note.id + "

"; }}$ // @default-end // @afterloop-begin > Done! But Markdown is not rendered correctly. Try to add \`// @use-markdown\` pragma before this line. // @afterloop-end `, }); const items = []; for (let i = 0; i < 3; i++) { const item = new Zotero.Item("book"); item.setField("title", `Title ${i}`); await item.saveTx(); items.push(item); } const note = new Zotero.Item("note"); await note.saveTx(); const html = await addon.api.template.runItemTemplate("[item]Test", { itemIds: items.map((item) => item.id), targetNoteId: note.id, }); // new ClipboardHelper().addText(parseTemplateString(html)).copy(); const expected = `

Hi! This only renders once

Title: ]Title 0

6

Title: ]Title 1

6

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); } await Zotero.Items.erase(note.id); addon.api.template.removeTemplate("[item]Test"); }); }); function importTemplate() { const shareCode = ` # This template is specifically for importing/sharing, using better # notes 'import from clipboard': copy the content and # goto Zotero menu bar, click Tools->New Template from Clipboard. # Do not copy-paste this to better notes template editor directly. name: "[text]TestGen" zoteroVersion: "7.0.12-beta.1+31bbf2acf" pluginVersion: "2.2.3-beta.2" savedAt: "2025-01-06T09:12:14.939Z" content: |- ${getNoteContent() .split("\n") .map((line) => ` ${line}`) .join("\n")} `; return getAddon().hooks.onImportTemplateFromClipboard(shareCode, { quiet: true, }); }