add: batch export
This commit is contained in:
parent
6ec4ba1e31
commit
5b29479186
|
|
@ -43,7 +43,9 @@
|
|||
|
||||
<popup id="zotero-itemmenu">
|
||||
<menuseparator />
|
||||
<menuitem id="zotero-itemmenu-__addonRef__-setMainKnowledge" label="&zotero.__addonRef__.itemmenu.setMainKnowledge.label;" oncommand="Zotero.Knowledge4Zotero.events.onEditorEvent.bind(Zotero.Knowledge4Zotero.events)({type: 'setMainKnowledge', content: {params: {itemID: ZoteroPane.getSelectedItems()[0].id}}})" class="menuitem-iconic" style="list-style-image: url('chrome://__addonRef__/skin/favicon.png');" />
|
||||
<menuitem id="zotero-itemmenu-__addonRef__-setMainKnowledge" class="menuitem-iconic popup-type-single-note" label="&zotero.__addonRef__.itemmenu.setMainKnowledge.label;" oncommand="Zotero.Knowledge4Zotero.events.onEditorEvent.bind(Zotero.Knowledge4Zotero.events)({type: 'setMainKnowledge', content: {params: {itemID: ZoteroPane.getSelectedItems()[0].id}}})" style="list-style-image: url('chrome://__addonRef__/skin/favicon.png');" />
|
||||
<menuitem id="zotero-itemmenu-__addonRef__-exportNote" class="menuitem-iconic popup-type-single" label="&zotero.__addonRef__.itemmenu.exportNote.label;" oncommand="Zotero.Knowledge4Zotero.events.onEditorEvent.bind(Zotero.Knowledge4Zotero.events)({type: 'exportNotes', content: {}})" style="list-style-image: url('chrome://__addonRef__/skin/favicon.png');" />
|
||||
<menuitem id="zotero-itemmenu-__addonRef__-exportNotes" class="menuitem-iconic popup-type-multiple" label="&zotero.__addonRef__.itemmenu.exportNotes.label;" oncommand="Zotero.Knowledge4Zotero.events.onEditorEvent.bind(Zotero.Knowledge4Zotero.events)({type: 'exportNotes', content: {}})" style="list-style-image: url('chrome://__addonRef__/skin/favicon.png');" />
|
||||
</popup>
|
||||
|
||||
<menupopup id="menu_FilePopup">
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@
|
|||
<!ENTITY zotero.__addonRef__.workspace.menu.about "About Better Notes">
|
||||
|
||||
<!ENTITY zotero.__addonRef__.itemmenu.setMainKnowledge.label "Set Main Note">
|
||||
<!ENTITY zotero.__addonRef__.itemmenu.exportNote.label "Export Note and SubNotes">
|
||||
<!ENTITY zotero.__addonRef__.itemmenu.exportNotes.label "Export Notes and SubNotes to Markdown">
|
||||
|
||||
<!ENTITY zotero.__addonRef__.export.title "Export">
|
||||
<!ENTITY zotero.__addonRef__.export.option.label "General">
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@
|
|||
<!ENTITY zotero.__addonRef__.workspace.menu.about "关于Better Notes">
|
||||
|
||||
<!ENTITY zotero.__addonRef__.itemmenu.setMainKnowledge.label "设置为主笔记">
|
||||
<!ENTITY zotero.__addonRef__.itemmenu.exportNote.label "导出笔记及条目子笔记">
|
||||
<!ENTITY zotero.__addonRef__.itemmenu.exportNotes.label "导出笔记及条目子笔记为Markdown">
|
||||
|
||||
<!ENTITY zotero.__addonRef__.export.title "导出笔记">
|
||||
<!ENTITY zotero.__addonRef__.export.option.label "通用">
|
||||
|
|
|
|||
|
|
@ -115,6 +115,8 @@ class AddonEvents extends AddonBase {
|
|||
this.initWorkspaceTab();
|
||||
this._Addon.views.switchRealMenuBar(true);
|
||||
this._Addon.views.switchKey(true);
|
||||
|
||||
this.initItemSelectListener();
|
||||
}
|
||||
|
||||
private async initWorkspaceTab() {
|
||||
|
|
@ -148,6 +150,25 @@ class AddonEvents extends AddonBase {
|
|||
}
|
||||
}
|
||||
|
||||
private initItemSelectListener() {
|
||||
ZoteroPane.itemsView.onSelect.addListener(() => {
|
||||
const items = ZoteroPane.getSelectedItems();
|
||||
const hasNote = items.filter((i) => i.isNote()).length > 0;
|
||||
const singleItem = items.length === 1;
|
||||
document
|
||||
.querySelectorAll(".popup-type-single")
|
||||
.forEach((el) => ((el as HTMLElement).hidden = !singleItem));
|
||||
document
|
||||
.querySelectorAll(".popup-type-multiple")
|
||||
.forEach((el) => ((el as HTMLElement).hidden = singleItem));
|
||||
document
|
||||
.querySelectorAll(".popup-type-single-note")
|
||||
.forEach(
|
||||
(el) => ((el as HTMLElement).hidden = !(singleItem && hasNote))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public addEditorInstanceListener() {
|
||||
if (!Zotero.Notes._knowledgeInit) {
|
||||
Zotero.Notes._knowledgeInit = true;
|
||||
|
|
@ -1135,9 +1156,12 @@ class AddonEvents extends AddonBase {
|
|||
} else if (message.type === "export") {
|
||||
/*
|
||||
message.content = {
|
||||
editorInstance
|
||||
editorInstance?, params?: {item}
|
||||
}
|
||||
*/
|
||||
const item = message.content.editorInstance
|
||||
? message.content.editorInstance._item
|
||||
: message.content.params.item;
|
||||
const io = {
|
||||
dataIn: null,
|
||||
dataOut: null,
|
||||
|
|
@ -1154,12 +1178,40 @@ class AddonEvents extends AddonBase {
|
|||
|
||||
const options = io.dataOut;
|
||||
await this._Addon.knowledge.exportNoteToFile(
|
||||
message.content.editorInstance._item,
|
||||
item,
|
||||
options.embedLink,
|
||||
options.exportFile,
|
||||
options.exportNote,
|
||||
options.exportCopy
|
||||
);
|
||||
} else if (message.type === "exportNotes") {
|
||||
/*
|
||||
message.content = {
|
||||
editorInstance
|
||||
}
|
||||
*/
|
||||
const items = ZoteroPane.getSelectedItems();
|
||||
const noteItems = [];
|
||||
items.forEach((item) => {
|
||||
if (item.isNote()) {
|
||||
noteItems.push(item);
|
||||
}
|
||||
if (item.isRegularItem()) {
|
||||
noteItems.splice(0, 0, Zotero.Items.get(item.getNotes()));
|
||||
}
|
||||
});
|
||||
if (noteItems.length === 0) {
|
||||
this._Addon.views.showProgressWindow(
|
||||
"Better Notes",
|
||||
"No standalone/item note selected."
|
||||
);
|
||||
} else if (noteItems.length === 1) {
|
||||
this.onEditorEvent(
|
||||
new EditorMessage("export", { params: { item: noteItems[0] } })
|
||||
);
|
||||
} else {
|
||||
await this._Addon.knowledge.exportNotesToFile(noteItems);
|
||||
}
|
||||
} else if (message.type === "openAttachment") {
|
||||
/*
|
||||
message.content = {
|
||||
|
|
|
|||
|
|
@ -804,6 +804,86 @@ class Knowledge extends AddonBase {
|
|||
}
|
||||
}
|
||||
|
||||
async exportNotesToFile(notes: ZoteroItem[]) {
|
||||
Components.utils.import("resource://gre/modules/osfile.jsm");
|
||||
const filepath = await pick(
|
||||
Zotero.getString("fileInterface.export"),
|
||||
"folder"
|
||||
);
|
||||
|
||||
if (!filepath) {
|
||||
return;
|
||||
}
|
||||
|
||||
await loadTranslator(TRANSLATOR_ID_BETTER_MARKDOWN);
|
||||
|
||||
this._exportPath = Zotero.File.pathToFile(filepath).path + "/attachments";
|
||||
// Convert to unix format
|
||||
this._exportPath = this._exportPath.replace(/\\/g, "/");
|
||||
|
||||
let attachmentCreated = false;
|
||||
|
||||
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
|
||||
);
|
||||
|
||||
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("<img");
|
||||
if (hasImage && !attachmentCreated) {
|
||||
await Zotero.File.createDirectoryIfMissingAsync(
|
||||
OS.Path.join(...this._exportPath.split(/\//))
|
||||
);
|
||||
attachmentCreated = true;
|
||||
}
|
||||
|
||||
let filename = `${Zotero.File.pathToFile(filepath).path}/${newNote
|
||||
.getNoteTitle()
|
||||
.replace(/[/\\?%*:|"<>]/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.Items.erase(newNote.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async convertNoteLines(
|
||||
currentNote: ZoteroItem,
|
||||
rootNoteIds: number[],
|
||||
|
|
|
|||
Loading…
Reference in New Issue