add: import note from md

This commit is contained in:
windingwind 2023-07-25 16:44:52 +08:00
parent 5a9678b7eb
commit a3524fd5e2
9 changed files with 94 additions and 18 deletions

View File

@ -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?

View File

@ -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?

View File

@ -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 文件同步?

View File

@ -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",

View File

@ -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,
};

View File

@ -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),
});
}
}
}

View File

@ -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);

View File

@ -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(

View File

@ -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",