@noteplanco/noteplan-mcp 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/README.md +257 -0
  2. package/dist/index.d.ts +3 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +8 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/noteplan/embeddings.d.ts +170 -0
  7. package/dist/noteplan/embeddings.d.ts.map +1 -0
  8. package/dist/noteplan/embeddings.js +684 -0
  9. package/dist/noteplan/embeddings.js.map +1 -0
  10. package/dist/noteplan/file-reader.d.ts +77 -0
  11. package/dist/noteplan/file-reader.d.ts.map +1 -0
  12. package/dist/noteplan/file-reader.js +488 -0
  13. package/dist/noteplan/file-reader.js.map +1 -0
  14. package/dist/noteplan/file-writer.d.ts +108 -0
  15. package/dist/noteplan/file-writer.d.ts.map +1 -0
  16. package/dist/noteplan/file-writer.js +621 -0
  17. package/dist/noteplan/file-writer.js.map +1 -0
  18. package/dist/noteplan/filter-store.d.ts +28 -0
  19. package/dist/noteplan/filter-store.d.ts.map +1 -0
  20. package/dist/noteplan/filter-store.js +180 -0
  21. package/dist/noteplan/filter-store.js.map +1 -0
  22. package/dist/noteplan/frontmatter-parser.d.ts +45 -0
  23. package/dist/noteplan/frontmatter-parser.d.ts.map +1 -0
  24. package/dist/noteplan/frontmatter-parser.js +259 -0
  25. package/dist/noteplan/frontmatter-parser.js.map +1 -0
  26. package/dist/noteplan/fuzzy-search.d.ts +7 -0
  27. package/dist/noteplan/fuzzy-search.d.ts.map +1 -0
  28. package/dist/noteplan/fuzzy-search.js +66 -0
  29. package/dist/noteplan/fuzzy-search.js.map +1 -0
  30. package/dist/noteplan/markdown-parser.d.ts +87 -0
  31. package/dist/noteplan/markdown-parser.d.ts.map +1 -0
  32. package/dist/noteplan/markdown-parser.js +519 -0
  33. package/dist/noteplan/markdown-parser.js.map +1 -0
  34. package/dist/noteplan/preferences.d.ts +44 -0
  35. package/dist/noteplan/preferences.d.ts.map +1 -0
  36. package/dist/noteplan/preferences.js +156 -0
  37. package/dist/noteplan/preferences.js.map +1 -0
  38. package/dist/noteplan/ripgrep-search.d.ts +29 -0
  39. package/dist/noteplan/ripgrep-search.d.ts.map +1 -0
  40. package/dist/noteplan/ripgrep-search.js +110 -0
  41. package/dist/noteplan/ripgrep-search.js.map +1 -0
  42. package/dist/noteplan/sqlite-reader.d.ts +77 -0
  43. package/dist/noteplan/sqlite-reader.d.ts.map +1 -0
  44. package/dist/noteplan/sqlite-reader.js +605 -0
  45. package/dist/noteplan/sqlite-reader.js.map +1 -0
  46. package/dist/noteplan/sqlite-writer.d.ts +63 -0
  47. package/dist/noteplan/sqlite-writer.d.ts.map +1 -0
  48. package/dist/noteplan/sqlite-writer.js +574 -0
  49. package/dist/noteplan/sqlite-writer.js.map +1 -0
  50. package/dist/noteplan/types.d.ts +97 -0
  51. package/dist/noteplan/types.d.ts.map +1 -0
  52. package/dist/noteplan/types.js +33 -0
  53. package/dist/noteplan/types.js.map +1 -0
  54. package/dist/noteplan/unified-store.d.ts +289 -0
  55. package/dist/noteplan/unified-store.d.ts.map +1 -0
  56. package/dist/noteplan/unified-store.js +1308 -0
  57. package/dist/noteplan/unified-store.js.map +1 -0
  58. package/dist/server.d.ts +4 -0
  59. package/dist/server.d.ts.map +1 -0
  60. package/dist/server.js +2468 -0
  61. package/dist/server.js.map +1 -0
  62. package/dist/tools/calendar.d.ts +311 -0
  63. package/dist/tools/calendar.d.ts.map +1 -0
  64. package/dist/tools/calendar.js +504 -0
  65. package/dist/tools/calendar.js.map +1 -0
  66. package/dist/tools/embeddings.d.ts +244 -0
  67. package/dist/tools/embeddings.d.ts.map +1 -0
  68. package/dist/tools/embeddings.js +226 -0
  69. package/dist/tools/embeddings.js.map +1 -0
  70. package/dist/tools/events.d.ts +176 -0
  71. package/dist/tools/events.d.ts.map +1 -0
  72. package/dist/tools/events.js +326 -0
  73. package/dist/tools/events.js.map +1 -0
  74. package/dist/tools/filters.d.ts +205 -0
  75. package/dist/tools/filters.d.ts.map +1 -0
  76. package/dist/tools/filters.js +347 -0
  77. package/dist/tools/filters.js.map +1 -0
  78. package/dist/tools/memory.d.ts +6 -0
  79. package/dist/tools/memory.d.ts.map +1 -0
  80. package/dist/tools/memory.js +161 -0
  81. package/dist/tools/memory.js.map +1 -0
  82. package/dist/tools/notes.d.ts +1221 -0
  83. package/dist/tools/notes.d.ts.map +1 -0
  84. package/dist/tools/notes.js +1868 -0
  85. package/dist/tools/notes.js.map +1 -0
  86. package/dist/tools/plugins.d.ts +140 -0
  87. package/dist/tools/plugins.d.ts.map +1 -0
  88. package/dist/tools/plugins.js +782 -0
  89. package/dist/tools/plugins.js.map +1 -0
  90. package/dist/tools/reminders.d.ts +207 -0
  91. package/dist/tools/reminders.d.ts.map +1 -0
  92. package/dist/tools/reminders.js +323 -0
  93. package/dist/tools/reminders.js.map +1 -0
  94. package/dist/tools/search.d.ts +58 -0
  95. package/dist/tools/search.d.ts.map +1 -0
  96. package/dist/tools/search.js +373 -0
  97. package/dist/tools/search.js.map +1 -0
  98. package/dist/tools/spaces.d.ts +484 -0
  99. package/dist/tools/spaces.d.ts.map +1 -0
  100. package/dist/tools/spaces.js +870 -0
  101. package/dist/tools/spaces.js.map +1 -0
  102. package/dist/tools/tasks.d.ts +313 -0
  103. package/dist/tools/tasks.d.ts.map +1 -0
  104. package/dist/tools/tasks.js +690 -0
  105. package/dist/tools/tasks.js.map +1 -0
  106. package/dist/tools/themes.d.ts +91 -0
  107. package/dist/tools/themes.d.ts.map +1 -0
  108. package/dist/tools/themes.js +294 -0
  109. package/dist/tools/themes.js.map +1 -0
  110. package/dist/tools/ui.d.ts +89 -0
  111. package/dist/tools/ui.d.ts.map +1 -0
  112. package/dist/tools/ui.js +137 -0
  113. package/dist/tools/ui.js.map +1 -0
  114. package/dist/utils/applescript.d.ts +5 -0
  115. package/dist/utils/applescript.d.ts.map +1 -0
  116. package/dist/utils/applescript.js +27 -0
  117. package/dist/utils/applescript.js.map +1 -0
  118. package/dist/utils/confirmation-tokens.d.ts +19 -0
  119. package/dist/utils/confirmation-tokens.d.ts.map +1 -0
  120. package/dist/utils/confirmation-tokens.js +58 -0
  121. package/dist/utils/confirmation-tokens.js.map +1 -0
  122. package/dist/utils/date-filters.d.ts +15 -0
  123. package/dist/utils/date-filters.d.ts.map +1 -0
  124. package/dist/utils/date-filters.js +129 -0
  125. package/dist/utils/date-filters.js.map +1 -0
  126. package/dist/utils/date-utils.d.ts +113 -0
  127. package/dist/utils/date-utils.d.ts.map +1 -0
  128. package/dist/utils/date-utils.js +341 -0
  129. package/dist/utils/date-utils.js.map +1 -0
  130. package/dist/utils/folder-matcher.d.ts +14 -0
  131. package/dist/utils/folder-matcher.d.ts.map +1 -0
  132. package/dist/utils/folder-matcher.js +191 -0
  133. package/dist/utils/folder-matcher.js.map +1 -0
  134. package/dist/utils/version.d.ts +10 -0
  135. package/dist/utils/version.d.ts.map +1 -0
  136. package/dist/utils/version.js +88 -0
  137. package/dist/utils/version.js.map +1 -0
  138. package/docs/plugin-api/Calendar.md +448 -0
  139. package/docs/plugin-api/CalendarItem.md +198 -0
  140. package/docs/plugin-api/Clipboard.md +101 -0
  141. package/docs/plugin-api/CommandBar.md +251 -0
  142. package/docs/plugin-api/DataStore.md +700 -0
  143. package/docs/plugin-api/Editor.md +982 -0
  144. package/docs/plugin-api/HTMLView.md +337 -0
  145. package/docs/plugin-api/NoteObject.md +588 -0
  146. package/docs/plugin-api/NotePlan.md +398 -0
  147. package/docs/plugin-api/ParagraphObject.md +242 -0
  148. package/docs/plugin-api/RangeObject.md +56 -0
  149. package/docs/plugin-api/getting-started.md +545 -0
  150. package/docs/plugin-api/plugin-api-condensed.md +526 -0
  151. package/docs/plugin-api/plugin.json +26 -0
  152. package/docs/plugin-api/script.js +542 -0
  153. package/package.json +60 -0
  154. package/scripts/calendar-helper +0 -0
  155. package/scripts/reminders-helper +0 -0
@@ -0,0 +1,982 @@
1
+ NotePlans JavaScript API - Editor
2
+
3
+ <details>
4
+ <summary>API - Window Management</summary>
5
+ <p>
6
+
7
+ ```javascript
8
+ // You can use `NotePlan.editors` to enumerate all editors.
9
+
10
+ /**
11
+ * Get a unique ID for the editor to make it easier to identify it later
12
+ * @type { String }
13
+ */
14
+ .id
15
+
16
+ /**
17
+ * Set / get a custom identifier, so you don't need to cache the unique id.
18
+ * If you are accessing this editor from the enumerator, you can set it like this: `NotePlan.editors[0].customId = "test"`
19
+ * @type { String }
20
+ */
21
+ .customId
22
+
23
+ /**
24
+ * Type of window where the editor is embedded in.
25
+ * Possible values: main|split|floating|unsupported
26
+ * It's unsupported on iOS at the moment.
27
+ * @type { String }
28
+ */
29
+ .windowType
30
+
31
+ /**
32
+ * Get the cursor into a specific editor and send the window to the front.
33
+ */
34
+ .focus()
35
+
36
+ /**
37
+ * Close the split view or window. If it's the main note, it will close the complete main window.
38
+ */
39
+ .close()
40
+
41
+
42
+ /**
43
+ * Set / get the position and size of the window that contains the editor. Returns an object with x, y, width, height values.
44
+ * If you want to change the coordinates or size, save the rect in a variable, modify the variable, then assign it to windowRect.
45
+ * The position of the window might not be very intuitive, because the coordinate system of the screen works differently (starts at the bottom left for example). Recommended is to adjust the size and position of the window relatively to it's values or other windows.
46
+ *
47
+ * This works also by enumerating windows with NotePlan.editors and NotePlan.htmlWindows.
48
+ *
49
+ * Note this is available with v3.9.1
50
+ * Example:
51
+ *
52
+ * const rect = Editor.windowRect
53
+ * rect.height -= 50
54
+ * Editor.windowRect = rect
55
+ *
56
+ * @type { x: Integer, y: Integer, width: Integer, height: Integer }
57
+ */
58
+ .windowRect
59
+
60
+ ```
61
+ </p>
62
+ </details>
63
+
64
+ <details>
65
+ <summary>API - Variables</summary>
66
+ <p>
67
+
68
+ ```javascript
69
+
70
+ Editor
71
+
72
+ /**
73
+ * Get the note object of the opened note in the editor
74
+ * @type {NoteObject}
75
+ */
76
+ .note
77
+
78
+ /**
79
+ * Get or set the markdown text of the note (will be saved to file directly)
80
+ * Contains also the raw frontmatter.
81
+ * @type {String}
82
+ */
83
+ .content
84
+
85
+ /**
86
+ * Get title of the note (first line)
87
+ * @type {String}
88
+ */
89
+ .title
90
+
91
+ /**
92
+ * Get the type of the note (indicates also where it is saved)
93
+ * @type {"Notes" | "Calendar"}
94
+ */
95
+ .type
96
+
97
+ /**
98
+ * Get the filename of the note. This includes the relative folder. So if the note is in the folder "Test". The filename will be `test/filename.txt` for example.
99
+ * @type {String}
100
+ */
101
+ .filename
102
+
103
+ /**
104
+ * Get or set the array of paragraphs contained in this note, such as tasks, bullets, etc. If you set the paragraphs, the content of the note will be updated.
105
+ * Contains also the raw frontmatter (the paragraphs have accordingly ranges that are with frontmatter text offset, as opposed to the selection functions, which don't respect the frontmatter offset).
106
+ * @type {[ParagraphObject]}
107
+ */
108
+ .paragraphs
109
+
110
+ /**
111
+ * Get an array of selected lines. The cursor doesn't have to select the full line, NotePlan returns all complete lines the cursor "touches".
112
+ * Any frontmatter at the very top of the note is ignored. That means line 0 is the first line of the actual note body.
113
+ * @type {[String]}
114
+ */
115
+ .selectedLinesText
116
+
117
+ /**
118
+ * Get an array of selected paragraphs. The cursor doesn't have to select the full paragraph, NotePlan returns all complete paragraphs the cursor "touches"
119
+ * Any frontmatter at the very top of the note is ignored. That means line 0 is the first line of the actual note body. The paragraph ranges reflect this as well and will yield different results than the .paragraphs function, which includes the frontmatter into it's calculations.
120
+ * @type {[ParagraphObject]}
121
+ */
122
+ .selectedParagraphs
123
+
124
+ /**
125
+ * Get the raw selection range (hidden Markdown is considered).
126
+ * Any frontmatter at the very top of the note is ignored. That means line 0 is the first line of the actual note body.
127
+ * @type {RangeObject}
128
+ */
129
+ .selection
130
+
131
+ /**
132
+ * Get the rendered selection range (hidden Markdown is NOT considered).
133
+ * Any frontmatter at the very top of the note is ignored. That means line 0 is the first line of the actual note body.
134
+ * @type {RangeObject}
135
+ */
136
+ .renderedSelection
137
+
138
+ /**
139
+ * Get the selected text.
140
+ * Any frontmatter at the very top of the note is ignored. That means line 0 is the first line of the actual note body.
141
+ * @type {String}
142
+ */
143
+ .selectedText
144
+
145
+ /**
146
+ * Returns the frontmatter key-value pairs inside the note. To set a frontmatter attribute, use setFrontmatterAttribute or
147
+ updateFrontmatterAttributes.
148
+ * You can also use the setter, but you will need to first read the complete frontmatter object (key-value pairs), change it and then
149
+ set it. Otherwise the setter won't be triggered if you set it directly like frontmatterAttributes["key"] = "value" (this won't work).
150
+ The setter is most useful when you want to replace all frontmatter attributes at once.
151
+ * { get set }
152
+ * @type {{[key: string]: string}}
153
+ * Available from v3.16.3
154
+ */
155
+ .frontmatterAttributes
156
+
157
+ /**
158
+ * Returns all types assigned to this note in the frontmatter as an array of strings.
159
+ * You can assign types to a note with frontmatter using `type: meeting-note, empty-note` for example (comma separated).
160
+ * { get }
161
+ * @type {[String]}
162
+ * Available from v3.16.3
163
+ */
164
+ .frontmatterTypes
165
+
166
+ /**
167
+ * Note: Available from NotePlan v3.6.2+
168
+ * Get all supported themes (including custom themes imported into the Theme folder) as an array of theme objects having four keys: "name" (name of the theme as seen in the json file), "mode" (dark or light), "filename" (original filename with "json" as extension) and "values" (parsed json file of the theme as object, so you can access every value like `Editor.availableThemes[0].values["styles"]["body"]["color"]`)
169
+ *
170
+ * Use together with `.setTheme(theme.name)`
171
+ * @type [
172
+ * {
173
+ * name: String,
174
+ * mode: String ("dark", "light"),
175
+ * filename: String,
176
+ * values: {...}
177
+ * }
178
+ * ]
179
+ */
180
+ .availableThemes
181
+
182
+ /**
183
+ * Note: Available from NotePlan v3.6.2+
184
+ * Get the current theme as an object with four keys: "name" (name of the theme as seen in the json file), "mode" (dark or light), "filename" (original filename with "json" as extension) and "values" (parsed json file of the theme as object, so you can access every value like `Editor.currentTheme.values["styles"]["body"]["color"]`). To get the name access Editor.currentTheme.name, for the mode, call Editor.currentTheme.mode, etc.
185
+ * @type {
186
+ * name: String,
187
+ * mode: String ("dark", "light"),
188
+ * filename: String,
189
+ * values: {...}
190
+ * }
191
+ */
192
+ .currentTheme
193
+
194
+ /**
195
+ * Note: Available from NotePlan v3.6.2+
196
+ * Get the current system mode, either "dark" or "light.
197
+ * @type { String }
198
+ */
199
+ .currentSystemMode
200
+
201
+ /**
202
+ * Prevents the next "Delete future todos" dialog when deleting a line with a @repeat tag. Will be reset automatically.
203
+ * @type { Boolean }
204
+ */
205
+ .skipNextRepeatDeletionCheck
206
+
207
+ ```
208
+ </p>
209
+ </details>
210
+
211
+ <details>
212
+ <summary>Examples</summary>
213
+ <p>
214
+
215
+ ```javascript
216
+ function noteInformation() {
217
+ try {
218
+ var title = Editor.title // First line of the note, typically the title
219
+ var type = Editor.type // Can be 'Calendar' or 'Notes'
220
+ var filename = Editor.filename // Actual filename as in Finder
221
+
222
+ console.log("Note info:\n\ttitle = " + title + "\n\ttype = " + type + "\n\tfilename = " + filename)
223
+ } catch (error) {
224
+ console.log("Plugin code error: \n"+JSON.stringify(error))
225
+ }
226
+ }
227
+
228
+ function selectionExample() {
229
+ try {
230
+ // By default you deal with raw selections and text
231
+ // Use the text "[link](https://noteplan.co) TEST" as a test to demonstrate the difference to rendered text and place the cursor before the "T" of "TEST".
232
+ let rawPos = Editor.selection
233
+ console.log("Raw selection: start = " + rawPos.start + " length = " + rawPos.length)
234
+
235
+ // Alternatively, return the rendered selection. Means the URLs are compressed to a single character and folded text will be also ignored.
236
+ let renderedPos = Editor.renderedSelection
237
+ console.log("Rendered selection: start = " + renderedPos.start + " length = " + renderedPos.length)
238
+
239
+ var selectedLines = Editor.selectedLinesText
240
+ console.log("Selected lines: " + selectedLines)
241
+
242
+ // Should select the "TEST" in "[link](https://noteplan.co) TEST"
243
+ Editor.select(28, 4)
244
+ } catch (error) {
245
+ console.log("Plugin code error: \n"+JSON.stringify(error))
246
+ }
247
+ }
248
+ ```
249
+
250
+ </p>
251
+ </details>
252
+
253
+ <details>
254
+ <summary>API - Functions (opening notes, inserting text, selection)</summary>
255
+ <p>
256
+
257
+ ```javascript
258
+
259
+ Editor
260
+
261
+ /**
262
+ * Note: Available from NotePlan v3.2 (Mac Build: 662, iOS Build: 593)
263
+ * Selects the full text in the editor.
264
+ */
265
+ .selectAll()
266
+
267
+ /**
268
+ * Note: Available from NotePlan v3.2 (Mac Build: 662, iOS Build: 593)
269
+ * Copies the currently selected text in the editor to the system clipboard.
270
+ */
271
+ .copySelection()
272
+
273
+ /**
274
+ * Note: Available from NotePlan v3.2 (Mac Build: 662, iOS Build: 593)
275
+ * Pastes the current content in the system clipboard into the current selection in the editor.
276
+ */
277
+ .pasteClipboard()
278
+
279
+ /**
280
+ * Inserts the given text at the given character position (index)
281
+ * @param {String} text - Text to insert
282
+ * @param {Number} index - Position to insert at (you can get this using 'renderedSelection' for example)
283
+ */
284
+ .insertTextAtCharacterIndex(text, index)
285
+
286
+ /**
287
+ * Replaces the text at the given range with the given text
288
+ * @param {String} text - Text to insert
289
+ * @param {Number} location - Position to insert at (you can get this using 'renderedSelection' for example)
290
+ * @param {Number} length - Amount of characters to replace from the location
291
+ */
292
+ .replaceTextInCharacterRange(text, location, length)
293
+
294
+ /**
295
+ * Inserts the given text at the current cursor position
296
+ * @param {String} text - Text to insert
297
+ */
298
+ .insertTextAtCursor(text)
299
+
300
+ /**
301
+ * Replaces the current cursor selection with the given text
302
+ * @param {String} text - Text to insert
303
+ */
304
+ .replaceSelectionWithText(text)
305
+
306
+ /**
307
+ * Sets a single frontmatter attribute with the given key and value.
308
+ * If the key already exists, updates its value. If it doesn't exist, adds a new key-value pair.
309
+ * @param {string} key - The frontmatter key to set
310
+ * @param {string} value - The value to set for the key
311
+ * Available from v3.17
312
+ */
313
+ .setFrontmatterAttribute(key, value)
314
+
315
+ /**
316
+ * Updates multiple frontmatter attributes at once in a single operation.
317
+ * More efficient than calling setFrontmatterAttribute multiple times as it only reads and writes the note content once.
318
+ * Each attribute object should have "key" and "value" properties.
319
+ * @param {Array<{key: string, value: string}>} attributes - Array of key-value pairs to update
320
+ * @example
321
+ * Editor.updateFrontmatterAttributes([
322
+ * { key: "title", value: "My Title" },
323
+ * { key: "type", value: "project" },
324
+ * { key: "status", value: "draft" }
325
+ * ])
326
+ * Available from v3.18.1
327
+ */
328
+ .updateFrontmatterAttributes(attributes)
329
+
330
+
331
+ // functions with promises as return values (use with await ... or .then())
332
+ /**
333
+ * Opens a note using the given filename
334
+ * @param {String} filename - Filename of the note file (can be without extension), but has to include the relative folder such as `folder/filename.txt`.
335
+ * @param {Boolean} newWindow - (optional) Open note in new window (default = false)?
336
+ * @param {Number} highlightStart - (optional) Start position of text highlighting
337
+ * @param {Number} highlightEnd - (optional) End position of text highlighting
338
+ * @param {Boolean} splitView - (optional) Open note in a new split view (Note: Available from v3.4)
339
+ * @param {Boolean} createIfNeeded - (optional) Create the note with the given filename if it doesn't exist (only project notes, v3.5.2+)
340
+ * @param {String} content - Content to fill the note (replaces contents if the note already existed) (v3.7.2+)
341
+ * @return {Promise} Note? - When the note has been opened, a promise will be returned with the note object
342
+ */
343
+ .openNoteByFilename(filename, newWindow, highlightStart, highlightEnd, splitView, createIfNeeded, content)
344
+
345
+ /**
346
+ * Opens a note by searching for the give title (first line of the note)
347
+ * @param {String} title - Title (case sensitive) of the note (first line)
348
+ * @param {Boolean} newWindow - (optional) Open note in new window (default = false)?
349
+ * @param {Number} highlightStart - (optional) Start position of text highlighting
350
+ * @param {Number} highlightEnd - (optional) End position of text highlighting
351
+ * @param {Boolean} splitView - (optional) Open note in a new split view (Note: Available from v3.4)
352
+ * @return {Promise} Note? - When the note has been opened, a promise will be returned with the note object
353
+ */
354
+ .openNoteByTitle(title, newWindow, highlightStart, highlightEnd, splitView)
355
+
356
+ /**
357
+ * Opens a note by searching for the give title (first line of the note)
358
+ * @param {String} title - Title (case insensitive) of the note (first line)
359
+ * @param {Boolean} newWindow - (optional) Open note in new window (default = false)?
360
+ * @param {Boolean} caseSensitive - (optional) Should title be case sensitive (default = false)?
361
+ * @param {Number} highlightStart - (optional) Start position of text highlighting
362
+ * @param {Number} highlightEnd - (optional) End position of text highlighting
363
+ * @param {Boolean} splitView - (optional) Open note in a new split view (Note: Available from v3.4)
364
+ * @return {Promise} Note? - When the note has been opened, a promise will be returned with the note object
365
+ */
366
+ .openNoteByTitleCaseInsensitive(title, newWindow, caseSensitive, highlightStart, highlightEnd, splitView)
367
+
368
+ /**
369
+ * Opens a calendar note by the given date
370
+ * @param {Date} date - The date that should be opened, this is a normal JavaScript date object
371
+ * @param {Boolean} newWindow - (optional) Open note in new window (default = false)?
372
+ * @param {Number} highlightStart - (optional) Start position of text highlighting
373
+ * @param {Number} highlightEnd - (optional) End position of text highlighting
374
+ * @param {Boolean} splitView - (optional) Open note in a new split view (Note: Available from v3.4)
375
+ * @param {String} timeframe - (optional) Use "week", "month", "quarter" or "year" to open a calendar note other than a daily one (Note: Available from v3.7.2)
376
+ * @param {String} parent - (optional) Use the ID or filename of a teamspace here to open alternatively a teamspace calendar note. By default it opens the private calendar note.
377
+ * @return {Promise} Note? - When the note has been opened, a promise will be returned with the note object
378
+ */
379
+ .openNoteByDate(date, newWindow, highlightStart, highlightEnd, splitView, timeframe, parent)
380
+
381
+ /**
382
+ * Opens a calendar note by the given date string
383
+ * @param {String} dateString - The date string that should be opened, in ISO format: "YYYYMMDD", like "20210501"
384
+ * @param {Boolean} newWindow - (optional) Open note in new window (default = false)?
385
+ * @param {Number} highlightStart - (optional) Start position of text highlighting
386
+ * @param {Number} highlightEnd - (optional) End position of text highlighting
387
+ * @param {Boolean} splitView - (optional) Open note in a new split view (Note: Available from v3.4)
388
+ * @return {Promise} Note? - When the note has been opened, a promise will be returned with the note object
389
+ */
390
+ .openNoteByDateString(dateString, newWindow, highlightStart, highlightEnd, splitView)
391
+
392
+
393
+ /**
394
+ * Opens a weekly calendar note by the given year and week number
395
+ * @param {Integer} year - The year of the week
396
+ * @param {Integer} weeknumber - The number of the week (0-52/53)
397
+ * @param {Boolean} newWindow - (optional) Open note in new window (default = false)?
398
+ * @param {Number} highlightStart - (optional) Start position of text highlighting
399
+ * @param {Number} highlightEnd - (optional) End position of text highlighting
400
+ * @param {Boolean} splitView - (optional) Open note in a new split view (Note: Available from v3.4)
401
+ * @return {Promise} Note? - When the note has been opened, a promise will be returned with the note object
402
+ */
403
+ .openWeeklyNote(year, weeknumber, newWindow, highlightStart, highlightEnd, splitView)
404
+
405
+ /**
406
+ * (Raw) select text in the editor (like select 10 characters = length from position 2 = start)
407
+ * Raw means here that the position is calculated with the Markdown revealed, including Markdown links and folded text.
408
+ * @param {Number} start - Character start position
409
+ * @param {Number} length - Character length
410
+ */
411
+ .select(start, length)
412
+
413
+ /**
414
+ * (Rendered) select text in the editor (like select 10 characters = length from position 2 = start)
415
+ * Rendered means here that the position is calculated with the Markdown hidden, including Markdown links and folded text.
416
+ * @param {Number} start - Character start position
417
+ * @param {Number} length - Character length
418
+ */
419
+ .renderedSelect(start, length)
420
+
421
+ /**
422
+ * Scrolls to and highlights the given paragraph. If the paragraph is folded, it will be unfolded.
423
+ * @param {ParagraphObject} paragraph
424
+ */
425
+ .highlight(paragraph)
426
+
427
+ /**
428
+ * Scrolls to and highlights the given character range. If the range exists in a folded heading, it will be unfolded.
429
+ * If a note contains frontmatter, the highlight position needs to be offsetted by the length of the frontmatter. To workaround this, you can set ignoreFrontmatter to true and it will subtract the frontmatter length automatically.
430
+ * @param { RangeObject } range
431
+ * @param { Boolean } ignoreFrontmatter (Available from v3.18)
432
+ */
433
+ .highlightByRange(range, ignoreFrontmatter)
434
+
435
+ /**
436
+ * Note: Available from v3.0.23
437
+ * Scrolls to and highlights the given range defined by the character index and the character length it should cover. If the paragraph is folded, it will be unfolded.
438
+ * If a note contains frontmatter, the highlight position needs to be offsetted by the length of the frontmatter. To workaround this, you can set ignoreFrontmatter to true and it will subtract the frontmatter length automatically.
439
+ * @param {Int}
440
+ * @param {Int}
441
+ * @param { Boolean } ignoreFrontmatter (Available from v3.18)
442
+ */
443
+ .highlightByIndex(index, length, ignoreFrontmatter)
444
+
445
+
446
+ /**
447
+ * Note: Available from v3.4, macOS only
448
+ * Opens the print dialog for the current note, so the user can save it as PDF or print it.
449
+ * @param {Bool}
450
+ */
451
+ .printNote(withBacklinksAndEvents)
452
+ ```
453
+
454
+ </p>
455
+ </details>
456
+
457
+ <details>
458
+ <summary>Examples</summary>
459
+ <p>
460
+
461
+ ```javascript
462
+ async function openNoteByDate() {
463
+ try {
464
+ // await Editor.openNoteByDateString("20210411") // Opens 11th April 2021
465
+ // await Editor.openNoteByDateString("20210411.txt") // Opens 11th April 2021
466
+ // await Editor.openNoteByDate(new Date()) // Opens today using a Javascript date
467
+ // await Editor.openNoteByDate(new Date(), true) // date, isNewWindow
468
+ await Editor.openNoteByDate(new Date(), false, 0, 10) // date, isNewWindow, highlightStart, highlightEnd
469
+ console.log("Filename: " + Editor.filename)
470
+ } catch (error) {
471
+ console.log("Plugin code error: \n"+JSON.stringify(error))
472
+ }
473
+ }
474
+
475
+ async function openNoteByFilename() {
476
+ try {
477
+ // await Editor.openNoteByFilename("TEST.txt") // filename
478
+ // await Editor.openNoteByFilename("TEST.txt", true) // filename, isNewWindow
479
+ await Editor.openNoteByFilename("TEST.txt", false, 0, 6) // filename, isNewWindow, highlightStart, highlightEnd
480
+ console.log("Filename: " + Editor.filename)
481
+ } catch (error) {
482
+ console.log("Plugin code error: \n"+JSON.stringify(error))
483
+ }
484
+ }
485
+
486
+ async function openNoteByTitle() {
487
+ try {
488
+ // Opens the first note it can find with that title
489
+ await Editor.openNoteByTitle("Test") // title
490
+ // Editor.openNoteByTitleCaseInsensitive("test")
491
+ // Editor.openNoteByTitle("TEST", true) // title, isNewWindow
492
+ // Editor.openNoteByTitle("TEST", false, 0, 6) // title, isNewWindow, highlightStart, highlightEnd
493
+ console.log("Filename: " + Editor.filename)
494
+ } catch (error) {
495
+ console.log("Plugin code error: \n"+JSON.stringify(error))
496
+ }
497
+ }
498
+
499
+ async function highlight() {
500
+ try {
501
+ let paragraphs = Editor.paragraphs
502
+ let re = await CommandBar.showOptions(paragraphs.map(p => (p.lineIndex + ": " + p.content)), "Select a paragraph to highlight")
503
+ Editor.highlight(paragraphs[re.index])
504
+ } catch (error) {
505
+ console.log("Plugin code error: \n"+JSON.stringify(error))
506
+ }
507
+ }
508
+
509
+ ```
510
+
511
+ </p>
512
+ </details>
513
+
514
+ <details>
515
+ <summary>API - Functions (paragraphs)</summary>
516
+ <p>
517
+
518
+ ```javascript
519
+
520
+ Editor
521
+
522
+
523
+ /* When you are changing the text in the editor through the functions below,
524
+ * they are updated live but not saved immediately. The editor saves changes
525
+ * to the next after 1-2 seconds of inactivity.
526
+ * When you get the list of paragraphs from the editor and then make changes that
527
+ * alter the line indeces of other paragraphs (like in the case of insert...,
528
+ * remove..., etc.), you need to get a new array of paragraphs to keep
529
+ * changing them. Paragraphs have no IDs and so NotePlan relies on the
530
+ * line index to match them up. So if the index changes, the reference is lost.
531
+ */
532
+
533
+ /**
534
+ * Returns a range object of the full paragraph of the given character position.
535
+ * @param {Number} pos - Character position
536
+ * @return {RangeObject} - The range of the paragraph = { .start, .end, .length }
537
+ */
538
+ .paragraphRangeAtCharacterIndex(pos)
539
+
540
+ /**
541
+ * Inserts a plain paragrah at the given line index
542
+ * @param {String} content - Text of the paragraph
543
+ * @param {Number} lineIndex - Line index where the todo should be inserted
544
+ * @param {"open", "done", "scheduled", "cancelled", "quote", "title", "title", "list" (= bullet), "text" (= plain text) or "empty" (= no text)} type
545
+ */
546
+ .insertParagraph(content, lineIndex, type)
547
+
548
+ /**
549
+ * Inserts a plain paragrah before the selected paragraph (or the paragraph the cursor is currently positioned)
550
+ * @param {String} content - Text of the paragraph
551
+ * @param {"open", "done", "scheduled", "cancelled", "quote", "title", "title", "list" (= bullet), "text" (= plain text) or "empty" (= no text)} type
552
+ * @param {Number} indents - How much it should be indented
553
+ */
554
+ .insertParagraphAtCursor(content, type, indents)
555
+
556
+ /**
557
+ * Inserts a todo at the given line index
558
+ * @param {String} content - Name of the todo (without the todo '* [ ] ' Markdown)
559
+ * @param {Number} lineIndex - Line index where the todo should be inserted
560
+ */
561
+ .insertTodo(content, lineIndex)
562
+
563
+ /**
564
+ * Inserts a completed todo at the given line index
565
+ * @param {String} content - Text of the completed todo (without the todo '* [x] ' Markdown)
566
+ * @param {Number} lineIndex - Line index where the todo should be inserted
567
+ */
568
+ .insertCompletedTodo(content, lineIndex)
569
+
570
+ /**
571
+ * Inserts a cancelled todo at the given line index
572
+ * @param {String} content - Text of the cancelled todo (without the todo '* [-] ' Markdown)
573
+ * @param {Number} lineIndex - Line index where the todo should be inserted
574
+ */
575
+ .insertCancelledTodo(content, lineIndex)
576
+
577
+ /**
578
+ * Inserts a scheduled todo at the given line index
579
+ * @param {String} content - Text of the scheduled todo (without the todo '* [>] ' Markdown)
580
+ * @param {Number} lineIndex - Line index where the todo should be inserted
581
+ * @param {Date} date - (optional) JavaScript date object if you need the date link '>YYYY-MM-DD'
582
+ */
583
+ .insertScheduledTodo(content, lineIndex, date)
584
+
585
+ /**
586
+ * Inserts a quote at the given line index
587
+ * @param {String} content - Text of the quote (without the quote '> ' Markdown)
588
+ * @param {Number} lineIndex - Line index where the todo should be inserted
589
+ */
590
+ .insertQuote(content, lineIndex)
591
+
592
+ /**
593
+ * Inserts a list (bullet) item at the given line index
594
+ * @param {String} content - Text of the bullet (without the bullet '- ' Markdown)
595
+ * @param {Number} lineIndex - Line index where the todo should be inserted
596
+ */
597
+ .insertList(content, lineIndex)
598
+
599
+ /**
600
+ * Inserts a heading at the given line index
601
+ * @param {String} content - Text of the heading (without the heading '## ' Markdown)
602
+ * @param {Number} lineIndex - Line index where the todo should be inserted
603
+ * @param {Number} level - Heading level, 1 - based, for example 2 = "## <text>"
604
+ */
605
+ .insertHeading(content, lineIndex, level)
606
+
607
+ /**
608
+ * Appends a todo at the end of the note
609
+ * @param {String} content - Text of the todo (without the heading '* [ ] ' Markdown)
610
+ */
611
+ .appendTodo(content)
612
+
613
+ /**
614
+ * Prepends a todo at the beginning of the note (after the title heading)
615
+ * @param {String} content - Text of the todo (without the heading '* [ ] ' Markdown)
616
+ */
617
+ .prependTodo(content)
618
+
619
+ /**
620
+ * Appends a paragraph at the end of the note
621
+ * @param {String} content - Text of the paragaraph
622
+ * @param {"open", "done", "scheduled", "cancelled", "quote", "title", "list" (= bullet), "text" (= plain text) or "empty" (= no text)} type
623
+ */
624
+ .appendParagraph(content, type)
625
+
626
+ /**
627
+ * Prepends a paragraph at the beginning of the note (after the title heading)
628
+ * @param {String} content - Text of the paragaraph
629
+ * @param {"open", "done", "scheduled", "cancelled", "quote", "title", "list" (= bullet), "text" (= plain text) or "empty" (= no text)} type
630
+ */
631
+ .prependParagraph(content, type)
632
+
633
+ /**
634
+ * Inserts a todo below the given title of a heading (at the beginning or end of existing text)
635
+ * @param {String} content - Text of the todo
636
+ * @param {String} headingTitle - Title of the heading (without '# Markdown)
637
+ * @param {Boolean} shouldAppend - If the todo should be appended at the bottom of existing text
638
+ * @param {Boolean} shouldCreate - If the heading should be created if non-existing
639
+ */
640
+ .addTodoBelowHeadingTitle(content, headingTitle, shouldAppend, shouldCreate)
641
+
642
+ /**
643
+ * Inserts a paragraph below the given title of a heading (at the beginning or end of existing text)
644
+ * @param {String} content - Text of the paragraph
645
+ * @param {"open", "done", "scheduled", "cancelled", "quote", "title", "list" (= bullet), "text" (= plain text) or "empty" (= no text)} paragraphType
646
+ * @param {String} headingTitle - Title of the heading (without '# Markdown)
647
+ * @param {Boolean} shouldAppend - If the todo should be appended at the bottom of existing text
648
+ * @param {Boolean} shouldCreate - If the heading should be created if non-existing
649
+ */
650
+ .addParagraphBelowHeadingTitle(content, paragraphType, headingTitle, shouldAppend: Bool, shouldCreate)
651
+
652
+ /**
653
+ * Appends a todo below the given heading index (at the end of existing text)
654
+ * @param {String} content - Text of the todo
655
+ * @param {Number} headinLineIndex - Line index of the heading (get the line index from a paragraph object)
656
+ */
657
+ .appendTodoBelowHeadingLineIndex(content, headinLineIndex)
658
+
659
+ /**
660
+ * Appends a paragraph below the given heading index (at the end of existing text)
661
+ * @param {String} content - Text of the paragraph
662
+ * @param {"open", "done", "scheduled", "cancelled", "quote", "title", "list" (= bullet), "text" (= plain text) or "empty" (= no text)} paragraphType
663
+ * @param {Number} headinLineIndex - Line index of the heading (get the line index from a paragraph object)
664
+ */
665
+ .appendParagraphBelowHeadingLineIndex(content, paragraphType, headinLineIndex)
666
+
667
+ /**
668
+ * Inserts a todo after a given paragraph
669
+ * @param {String} content - Text of the paragraph
670
+ * @param {ParagraphObject} otherParagraph - Another paragraph, get it from `.paragraphs`
671
+ */
672
+ .insertTodoAfterParagraph(content, otherParagraph)
673
+
674
+ /**
675
+ * Inserts a todo before a given paragraph
676
+ * @param {String} content - Text of the paragraph
677
+ * @param {ParagraphObject} otherParagraph - Another paragraph, get it from `.paragraphs`
678
+ */
679
+ .insertTodoBeforeParagraph(content, otherParagraph)
680
+
681
+ /**
682
+ * Inserts a paragraph after a given paragraph
683
+ * @param {String} content - Text of the paragraph
684
+ * @param {ParagraphObject} otherParagraph - Another paragraph, get it from `.paragraphs`
685
+ * @param {"open", "done", "scheduled", "cancelled", "quote", "title", "list" (= bullet), "text" (= plain text) or "empty" (= no text)} paragraphType
686
+ */
687
+ .insertParagraphAfterParagraph(content, otherParagraph, paragraphType)
688
+
689
+ /**
690
+ * Inserts a paragraph before a given paragraph
691
+ * @param {String} content - Text of the paragraph
692
+ * @param {ParagraphObject} otherParagraph - Another paragraph, get it from `.paragraphs`
693
+ * @param {"open", "done", "scheduled", "cancelled", "quote", "title", "list" (= bullet), "text" (= plain text) or "empty" (= no text)} paragraphType
694
+ */
695
+ .insertParagraphBeforeParagraph(content, otherParagraph, paragraphType)
696
+
697
+ /**
698
+ * Removes a paragraph at a given line index
699
+ * @param {Number} lineIndex - Line index of the paragraph
700
+ */
701
+ .removeParagraphAtIndex(lineIndex)
702
+
703
+ /**
704
+ * Removes a given paragraph. If you need to remove multiple paragraphs, prefer using `.removeParagraphs(ps)`, which is safer.
705
+ * @param {ParagraphObject} paragraph - Paragraph object to remove, get it from `.paragraphs`
706
+ */
707
+ .removeParagraph(paragraph)
708
+
709
+ /**
710
+ * Removes an array paragraphs
711
+ * @param {[ParagraphObject]} paragraphs - Paragraph objects to remove, get it from `.paragraphs`
712
+ */
713
+ .removeParagraphs(paragraphs)
714
+
715
+ /**
716
+ * Updates a given paragraph. Get the paragraph, then modify it and update the text in the note or editor using this method.
717
+ * @param {ParagraphObject} paragraph - Paragraph object to update, get it from `.paragraphs`
718
+ */
719
+ .updateParagraph(paragraph)
720
+
721
+ /**
722
+ * Updates an array paragraphs. Get the paragraphs, then modify them and update the text in the note or editor using this method.
723
+ * @param {[ParagraphObject]} paragraphs - Paragraph objects to update, get it from `.paragraphs`
724
+ */
725
+ .updateParagraphs(paragraphs)
726
+
727
+ /**
728
+ * Generates a unique block ID and adds it to the content of this paragraph. Remember to call .updateParagraph(p) to write it to the note. You can call this on the Editor or note you got the paragraph from.
729
+ * @param {ParagraphObject}
730
+ */
731
+ .addBlockID(paragraph)
732
+ ```
733
+
734
+ </p>
735
+ </details>
736
+
737
+ <details>
738
+ <summary>Examples</summary>
739
+ <p>
740
+
741
+ ```javascript
742
+ async function insertTodo() {
743
+ try {
744
+ // Ask user to type the name
745
+ let text = await CommandBar.showInput("Type the name of the task", "Create task named '%@'")
746
+ let lines = Editor.paragraphs
747
+
748
+ let re = await CommandBar.showOptions(lines.map(p => p.lineIndex.toString() + ": " + p.content),
749
+ "Select line for the new task")
750
+ let line = lines[re.index]
751
+ console.log("selected line: " + line.content)
752
+
753
+ if(line != undefined) {
754
+ Editor.insertTodo(text, line.lineIndex)
755
+ } else {
756
+ console.log("index undefined")
757
+ }
758
+ } catch (error) {
759
+ console.log("Plugin code error: \n"+JSON.stringify(error))
760
+ }
761
+ }
762
+
763
+ async function appendTodo() {
764
+ try {
765
+ let text = await CommandBar.showInput("Type the name of the task", "Create task named '%@'")
766
+ Editor.prependTodo(text)
767
+ } catch (error) {
768
+ console.log("Plugin code error: \n"+JSON.stringify(error))
769
+ }
770
+ }
771
+
772
+ async function addTaskToNote() {
773
+ try {
774
+ let notes = DataStore.projectNotes
775
+
776
+ // CommandBar.showOptions only takes [string] as input
777
+ let re = await CommandBar.showOptions(notes.map(n => n.title), "Select note for new todo")
778
+ let note = notes[re.index]
779
+
780
+ let todoTitle = await CommandBar.showInput("Type the task", "Add task '%@' to '" + note.title + "'")
781
+ note.insertTodo(todoTitle, 1)
782
+ } catch (error) {
783
+ console.log("Plugin code error: \n"+JSON.stringify(error))
784
+ }
785
+ }
786
+
787
+ async function addTaskToHeading() {
788
+ try {
789
+ // First ask for the note we want to add the todo
790
+ let notes = DataStore.projectNotes
791
+
792
+ // CommandBar.showOptions only takes [string] as input
793
+ let re = await CommandBar.showOptions(notes.map(n => n.title), "Select note for new todo")
794
+ let note = notes[re.index]
795
+ printNote(note)
796
+
797
+ // Ask to which heading to add the todo
798
+ let headings = note.paragraphs.filter(p => p.type == "title")
799
+ let re2 = await CommandBar.showOptions(headings.map(p => (p.prefix + p.content)), "Select a heading")
800
+
801
+ let heading = headings[re2.index]
802
+ console.log("Selected heading: " + heading.content)
803
+
804
+ // Ask for the todo title finally
805
+ let todoTitle = await CommandBar.showInput("Type the task", "Add task '%@' to '" + note.title + "'")
806
+ console.log("Adding todo: " + todoTitle + " to " + note.title + " in heading: " + heading.content)
807
+
808
+ // Add todo to the heading in the note
809
+ note.appendTodoBelowHeadingLineIndex(todoTitle, heading.lineIndex) // This works also if there are duplicate headings
810
+
811
+ // Alternative implementations
812
+ // note.appendParagraphBelowHeadingLineIndex(todoTitle, "quote", heading.lineIndex)
813
+ // note.addTodoBelowHeadingTitle(todoTitle, heading.content, false, true)
814
+ // note.addParagraphBelowHeadingTitle(todoTitle, "done", heading.content, true, true)
815
+ // note.insertTodoAfterParagraph(todoTitle, heading.content)
816
+ // note.insertTodoBeforeParagraph(todoTitle, heading.content)
817
+ // note.insertParapgrahBeforeParagraph(todoTitle, heading.content, "list")
818
+ // note.insertParagraphAfterParagraph(todoTitle, heading.content, "list")
819
+ } catch (error) {
820
+ console.log("Plugin code error: \n"+JSON.stringify(error))
821
+ }
822
+ }
823
+
824
+ function rangeOfParagraph() {
825
+ try {
826
+ let selection = Editor.selection
827
+ let range = Editor.paragraphRangeAtCharacterIndex(selection.start)
828
+
829
+ let text = "Location: " + range.start + ", length: " + range.length
830
+ CommandBar.showOptions([text], "The paragraph range is:")
831
+ } catch (error) {
832
+ console.log("Plugin code error: \n"+JSON.stringify(error))
833
+ }
834
+ }
835
+
836
+ async function modifyExistingParagraphs() {
837
+ try {
838
+ let paragraphs = Editor.paragraphs
839
+
840
+ // Change the content and type of a paragraph
841
+ let re = await CommandBar.showOptions(paragraphs.map(p => (p.lineIndex + ": " + p.content)), "Select a paragraph to modify")
842
+ let newParagraphText = await CommandBar.showInput("New content of selected paragraph", "Change paragraph to '%@'")
843
+ let newType = await CommandBar.showOptions(["open", "done", "scheduled", "cancelled", "quote", "text", "empty", "list", "title"], "Select the new type")
844
+
845
+ paragraphs[re.index].content = newParagraphText
846
+ paragraphs[re.index].type = newType.value
847
+ Editor.paragraphs = paragraphs
848
+
849
+ // Alternative implementation
850
+ // let paragraph = paragraphs[re.index]
851
+ // paragraph.content = newParagraphText
852
+ // paragraph.type = newType.value
853
+ // Editor.updateParagraph(paragraph)
854
+
855
+ } catch (error) {
856
+ console.log("Plugin code error: \n"+JSON.stringify(error))
857
+ }
858
+ }
859
+
860
+ async function removeParagraph() {
861
+ try {
862
+ let paragraphs = Editor.paragraphs
863
+
864
+ let re = await CommandBar.showOptions(paragraphs.map(p => (p.lineIndex + ": " + p.content)), "Select a paragraph to remove")
865
+
866
+ Editor.removeParagraphAtIndex(re.index)
867
+
868
+ // Alternative implementations
869
+ // Editor.removeParagraph(paragraphs[re.index])
870
+
871
+ // or...
872
+ // paragraphs.splice(re.index, 1)
873
+ // Editor.paragraphs = paragraphs
874
+ } catch (error) {
875
+ console.log("Plugin code error: \n"+JSON.stringify(error))
876
+ }
877
+ }
878
+
879
+ async function assignBlockID() {
880
+ try {
881
+ let paragraphs = Editor.paragraphs
882
+ Editor.addBlockID(paragraphs[0])
883
+ Editor.updateParagraph(paragraphs[0])
884
+ } catch (error) {
885
+ console.log("Plugin code error: \n"+JSON.stringify(error))
886
+ }
887
+ }
888
+
889
+
890
+ ```
891
+
892
+ </p>
893
+ </details>
894
+
895
+
896
+ <details>
897
+ <summary>API - Functions (other)</summary>
898
+ <p>
899
+
900
+ ```javascript
901
+ /**
902
+ * Note: Available from NotePlan v3.6.2+
903
+ * Change the current theme. Get all available theme names using `.availableThemes`. Custom themes are also supported (works only with the filename). This will not save the theme, it will just set it. If the system switched from light to dark mode, NotePlan will automatically load up the default (saved) theme for that mode.
904
+ * @param {String}
905
+ */
906
+ .setTheme(filename)
907
+
908
+ /**
909
+ * Note: Available from NotePlan v3.6.2+
910
+ * Saves the default theme for a specific mode. It will not set the currently used theme, but just save it. So if you restart NotePlan or the system mode changes, it will use this saved default theme (if it's the same mode you saved it for). As mode use "dark", "light" or "auto" (uses the current system mode).
911
+ * @param {String}
912
+ * @param {String}
913
+ */
914
+ .saveDefaultTheme(filename, mode)
915
+
916
+ /**
917
+ * Note: Available from NotePlan v3.1+
918
+ * Add a new theme using the raw json string. It will be added as a custom theme and you can load it right away with `.setTheme(name)` using the filename defined as second parameter. Use ".json" as file extension.
919
+ * It returns true if adding was successful and false if not. An error will be also printed into the console.
920
+ * Adding a theme might fail, if the given json text was invalid. Make sure to stringify the json using `JSON.stringify(theme)`.
921
+ * @param {String}
922
+ * @param {String}
923
+ * @return {Boolean}
924
+ */
925
+ .addTheme(stringifiedJSON, filename)
926
+
927
+ /**
928
+ * Note: Available from NotePlan v3.9.3+
929
+ * Saves the content of the editor into the note file, so you can work with the updated cache later (you might need to call DataStore.updateCache(note, true) to update tags etc.).
930
+ * @param {Float} - optional timeout in seconds, default is 2.0 seconds (v3.18.2)
931
+ * @return {Promise}
932
+ */
933
+ .save(timeout)
934
+ ```
935
+
936
+ </p>
937
+ </details>
938
+
939
+ <details>
940
+ <summary>Examples</summary>
941
+ <p>
942
+
943
+ ```javascript
944
+ function customTheme() {
945
+ let json = `
946
+ {
947
+ "name": "Monospace-Light",
948
+ "style": "Light",
949
+ "author": {
950
+ "name": "David - Not really author, more like surgeon",
951
+ "email": "hello@noteplan.co"
952
+ },
953
+ "editor": {
954
+ "backgroundColor": "#ffffff",
955
+ "altBackgroundColor": "#FAFFFF",
956
+ "tintColor": "#DD4C4F",
957
+ "tintColor2": "#DD4C4F",
958
+ "textColor": "#333333",
959
+ "toolbarBackgroundColor": "#F3F5F7",
960
+ "toolbarIconColor": "#dd4c4f",
961
+ "menuItemColor": "#dd4c4f",
962
+ "shouldOverwriteFont": false,
963
+ "font": "Menlo-Regular",
964
+ },
965
+ "styles": {
966
+ "body": {
967
+ "font": "Menlo-Regular",
968
+ "size": 16,
969
+ "color": "#444444"
970
+ }
971
+ }
972
+ }
973
+ `
974
+ if (Editor.addTheme(json, "plain-text.json")) {
975
+ console.log(Editor.availableThemes)
976
+ Editor.setTheme("plain-text.json")
977
+ }
978
+ }
979
+ ```
980
+
981
+ </p>
982
+ </details>