原先 Obsidian-Bridge 搭配 Marginnote-Companion(Obsidian 插件)有两大痛点
- 随着版本更新,自动插入模式不再有效
- Marginnote-Companion 不能读取指向学习集的笔记链接(目前是指向文档),所以传送非常不便
不过我发现Obsidian-Bridge 开启后,在 MN中点击笔记后会获得包含笔记的所有字符串,因此在此基础上,在 AI 的协助下写了一个 Templater 脚本
,Marginnote-Companion 可以关掉了
- 在 Obsidian 中 安装 Templater 插件
- 新建一个模板文件
- 复制代码
<%*
// --- 配置区域 ---
const POLL_INTERVAL = 1000; // 检查频率:1000毫秒 = 1秒
const MN_SIGNATURE = "noteId"; // 简单的特征识别,防止误粘贴其他东西
// 定义全局变量来控制开关 (依附在 window 对象上)
if (!window.mn_auto_listener) {
window.mn_auto_listener = {
running: false,
intervalId: null,
lastClip: ""
};
}
const listener = window.mn_auto_listener;
// --- 开关逻辑 ---
if (listener.running) {
// 如果正在运行,则关闭
clearInterval(listener.intervalId);
listener.running = false;
listener.intervalId = null;
new Notice("🛑 MN 自动监听已停止");
} else {
// 如果没运行,则启动
listener.running = true;
listener.lastClip = await tp.system.clipboard(); // 记住当前的,防止一开始就重复粘贴
new Notice("🟢 MN 自动监听已启动!请去 MN 尽情复制吧");
// 启动定时循环
listener.intervalId = window.setInterval(async () => {
try {
// 1. 获取当前剪贴板
// 注意:这里我们直接用 electron 的 api 获取,这比 tp.system 快一点且不卡顿
const electron = require("electron");
const clip = electron.clipboard.readText();
// 2. 只有当剪贴板变化了,且包含 MN 特征时才处理
if (clip !== listener.lastClip && clip.includes(MN_SIGNATURE) && clip.includes("{")) {
// 更新最后状态
listener.lastClip = clip;
// --- 3. 调用 V5.1 核心处理逻辑 (直接内嵌) ---
let output = "";
try {
const start = clip.indexOf('{');
const end = clip.lastIndexOf('}');
if (start !== -1 && end !== -1) {
let jsonStr = clip.substring(start, end + 1);
jsonStr = jsonStr.replace(/[\u0000-\u0009\u000B-\u001F\u007F]/g, "");
const data = JSON.parse(jsonStr);
let noteData = data.data || data.last?.data;
if (!noteData && data.rows) noteData = data.rows[0];
if (noteData) {
// 提取字段
let noteId = noteData.noteId;
let docMd5 = noteData.docMd5;
let title = (noteData.noteTitle || "").trim();
let excerpt = (noteData.highlight_text || noteData.excerptText || "").trim();
let notesText = (noteData.notesText || "").trim();
// 内容构建
let textParts = [];
if (title) textParts.push(title);
if (notesText && excerpt && notesText.includes(excerpt)) {
textParts.push(notesText);
} else {
if (excerpt) textParts.push(excerpt);
if (notesText) textParts.push(notesText);
}
textParts = [...new Set(textParts)];
// 链接构建
let link = "";
if (noteId) {
let topicId = "";
if (data.bookMap && docMd5 && data.bookMap[docMd5]) {
topicId = data.bookMap[docMd5].currentTopicId;
}
link = `marginnote4app://note/${noteId}`;
if (topicId) link += `/${topicId}`;
}
// 链接前置
if (link && textParts.length > 0) {
textParts[0] = `${textParts[0]} [MN](${link})`;
}
// 最终组合
output = textParts.join("\n\n");
if (textParts.length === 0 && link) output = `[MN](${link})`;
}
}
} catch (err) {
console.log("MN 解析忽略非标准数据");
}
// --- 4. 写入当前文件 ---
if (output) {
// 获取当前活跃的编辑器
const view = app.workspace.activeLeaf.view;
if (view.editor) {
const editor = view.editor;
// 在光标处或者文件末尾插入
// 这里我们选择:插入到当前光标位置,并换行
const cursor = editor.getCursor();
// 插入内容 + 两个换行
editor.replaceRange(output + "\n\n", cursor);
// 移动光标到最后,方便下一条
const newCursor = {
line: cursor.line + output.split("\n").length + 2,
ch: 0
};
editor.setCursor(newCursor);
new Notice("✅ 已捕获一条笔记");
}
}
}
} catch (e) {
console.error(e);
// 出错不停止,继续监听
}
}, POLL_INTERVAL);
}
%>
- 调用这个模板:会看到右上角弹出绿色提示:“
MN 自动监听已启动!” - 随后在MarginNote 里阅读,点击卡片,Obsidian 会在后台默默地把你复制的内容处理好,追加到那个文件的末尾。
- 阅读完成后再次调用模板,你会看到红色提示:“
MN 自动监听已停止”
还有很多优化的空间