#obsidian
之前看到有人在问怎么在手机上实现obsidian的待办提醒,有一个正在开发的项目值得关注,原理是单独开发一个配套的app,定期扫描手机本地的ob库中的文件,然后用这个app走安卓的通知
Obsidian 实现复制时自动上传图片到图床
Obsidian 实现复制时自动上传图片到图床
【QuickAdd脚本】带图复制-自动上传图片到图床 – 经验分享 – Obsidian 中文论坛
我新开一个库可以用,但是在主力库里就不行,报错为
QuickAdd: (ERROR) failed to run user script 带
图复制.Error:
The “path" argument must be of type string.
Received undlefined
这个问题很奇怪,我在新开的空白ob库里没有遇见,但是在主力库就有这个问题。
怎么排查问题?
- 尝试删除js脚本后再执行命令,看看是不是脚本的问题——删除后报错找不到脚本,看来不是这个问题。
然后我想为什么空白库是对的,多半是插件或者设置的问题,然后我把脚本发给kimi,kimi分析到一个关键点,就是文件路径。
于是我发现问题了:试用的时候发现一个问题:
如果内部链接类型
设置为基于当前笔记的相对路径
,脚本会报错
QuickAdd: (ERROR) failed to run user script 带图 复制.Error: The “path" argument must be of type string. Received undefined
采用绝对路径也会有同样问题。改为尽量短路径就正常了。
用chatgpt修复这个bug(还得是chatgpt哇),修复版的脚本为:
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("Selected text:", selection);
for (let line of selection.split("n")) {
let embed = "";
if (line) {
embed = matchSelectionEmbed(line);
}
console.log("Matched embed:", embed);
if (embed && /.(png|jpg|jpeg|gif|bmp)$/.test(embed)) {
let wikiPath = getFilePath(files, embed); // 匹配Wiki链接
if (!wikiPath) {
new Notice(`❌无法找到文件: ${embed}`);
console.log(`❌无法找到文件: ${embed}`);
continue;
}
// 获取绝对路径
const imgPath = app.vault.adapter.getFullPath(wikiPath);
console.log("Image path:", 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(`❌上传 ${path.basename(imgPath)} 图片失败`);
console.log(`❌上传 ${path.basename(imgPath)} 图片失败`);
}
}
content += line + "n";
}
console.log("Final content:", content);
copyToClipboard(content)
new Notice(`✅复制成功`);
};
// 获取文件路径函数
function getFilePath(files, baseName) {
let matchingFiles = files.filter(f => {
const fullPath = f.path;
console.log(`Comparing ${fullPath} with ${baseName}`);
return fullPath.endsWith(baseName);
});
if (matchingFiles.length === 0) {
console.log(`No files matched for: ${baseName}`);
return undefined;
}
return matchingFiles[0].path;
}
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 }),
});
const data = response.json; // 直接访问 `json` 属性,而不是调用 `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);
}
使用方法
- 安装插件quickadd
- 在quickadd中设置脚本存放目录
Template Folder Path
,然后在对应目录下新建带图复制.js
,把代码粘贴进去 - 新建一个宏,选择刚刚新建的脚本
- 安装piclist,配置好图床
- 在obsidian中选中要分享的文本,其中需要包含要上传的图片,然后ctrl+p使用脚本
- 粘贴即可
直接把图片上传到github
用 github publisher 插件能把图片上传到 github,但是图片在文章中的格式是 [[]]
的 wiki 链接,因此我们需要通过正则的方式来转换格式。
参考这篇文章 obsidian图片链接转换成markdown语法,不关闭wiki链接_obsidian图片显示变成链接-CSDN博客
同时上面这个方法还可以解决这个问题:obsidian 粘贴进来的图片名字会自动带空格,如 Pasted image 20240806221817.png
最后发布后就能看到在 github 是可以正常查看图片了,但是为了同步到其他平台,可以批量的在图片路径前面加上 https://github.com/dangehub/github2wp/blob/main/_posts
方法也很简单,就是搜索 assets/
,然后替换为 https://github.com/dangehub/github2wp/blob/main/_posts/assets/
- 但是为什么同步到 wordpress 的文章里图片没有了?
同步到 wp 的是 html 代码:
<p><img alt="" src="https://github.com/dangehub/github2wp/blob/main/_posts/assets/Pasted%20image%2020240806214536.png" /></p>
直接访问这个链接是对的,但是这段 html 代码不能正常工作。
比如放到 obsidian 中:
上面的分隔线中就是这段 html 代码,无法显示图像。为什么?
去调试台看了下,报错 (失败)net::ERR_BLOCKED_BY_ORB
,这是跨域问题
但是都没人说 github 的图片会限制跨域,检查之后发现 https://github.com/dangehub/github2wp/blob/b85405e3ef0c15a3caf57a038a545e0842d43996/_posts/assets/Pasted%20image%2020240806214536.png
指向的不是图片本身,https://github.com/dangehub/github2wp/blob/b85405e3ef0c15a3caf57a038a545e0842d43996/_posts/assets/Pasted%20image%2020240806214536.png?raw=true
才是图片本身,替换为这个链接就好了。
即用 png?raw=true
替换 png
突然发现微软e5开发者账号从5T变成1T了…
突然发现微软e5开发者账号从5T变成1T了…
obsidian技巧之用maoxian插件剪藏网络文章,同时把图片下载到本地
前言
今天在学习隐写术的时候看到一篇挺有价值的文章,本来想用ob官方的剪藏工具保存下来,但是发现官方工具到现在还不能把网络图片下载下来,这对于剪藏防丢失这个目的来说,这种级别就是不可用的,于是还是换工具了,调研了一下,发现maoxian可能是最适合我的。
maoxian的优势:
- 在浏览器环境下下载图片,可以使用浏览器的代理、cookie等环境信息,做到所见即可得
- 开源
- 文件保存的名称、内容格式、路径高度可自定义
maoxian web clipper配置过程记录
Obsidian库: C:Users62300Documentslivesync
网摘入口:C:Users62300Documentslivesync201-文章摘录
浏览器默认下载地址:C:Users62300Downloads
maoxian根目录:maoxian摘录
你需要根据电脑的用户名、obsidian库名称、剪藏存放的文件夹来替换部分内容。
创建软链接(路径有中文就必须要有引号)
mklink /D "C:Users62300Downloadsmaoxian摘录" "C:Users62300Documentslivesync201-文章摘录"
调整maoxian的设置,由于内容过多,我直接把我的配置文件贴在文章末尾,详见obsidian技巧之用maoxian插件剪藏网络文章,同时把图片下载到本地#我的maoxian配置文件
我的maoxian配置文件
使用方法:保存为json文件后到maoxian的备份中导入
[fold]
{
"data": {
"assistant.default-tag-status": "",
"assistant.public-plan.default.20240502": [
{
"actions": [
{
"hide": [
"div#toc",
"table.infobox",
"span.mw-editsection",
"table.navbox",
"div.thumb",
"div.dablink",
"table.metadata"
]
},
{
"pick": "div.mw-parser-output"
}
],
"excludePattern": "https://*.m.wikipedia.org/*/",
"name": "wikipedia.org",
"pattern": "https://*.wikipedia.org/wiki/*",
"tags": [
"knowledge",
"wiki"
],
"version": 20240502
},
{
"actions": [
{
"hide": [
".page-actions-menu",
"#toc",
".mw-editsection",
"h2 > div.mw-ui-icon",
"table.box-Unreferenced",
"table.box-More_citations_needed"
]
},
{
"chAttr": {
"attr": "style",
"pick": "h2.section-heading",
"sep": ";",
"type": "split2list.add",
"value": "width: 100%"
}
}
],
"contributors": [
"Altair Wei (author)"
],
"name": "Wikipedia Mobile View",
"pattern": "https://*.m.wikipedia.org/*/",
"tags": [
"knowledge",
"wiki"
],
"version": 20240502
},
{
"actions": [
{
"hide": [
".avatar",
".avatar-parent-child",
".inline-comment-form-actions",
".flex-items-center.d-sm-flex.d-none",
".d-inline-block"
]
},
{
"pick": [
".js-discussion",
".markdown-body"
]
}
],
"contributors": [
"yzqzss (author)"
],
"name": "Github",
"pattern": "https://github.com/",
"tags": [
"IT",
"geek",
"git"
],
"version": 20240502
},
{
"actions": [
{
"pick": "#bodyContent"
}
],
"contributors": [
"Mika"
],
"name": "ArchWiki",
"pattern": "https://wiki.archlinux.org/title/*",
"tags": [
"IT",
"wiki",
"doc"
],
"version": 20240502
}
],
"assistant.public-plan.default.latest": "assistant.public-plan.default.20240502",
"assistant.public-plan.default.text": "[n {n "name": "wikipedia.org",n "pattern": "https://*.wikipedia.org/wiki/*",n "excludePattern": "https://*.m.wikipedia.org/*/",n "version": 20240502,n "actions": [n {n "hide": [n "div#toc",n "table.infobox",n "span.mw-editsection",n "table.navbox",n "div.thumb",n "div.dablink",n "table.metadata"n ]n },n {n "pick": "div.mw-parser-output"n }n ],n "tags": [n "knowledge",n "wiki"n ]n },n {n "name": "Wikipedia Mobile View",n "pattern": "https://*.m.wikipedia.org/*/",n "version": 20240502,n "actions": [n {n "hide": [n ".page-actions-menu",n "#toc",n ".mw-editsection",n "h2 > div.mw-ui-icon",n "table.box-Unreferenced",n "table.box-More_citations_needed"n ]n },n {n "chAttr": {n "type": "split2list.add",n "pick": "h2.section-heading",n "attr": "style",n "value": "width: 100%",n "sep": ";"n }n }n ],n "tags": [n "knowledge",n "wiki"n ],n "contributors": [n "Altair Wei (author)"n ]n },n {n "name": "Github",n "pattern": "https://github.com/",n "version": 20240502,n "actions": [n {n "hide": [n ".avatar",n ".avatar-parent-child",n ".inline-comment-form-actions",n ".flex-items-center.d-sm-flex.d-none",n ".d-inline-block"n ]n },n {n "pick": [n ".js-discussion",n ".markdown-body"n ]n }n ],n "tags": [n "IT",n "geek",n "git"n ],n "contributors": [n "yzqzss (author)"n ]n },n {n "name": "ArchWiki",n "pattern": "https://wiki.archlinux.org/title/*",n "version": 20240502,n "actions": [n {n "pick": "#bodyContent"n }n ],n "tags": [n "IT",n "wiki",n "doc"n ],n "contributors": [n "Mika"n ]n }n]",
"assistant.public-plan.pointers": [
"assistant.public-plan.default.20240502"
],
"assistant.public-plan.subscription-urls": [
"https://mika-cn.github.io/maoxian-web-clipper/assistant/plans/default/index.json"
],
"assistant.public-plan.subscriptions": [
{
"description": "Default channel hosts plans that relative to international websites",
"latestVersion": 20240502,
"name": "default",
"size": 4,
"updateUrl": "https://mika-cn.github.io/maoxian-web-clipper/assistant/plans/default/20240502.json",
"url": "https://mika-cn.github.io/maoxian-web-clipper/assistant/plans/default/index.json"
}
],
"config": {
"allowFileSchemeAccess": true,
"assetFileName": "$TIME-INTSEC-$MD5URL$EXT",
"assetFolder": "$ROOT-FOLDER/assets",
"assistantEnabled": false,
"autoInputLastCategory": true,
"autoInputLastTags": true,
"autoRefreshHistory": false,
"autoRunContentScripts": false,
"autoUpdatePublicPlan": false,
"autogenerateClippingJs": false,
"backupAssistantData": true,
"backupHistoryPageConfig": true,
"backupSelectionData": true,
"backupSettingPageConfig": true,
"clippingFolderName": "$YYYY-$MM-$DD-$TIME-INTSEC",
"clippingHandler": "Browser",
"clippingJsPath": "$STORAGE-PATH/history/clippings.js",
"communicateWithThirdParty": false,
"defaultCategory": "default",
"frameFileFolder": "$ROOT-FOLDER/frames",
"frameFileName": "$TIME-INTSEC-$MD5URL.frame.html",
"handlerBrowserEnabled": true,
"handlerNativeAppEnabled": false,
"handlerWizNotePlusEnabled": false,
"htmlCaptureApplet": "remove",
"htmlCaptureAudio": "remove",
"htmlCaptureCssImage": "remove",
"htmlCaptureCssRules": "saveUsed",
"htmlCaptureEmbed": "saveImage",
"htmlCaptureIcon": "remove",
"htmlCaptureImage": "saveAll",
"htmlCaptureObject": "saveImage",
"htmlCaptureVideo": "remove",
"htmlCaptureWebFont": "remove",
"htmlCompressCss": false,
"htmlCustomBodyBgCssEnabled": false,
"htmlCustomBodyBgCssValue": "#000000",
"htmlEmbedFilter": "<images>",
"htmlObjectFilter": "<images>",
"htmlSaveClippingInformation": false,
"htmlWebFontFilterList": "woff2|woff|otf|ttf",
"infoFileFolder": "$CLIPPING-PATH",
"infoFileName": "index.json",
"mainFileFolder": "$ROOT-FOLDER",
"mainFileName": "$TITLE.$FORMAT",
"markdownOptionBulletListMarker": "-",
"markdownOptionCodeBlockStyle": "fenced",
"markdownOptionEmDelimiter": "*",
"markdownOptionFence": "```",
"markdownOptionFormulaBlockWrapper": "padSameLine",
"markdownOptionHeadingStyle": "atx",
"markdownOptionHr": "- - -",
"markdownOptionLinkReferenceStyle": "full",
"markdownOptionLinkStyle": "inlined",
"markdownOptionPreformattedCode": false,
"markdownOptionStrongDelimiter": "**",
"markdownTemplate": "n{{content}}n",
"mouseModeEnabled": true,
"offlinePageHandler": "Browser",
"refreshHistoryHandler": "NativeApp",
"rememberSelection": false,
"requestCache": "default",
"requestCacheCss": true,
"requestCacheImage": true,
"requestCacheWebFont": false,
"requestCredentials": "same-origin",
"requestMaxTries": 3,
"requestReferrerPolicy": "strict-origin-when-cross-origin",
"requestTimeout": 300,
"rootFolder": "maoxian摘录",
"saveDomainAsTag": false,
"saveFormat": "md",
"saveInfoFile": false,
"saveTitleFile": false,
"selectSaveFormatOnMenus": false,
"shortcutSlot0": "_openLastClipping",
"shortcutSlot1": "_clipAsDefault",
"shortcutSlot2": "_clipAsHTML",
"shortcutSlot3": "_clipAsMarkdown",
"shortcutSlot4": "_doNothing",
"shortcutSlot5": "_doNothing",
"shortcutSlot6": "_doNothing",
"shortcutSlot7": "_doNothing",
"shortcutSlot8": "_doNothing",
"shortcutSlot9": "_doNothing",
"titleFileFolder": "$CLIPPING-PATH",
"titleFileName": "a-title_$TITLE",
"userCommandsText": "{n "doNothing": {"exec": "doNothing"}n}",
"version": "2.16"
},
"history.page.cache.enableAdvancedSearchMode": false,
"history.page.cache.enableConfirmMode": true,
"history.page.cache.localstorage.migrated": true,
"history.page.cache.search.keyword": ""
},
"backupAt": "2024-12-17 16:25:24"
}
为什么我说话这么喜欢叠甲呢?因为如果我叠完甲还能遇见傻逼,那我就知道他是真的傻逼了。
为什么我说话这么喜欢叠甲呢?因为如果我叠完甲还能遇见傻逼,那我就知道他是真的傻逼了。
我维护了一个obsidian示例库,分享了我的obsidian工作流
我使用obsidian也有很长时间了,有时候也有朋友会问我,你是如何使用obsidian的,于是我制作了这个示例库,里面有我的一些常用插件与脚本,如果你还没有总结出独属于你的obsidian工作流,或许它会有一点价值。
使用方法也很简单:
- 打开网址:dangehub/aqu_ob_share: Share my Obsidian techniques
- 按图下载示例库
- 解压此压缩包后,在obsidian中打开它
- 具体细节请见库中
README.md
,也就是用obsidian打开它之后根目录的那篇笔记。
又点了一份烤鱼,但是吃在嘴里却没有想要的味道。可能是喜欢的不是烤鱼,是记忆中的那天。
又点了一份烤鱼,但是吃在嘴里却没有想要的味道。可能是喜欢的不是烤鱼,是记忆中的那天。
#梗 一部手机的寿命是3~5年,而人的寿命在70~100,手机只是人类眼中的过客,但对于手机来说,你就是它的一生,所以,放下身边的杂活,多陪陪你的手机
#梗 一部手机的寿命是3~5年,而人的寿命在70~100,手机只是人类眼中的过客,但对于手机来说,你就是它的一生,所以,放下身边的杂活,多陪陪你的手机
回复