add: import note from md
This commit is contained in:
parent
5a9678b7eb
commit
a3524fd5e2
|
|
@ -22,6 +22,7 @@ menuAddNote-newMainNote-enterNoteTitle = Enter new note title:
|
|||
menuAddNote-newMainNote-openWorkspaceTab = Open note workspace now?
|
||||
menuAddNote-newTemplateStandaloneNote = New Standalone Note from Template
|
||||
menuAddNote-newTemplateItemNote = New Item Note from Template
|
||||
menuAddNote-importMD = Import MarkDown File as Note
|
||||
|
||||
menuAddReaderNote-newTemplateNote = New Item Note from Template
|
||||
|
||||
|
|
@ -122,3 +123,4 @@ templatePicker-itemData-title = Choose Item Template Data Source
|
|||
alert-notValidCollectionError = Please select a valid collection.
|
||||
alert-notValidParentItemError = No valid parent item.
|
||||
alert-notValidWorkspaceNote = Workspace note is not set. Create one?
|
||||
alert-syncImportedNotes = Keep imported notes in sync with MarkDown files?
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ menuAddNote-newMainNote-enterNoteTitle=Ввести имя новой замет
|
|||
menuAddNote-newMainNote-openWorkspaceTab=Открыть пространство заметок?
|
||||
menuAddNote-newTemplateStandaloneNote=Новая отдельная заметка из шаблона
|
||||
menuAddNote-newTemplateItemNote=Новая элементная заметка из шаблона
|
||||
menuAddNote-importMD = Импорт файла MarkDown в качестве примечания
|
||||
|
||||
menuAddReaderNote-newTemplateNote=Новая элементная заметка из шаблона
|
||||
|
||||
|
|
@ -122,3 +123,4 @@ templatePicker-itemData-title=Choose Item Template Data Source
|
|||
alert-notValidCollectionError=Выберите валидную коллекцию.
|
||||
alert-notValidParentItemError=Нет валидного родительского элемента.
|
||||
alert-notValidWorkspaceNote=Заметка рабочего пространства не установлена. Создать?
|
||||
alert-syncImportedNotes = Синхронизировать импортированные заметки с файлами MarkDown?
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ menuAddNote-newMainNote-enterNoteTitle=请输入新笔记的标题:
|
|||
menuAddNote-newMainNote-openWorkspaceTab=现在打开笔记工作区吗?
|
||||
menuAddNote-newTemplateStandaloneNote=从模板新建独立笔记
|
||||
menuAddNote-newTemplateItemNote=从模板新建条目子笔记
|
||||
menuAddNote-importMD = 导入MarkDown为笔记
|
||||
|
||||
menuAddReaderNote-newTemplateNote=从模板新建条目子笔记
|
||||
|
||||
|
|
@ -80,7 +81,7 @@ syncInfo-sync=同步
|
|||
syncInfo-unSync=取消同步
|
||||
syncInfo-reveal=在文件夹中显示
|
||||
syncInfo-manager=同步管理
|
||||
syncInfo-export=导出为---
|
||||
syncInfo-export=导出为...
|
||||
syncInfo-cancel=关闭
|
||||
|
||||
sync-start-hint=自动同步已启用, 间隔
|
||||
|
|
@ -122,3 +123,4 @@ templatePicker-itemData-title=选择条目模板数据源
|
|||
alert-notValidCollectionError=请选择一个有效的分类。
|
||||
alert-notValidParentItemError=无效的父条目。
|
||||
alert-notValidWorkspaceNote=工作区笔记未设置。创建一个吗?
|
||||
alert-syncImportedNotes = 保持导入的笔记与 MarkDown 文件同步?
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@
|
|||
"unist-util-visit": "^4.1.2",
|
||||
"unist-util-visit-parents": "^5.1.3",
|
||||
"yamljs": "^0.3.0",
|
||||
"zotero-plugin-toolkit": "2.1.5"
|
||||
"zotero-plugin-toolkit": "^2.1.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/browser-or-node": "^1.3.0",
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ import { showTemplateEditor } from "./modules/template/editorWindow";
|
|||
import {
|
||||
createNoteFromTemplate,
|
||||
createWorkspaceNote,
|
||||
createNoteFromMD,
|
||||
} from "./modules/createNote";
|
||||
import { annotationTagAction } from "./modules/annotationTagAction";
|
||||
|
||||
|
|
@ -302,6 +303,8 @@ const onCreateWorkspaceNote = createWorkspaceNote;
|
|||
|
||||
const onCreateNoteFromTemplate = createNoteFromTemplate;
|
||||
|
||||
const onCreateNoteFromMD = createNoteFromMD;
|
||||
|
||||
// Add your hooks here. For element click, etc.
|
||||
// Keep in mind hooks only do dispatch. Don't add code that does real jobs in hooks.
|
||||
// Otherwise the code would be hard to read and maintain.
|
||||
|
|
@ -328,4 +331,5 @@ export default {
|
|||
onShowTemplateEditor,
|
||||
onCreateWorkspaceNote,
|
||||
onCreateNoteFromTemplate,
|
||||
onCreateNoteFromMD,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { getString } from "../utils/locale";
|
||||
import { config } from "../../package.json";
|
||||
|
||||
export { createWorkspaceNote, createNoteFromTemplate };
|
||||
export { createWorkspaceNote, createNoteFromTemplate, createNoteFromMD };
|
||||
|
||||
async function createWorkspaceNote() {
|
||||
const currentCollection = ZoteroPane.getSelectedCollection();
|
||||
|
|
@ -81,3 +81,41 @@ async function createNoteFromTemplate(
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function createNoteFromMD() {
|
||||
const currentCollection = ZoteroPane.getSelectedCollection();
|
||||
if (!currentCollection) {
|
||||
window.alert(getString("alert.notValidCollectionError"));
|
||||
return;
|
||||
}
|
||||
|
||||
const syncNotes = window.confirm(getString("alert-syncImportedNotes"));
|
||||
|
||||
const filePaths = (await new ztoolkit.FilePicker(
|
||||
"Import MarkDown",
|
||||
"multiple",
|
||||
[[`MarkDown(*.md)`, `*.md`]]
|
||||
).open()) as string[];
|
||||
|
||||
if (!filePaths.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const filepath of filePaths) {
|
||||
const noteItem = await addon.api.$import.fromMD(filepath, {
|
||||
ignoreVersion: true,
|
||||
});
|
||||
if (noteItem && syncNotes) {
|
||||
const pathSplit = Zotero.File.normalizeToUnix(filepath).split("/");
|
||||
const stat = await OS.File.stat(filepath);
|
||||
addon.api.sync.updateSyncStatus(noteItem.id, {
|
||||
itemID: noteItem.id,
|
||||
path: Zotero.File.normalizeToUnix(pathSplit.slice(0, -1).join("/")),
|
||||
filename: pathSplit.pop() || "",
|
||||
lastsync: new Date().getTime(),
|
||||
md5: "",
|
||||
noteMd5: Zotero.Utilities.Internal.md5(noteItem.getNote(), false),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,10 +68,10 @@ async function exportNotes(
|
|||
);
|
||||
if (options.exportMD) {
|
||||
if (options.setAutoSync) {
|
||||
const raw = await new ztoolkit.FilePicker(
|
||||
const raw = (await new ztoolkit.FilePicker(
|
||||
`${getString("fileInterface.sync")} MarkDown File`,
|
||||
"folder"
|
||||
).open();
|
||||
).open()) as string;
|
||||
if (raw) {
|
||||
const syncDir = formatPath(raw);
|
||||
// Hard reset sync status for input notes
|
||||
|
|
@ -140,12 +140,12 @@ async function toMD(
|
|||
) {
|
||||
let filename = options.filename;
|
||||
if (!filename) {
|
||||
const raw = await new ztoolkit.FilePicker(
|
||||
const raw = (await new ztoolkit.FilePicker(
|
||||
`${Zotero.getString("fileInterface.export")} MarkDown File`,
|
||||
"save",
|
||||
[["MarkDown File(*.md)", "*.md"]],
|
||||
`${noteItem.getNoteTitle()}.md`
|
||||
).open();
|
||||
).open()) as string;
|
||||
if (!raw) return;
|
||||
filename = formatPath(raw, ".md");
|
||||
}
|
||||
|
|
@ -171,24 +171,24 @@ async function toSync(
|
|||
}
|
||||
|
||||
async function toDocx(noteItem: Zotero.Item) {
|
||||
const raw = await new ztoolkit.FilePicker(
|
||||
const raw = (await new ztoolkit.FilePicker(
|
||||
`${Zotero.getString("fileInterface.export")} MS Word Docx`,
|
||||
"save",
|
||||
[["MS Word Docx File(*.docx)", "*.docx"]],
|
||||
`${noteItem.getNoteTitle()}.docx`
|
||||
).open();
|
||||
).open()) as string;
|
||||
if (!raw) return;
|
||||
const filename = formatPath(raw, ".docx");
|
||||
await addon.api.$export.saveDocx(filename, noteItem.id);
|
||||
}
|
||||
|
||||
async function toFreeMind(noteItem: Zotero.Item) {
|
||||
const raw = await new ztoolkit.FilePicker(
|
||||
const raw = (await new ztoolkit.FilePicker(
|
||||
`${Zotero.getString("fileInterface.export")} FreeMind XML`,
|
||||
"save",
|
||||
[["FreeMind XML File(*.mm)", "*.mm"]],
|
||||
`${noteItem.getNoteTitle()}.mm`
|
||||
).open();
|
||||
).open()) as string;
|
||||
if (!raw) return;
|
||||
const filename = formatPath(raw, ".mm");
|
||||
await addon.api.$export.saveFreeMind(filename, noteItem.id);
|
||||
|
|
|
|||
|
|
@ -108,8 +108,7 @@ export function registerMenus() {
|
|||
},
|
||||
});
|
||||
|
||||
// menuTools
|
||||
// menuEdit
|
||||
// menuFile
|
||||
const menuFileAnchor = document.querySelector(
|
||||
"#menu_newCollection"
|
||||
) as XUL.MenuItem;
|
||||
|
|
@ -227,9 +226,21 @@ export function registerMenus() {
|
|||
"menuFile",
|
||||
{
|
||||
tag: "menuitem",
|
||||
label: getString("menuAddNote.newMainNote"),
|
||||
label: getString("menuAddNote-importMD"),
|
||||
icon: `chrome://${config.addonRef}/content/icons/favicon.png`,
|
||||
commandListener: addon.hooks.onCreateWorkspaceNote,
|
||||
commandListener: () => addon.hooks.onCreateNoteFromMD(),
|
||||
},
|
||||
"after",
|
||||
menuFileAnchor
|
||||
);
|
||||
ztoolkit.Menu.register(
|
||||
"menuFile",
|
||||
{
|
||||
tag: "menuitem",
|
||||
label: getString("menuAddNote.newTemplateItemNote"),
|
||||
icon: `chrome://${config.addonRef}/content/icons/favicon.png`,
|
||||
commandListener: () =>
|
||||
addon.hooks.onCreateNoteFromTemplate("item", "library"),
|
||||
},
|
||||
"after",
|
||||
menuFileAnchor
|
||||
|
|
@ -249,10 +260,9 @@ export function registerMenus() {
|
|||
"menuFile",
|
||||
{
|
||||
tag: "menuitem",
|
||||
label: getString("menuAddNote.newTemplateItemNote"),
|
||||
label: getString("menuAddNote.newMainNote"),
|
||||
icon: `chrome://${config.addonRef}/content/icons/favicon.png`,
|
||||
commandListener: () =>
|
||||
addon.hooks.onCreateNoteFromTemplate("item", "library"),
|
||||
commandListener: addon.hooks.onCreateWorkspaceNote,
|
||||
},
|
||||
"after",
|
||||
menuFileAnchor
|
||||
|
|
@ -281,6 +291,12 @@ export function registerMenus() {
|
|||
commandListener: () =>
|
||||
addon.hooks.onCreateNoteFromTemplate("item", "library"),
|
||||
});
|
||||
ztoolkit.Menu.register(newNoteMenu, {
|
||||
tag: "menuitem",
|
||||
label: getString("menuAddNote-importMD"),
|
||||
icon: `chrome://${config.addonRef}/content/icons/favicon.png`,
|
||||
commandListener: () => addon.hooks.onCreateNoteFromMD(),
|
||||
});
|
||||
|
||||
// create note menu in reader side panel
|
||||
ztoolkit.Menu.register(
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ function updateSyncStatus(noteId: number, status: SyncStatus) {
|
|||
addSyncNote(noteId);
|
||||
setPref(`syncDetail-${noteId}`, JSON.stringify(status));
|
||||
}
|
||||
|
||||
function getNoteStatus(noteId: number) {
|
||||
const noteItem = Zotero.Items.get(noteId);
|
||||
if (!noteItem?.isNote()) {
|
||||
|
|
@ -183,6 +184,16 @@ async function getMDStatus(
|
|||
}
|
||||
|
||||
async function getMDFileName(noteId: number, searchDir?: string) {
|
||||
const syncStatus = getSyncStatus(noteId);
|
||||
// If the note is already synced, use the filename in sync status
|
||||
if (
|
||||
(!searchDir || searchDir === syncStatus.path) &&
|
||||
syncStatus.filename &&
|
||||
OS.File.exists(`${syncStatus.path}/${syncStatus.filename}`)
|
||||
) {
|
||||
return syncStatus.filename;
|
||||
}
|
||||
// If the note is not synced or the synced file does not exists, search for the latest file with the same key
|
||||
const noteItem = Zotero.Items.get(noteId);
|
||||
if (searchDir !== undefined && (await OS.File.exists(searchDir))) {
|
||||
const mdRegex = /\.(md|MD|Md|mD)$/;
|
||||
|
|
@ -209,6 +220,7 @@ async function getMDFileName(noteId: number, searchDir?: string) {
|
|||
return matchedFileName;
|
||||
}
|
||||
}
|
||||
// If no file found, use the template to generate a new filename
|
||||
return await addon.api.template.runTemplate(
|
||||
"[ExportMDFileNameV2]",
|
||||
"noteItem",
|
||||
|
|
|
|||
Loading…
Reference in New Issue