需求分析
有时候我们想要分享自己的笔记到网络上。但 Obsidian 笔记本身存在 WIKI 链接语法以及图片保存在本地,不太方便转换。希望有一种方法可以将包含本地图片的 Markdown 文章一键转换为在知乎、CSDN 等网站上能够正确显示图片的形式,以便分享更加便捷,内容展示更完整。
实现方法
最好的办法就是将图片上传到图床,但又不想改变笔记原来的结构,只想把图片保留到本地,因此该脚本的作用就是自动检测复制文本中存在的本地图片链接,将图片上传到图床替换为在线 Markdown 图片格式。
- 检测本地图片链接
- 图片上传至图床
- PS: 上传的是PicGo的接口,图床设置请自行了解
- 替换 Markdown 文章中图片链接
- 发送到剪切板并提示
PS: 本方法灵感来源于 Ob 群友新奥尔良烤乳猪和简哲之间的讨论。
实现效果
QuickAdd Macro脚本源码
const path = require('path');
const quickAddApi = app.plugins.plugins.quickadd.api;
const { editor, file, containerEl } = app.workspace.activeEditor;
const url = "http://127.0.0.1:36677/upload";
module.exports = async () => {
const files = app.vault.getFiles();
let selection = "";
let content = "";
selection = editor.getSelection();
console.log(selection);
for (let line of selection.split("\n")) {
let embed = "";
if (line) {
embed = matchSelectionEmbed(line);
}
console.log(embed);
if (embed && /\.(png|jpg|jpeg|gif|bmp)$/.test(embed)) {
let wikiPath = getFilePath(files, embed); // 匹配Wiki链接
// 获取绝对路径
const imgPath = app.vault.adapter.getFullPath(wikiPath);
console.log(imgPath);
const data = await uploadFiles([imgPath], url);
if (data.success) {
const imgWiki = `[[${embed}]]`;
const imgLink = `[${embed}](${data.result})`;
line = line.replace(imgWiki, imgLink);
} else {
new Notice(`❌上传${imgPath.name}图片失败`);
}
}
content += line + "\n";
}
console.log(content);
copyToClipboard(content)
new Notice(`✅复制成功`);
};
// 获取文件路径函数
function getFilePath(files, baseName) {
let files2 = files.filter(f => path.basename(f.path).replace(".md", "") === baseName.replace(".md", ""));
let filePath = files2.map((f) => f.path);
return filePath[0];
}
function matchSelectionEmbed(text) {
const regex = /\[\[?([^\]]*?)(\|.*)?\]\]?\(?([^)\n]*)\)?/;
const matches = text.match(regex);
if (!matches) return;
if (matches[3]) return decodeURIComponent(matches[3]);
if (matches[1]) return decodeURIComponent(matches[1]);
}
async function uploadFiles(imagePathList, url) {
const response = await requestUrl({
url: url,
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ list: imagePathList }),
});
data = await response.json;
return data;
};
function copyToClipboard(extrTexts) {
const txtArea = document.createElement('textarea');
txtArea.value = extrTexts;
document.body.appendChild(txtArea);
txtArea.select();
if (document.execCommand('copy')) {
console.log('copy to clipboard.');
}else{
console.log('fail to copy.');
}
document.body.removeChild(txtArea);
}
不足之处:
- 相同文档多次复制会重复上传已有图片
- 如果一行多个图片正则匹配不到,还请手动上传