diff --git a/addon/chrome/content/export.xul b/addon/chrome/content/export.xul
index 8c2c529..98f4e59 100644
--- a/addon/chrome/content/export.xul
+++ b/addon/chrome/content/export.xul
@@ -31,9 +31,13 @@
-
+
+
+
+
+
diff --git a/addon/chrome/locale/en-US/overlay.dtd b/addon/chrome/locale/en-US/overlay.dtd
index 31128f1..2b1c8ad 100644
--- a/addon/chrome/locale/en-US/overlay.dtd
+++ b/addon/chrome/locale/en-US/overlay.dtd
@@ -28,6 +28,7 @@
+
diff --git a/addon/chrome/locale/zh-CN/overlay.dtd b/addon/chrome/locale/zh-CN/overlay.dtd
index e28f90f..959f9ad 100644
--- a/addon/chrome/locale/zh-CN/overlay.dtd
+++ b/addon/chrome/locale/zh-CN/overlay.dtd
@@ -28,6 +28,7 @@
+
diff --git a/src/Better Note Markdown.js b/src/Better Note Markdown.js
index f327b22..c594665 100644
--- a/src/Better Note Markdown.js
+++ b/src/Better Note Markdown.js
@@ -774,6 +774,22 @@ let bundle;
var href = node.getAttribute("href");
var title = cleanAttribute(node.getAttribute("title"));
if (title) title = ' "' + title + '"';
+ if (href.search(/zotero:\/\/note\/\w+\/\w+\//g) !== -1) {
+ // A note link should be converted if it is in the _exportFileDict
+ var _Zotero = Components.classes[
+ "@zotero.org/Zotero;1"
+ ].getService(
+ Components.interfaces.nsISupports
+ ).wrappedJSObject;
+ const noteInfo =
+ _Zotero.Knowledge4Zotero.knowledge._exportFileDict &&
+ _Zotero.Knowledge4Zotero.knowledge._exportFileDict.find(
+ (i) => href.includes(i.link)
+ );
+ if (noteInfo) {
+ href = `./${noteInfo.filename}`;
+ }
+ }
return "[" + content + "](" + href + title + ")";
},
};
@@ -1800,7 +1816,7 @@ let bundle;
);
async function doExport() {
- const _Zotero = Components.classes["@zotero.org/Zotero;1"].getService(
+ var _Zotero = Components.classes["@zotero.org/Zotero;1"].getService(
Components.interfaces.nsISupports
).wrappedJSObject;
Zotero.setCharacterSet("utf-8");
diff --git a/src/events.ts b/src/events.ts
index 6b51729..16bd1bf 100644
--- a/src/events.ts
+++ b/src/events.ts
@@ -126,7 +126,6 @@ class AddonEvents extends AddonBase {
if (state) {
const noteTab = state.tabs.find((t) => t.type === "betternotes");
Zotero.debug(noteTab);
- this._Addon.views.showProgressWindow("1", noteTab.select);
if (noteTab) {
let t = 0;
while (t < 5) {
@@ -1177,18 +1176,20 @@ class AddonEvents extends AddonBase {
await io.deferred.promise;
const options = io.dataOut;
- await this._Addon.knowledge.exportNoteToFile(
- item,
- options.embedLink,
- options.exportFile,
- options.exportNote,
- options.exportCopy
- );
+ if (options.exportFile && options.exportSingleFile) {
+ await this._Addon.knowledge.exportNotesToFile([item], false);
+ } else {
+ await this._Addon.knowledge.exportNoteToFile(
+ item,
+ options.embedLink,
+ options.exportFile,
+ options.exportNote,
+ options.exportCopy
+ );
+ }
} else if (message.type === "exportNotes") {
/*
- message.content = {
- editorInstance
- }
+ message.content = {}
*/
const items = ZoteroPane.getSelectedItems();
const noteItems = [];
@@ -1210,7 +1211,11 @@ class AddonEvents extends AddonBase {
new EditorMessage("export", { params: { item: noteItems[0] } })
);
} else {
- await this._Addon.knowledge.exportNotesToFile(noteItems);
+ const useSingleFile = confirm("Export linked notes to markdown files?");
+ await this._Addon.knowledge.exportNotesToFile(
+ noteItems,
+ !useSingleFile
+ );
}
} else if (message.type === "openAttachment") {
/*
diff --git a/src/export.ts b/src/export.ts
index 6cc3ea6..a752328 100644
--- a/src/export.ts
+++ b/src/export.ts
@@ -23,6 +23,16 @@ class AddonExport extends AddonBase {
) as XUL.Checkbox
).checked = exportFile;
}
+ let exportSingleFile = Zotero.Prefs.get(
+ "Knowledge4Zotero.exportSingleFile"
+ );
+ if (typeof exportSingleFile !== "undefined") {
+ (
+ this._window.document.getElementById(
+ "Knowledge4Zotero-export-enablesingle"
+ ) as XUL.Checkbox
+ ).checked = exportSingleFile;
+ }
let embedLink = Zotero.Prefs.get("Knowledge4Zotero.embedLink");
if (typeof embedLink !== "undefined") {
(
@@ -48,6 +58,25 @@ class AddonExport extends AddonBase {
).checked = exportCopy;
}
}
+ doUpdate(event: XULEvent) {
+ if (
+ event.target.getAttribute("id") === "Knowledge4Zotero-export-enablesingle"
+ ) {
+ (
+ this._window.document.getElementById(
+ "Knowledge4Zotero-export-embedLink"
+ ) as XUL.Checkbox
+ ).disabled = (event.target as XUL.Checkbox).checked;
+ } else if (
+ event.target.getAttribute("id") === "Knowledge4Zotero-export-enablefile"
+ ) {
+ (
+ this._window.document.getElementById(
+ "Knowledge4Zotero-export-enablesingle"
+ ) as XUL.Checkbox
+ ).disabled = !(event.target as XUL.Checkbox).checked;
+ }
+ }
doUnload() {
this.io.deferred && this.io.deferred.resolve();
}
@@ -58,6 +87,11 @@ class AddonExport extends AddonBase {
"Knowledge4Zotero-export-enablefile"
) as XUL.Checkbox
).checked;
+ let exportSingleFile = (
+ this._window.document.getElementById(
+ "Knowledge4Zotero-export-enablesingle"
+ ) as XUL.Checkbox
+ ).checked;
let embedLink = (
this._window.document.getElementById(
"Knowledge4Zotero-export-embedLink"
@@ -74,6 +108,7 @@ class AddonExport extends AddonBase {
) as XUL.Checkbox
).checked;
Zotero.Prefs.set("Knowledge4Zotero.exportFile", exportFile);
+ Zotero.Prefs.set("Knowledge4Zotero.exportSingleFile", exportSingleFile);
Zotero.Prefs.set("Knowledge4Zotero.embedLink", embedLink);
Zotero.Prefs.set("Knowledge4Zotero.exportNote", exportNote);
Zotero.Prefs.set("Knowledge4Zotero.exportCopy", exportCopy);
@@ -81,6 +116,7 @@ class AddonExport extends AddonBase {
Zotero.debug(this.io.dataOut);
this.io.dataOut = {
exportFile: exportFile,
+ exportSingleFile: exportSingleFile,
embedLink: embedLink,
exportNote: exportNote,
exportCopy: exportCopy,
diff --git a/src/knowledge.ts b/src/knowledge.ts
index d3eda8e..4549886 100644
--- a/src/knowledge.ts
+++ b/src/knowledge.ts
@@ -11,6 +11,7 @@ class Knowledge extends AddonBase {
workspaceTabId: string;
_exportNote: ZoteroItem;
_exportPath: string;
+ _exportFileDict: object;
constructor(parent: Knowledge4Zotero) {
super(parent);
this.currentLine = -1;
@@ -712,6 +713,8 @@ class Knowledge extends AddonBase {
if (!saveFile && !saveNote && !saveCopy) {
return;
}
+ this._exportFileDict = [];
+
note = note || this.getWorkspaceNote();
let newNote: ZoteroItem;
if (convertNoteLinks || saveNote) {
@@ -804,8 +807,9 @@ class Knowledge extends AddonBase {
}
}
- async exportNotesToFile(notes: ZoteroItem[]) {
+ async exportNotesToFile(notes: ZoteroItem[], useEmbed: boolean) {
Components.utils.import("resource://gre/modules/osfile.jsm");
+ this._exportFileDict = [];
const filepath = await pick(
Zotero.getString("fileInterface.export"),
"folder"
@@ -821,68 +825,120 @@ class Knowledge extends AddonBase {
// Convert to unix format
this._exportPath = this._exportPath.replace(/\\/g, "/");
- let attachmentCreated = false;
+ if (useEmbed) {
+ for (const note of notes) {
+ let newNote: ZoteroItem;
+ if (this.getLinkFromText(note.getNote())) {
+ const noteID = await ZoteroPane_Local.newNote();
+ newNote = Zotero.Items.get(noteID);
+ const rootNoteIds = [note.id];
- for (const note of notes) {
- let newNote: ZoteroItem;
- if (this.getLinkFromText(note.getNote())) {
- const noteID = await ZoteroPane_Local.newNote();
- newNote = Zotero.Items.get(noteID);
- const rootNoteIds = [note.id];
+ const convertResult = await this.convertNoteLines(
+ note,
+ rootNoteIds,
+ true
+ );
- const convertResult = await this.convertNoteLines(
- note,
- rootNoteIds,
- true
- );
+ this.setLinesToNote(newNote, convertResult.lines);
+ Zotero.debug(convertResult.subNotes);
- this.setLinesToNote(newNote, convertResult.lines);
- Zotero.debug(convertResult.subNotes);
-
- await Zotero.DB.executeTransaction(async () => {
- await Zotero.Notes.copyEmbeddedImages(note, newNote);
- for (const subNote of convertResult.subNotes) {
- await Zotero.Notes.copyEmbeddedImages(subNote, newNote);
- }
- });
- } else {
- newNote = note;
- }
-
- this._exportNote = newNote;
-
- const hasImage = newNote.getNote().includes("
]/g, "-") + "-"
- : ""
- }${note.key}.md`;
- filename = filename.replace(/\\/g, "/");
- const translator = new Zotero.Translate.Export();
- translator.setItems([newNote]);
- translator.setLocation(
- Zotero.File.pathToFile(OS.Path.join(...filename.split(/\//)))
- );
- translator.setTranslator(TRANSLATOR_ID_BETTER_MARKDOWN);
- translator.translate();
- this._Addon.views.showProgressWindow(
- "Better Notes",
- `Note Saved to ${filename}`
- );
- if (newNote.id !== note.id) {
- const _w: Window = ZoteroPane.findNoteWindow(newNote.id);
- if (_w) {
- _w.close();
+ await Zotero.DB.executeTransaction(async () => {
+ await Zotero.Notes.copyEmbeddedImages(note, newNote);
+ for (const subNote of convertResult.subNotes) {
+ await Zotero.Notes.copyEmbeddedImages(subNote, newNote);
+ }
+ });
+ } else {
+ newNote = note;
}
- await Zotero.Items.erase(newNote.id);
+
+ this._exportNote = newNote;
+
+ let filename = `${Zotero.File.pathToFile(filepath).path}/${
+ newNote.getNoteTitle
+ ? newNote.getNoteTitle().replace(/[/\\?%*:|"<>]/g, "-") + "-"
+ : ""
+ }${note.key}.md`;
+ filename = filename.replace(/\\/g, "/");
+
+ this._export(newNote, filename, newNote.id !== note.id);
}
+ } else {
+ // Export every linked note as a markdown file
+ // Find all linked notes that need to be exported
+ let allNoteIds: number[] = [].concat(notes.map((n) => n.id));
+ for (const note of notes) {
+ const subNoteIds = (
+ await Promise.all(
+ note
+ .getNote()
+ .match(/zotero:\/\/note\/\w+\/\w+\//g)
+ .map(async (link) => this.getNoteFromLink(link))
+ )
+ )
+ .filter((res) => res.item)
+ .map((res) => res.item.id);
+ allNoteIds = allNoteIds.concat(subNoteIds);
+ }
+ allNoteIds = new Array(...new Set(allNoteIds));
+ // console.log(allNoteIds);
+ const allNoteItems: ZoteroItem[] = Zotero.Items.get(allNoteIds);
+ const noteLinkDict = allNoteItems.map((_note) => {
+ return {
+ link: this.getNoteLink(_note),
+ id: _note.id,
+ note: _note,
+ filename:
+ (_note.getNoteTitle
+ ? _note.getNoteTitle().replace(/[/\\?%*:|"<> ]/g, "-") + "-"
+ : "") +
+ _note.key +
+ ".md",
+ };
+ });
+ this._exportFileDict = noteLinkDict;
+
+ for (const noteInfo of noteLinkDict) {
+ this._exportNote = noteInfo.note;
+ this._export(
+ noteInfo.note,
+ `${Zotero.File.pathToFile(filepath).path}/${noteInfo.filename}`,
+ false
+ );
+ }
+ }
+ }
+
+ async _export(
+ note: ZoteroItem,
+ filename: string,
+ deleteAfterExport: boolean
+ ) {
+ const hasImage = note.getNote().includes("![]()