不信人间有白头

曲淡歌
曲淡歌@qudange

4 天前

#obsidian 

之前看到有人在问怎么在手机上实现obsidian的待办提醒,有一个正在开发的项目值得关注,原理是单独开发一个配套的app,定期扫描手机本地的ob库中的文件,然后用这个app走安卓的通知

4 天前 5
曲淡歌
曲淡歌@qudange

4 天前

Obsidian 实现复制时自动上传图片到图床 

Obsidian 实现复制时自动上传图片到图床

【QuickAdd脚本】带图复制-自动上传图片到图床 – 经验分享 – Obsidian 中文论坛

我新开一个库可以用,但是在主力库里就不行,报错为

assets/Pasted image 20240808164552.png

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

使用方法

  1. 安装插件quickadd
  2. 在quickadd中设置脚本存放目录 Template Folder Path,然后在对应目录下新建 带图复制.js,把代码粘贴进去
  3. 新建一个宏,选择刚刚新建的脚本
  4. 安装piclist,配置好图床
  5. 在obsidian中选中要分享的文本,其中需要包含要上传的图片,然后ctrl+p使用脚本
  6. 粘贴即可

直接把图片上传到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

跳转到我的数字花园

4 天前 4
曲淡歌
曲淡歌@qudange

5 天前

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"
}

跳转到我的数字花园

5 天前 4
曲淡歌
曲淡歌@qudange

6 天前

我维护了一个obsidian示例库,分享了我的obsidian工作流 

我使用obsidian也有很长时间了,有时候也有朋友会问我,你是如何使用obsidian的,于是我制作了这个示例库,里面有我的一些常用插件与脚本,如果你还没有总结出独属于你的obsidian工作流,或许它会有一点价值。

使用方法也很简单:

  1. 打开网址:dangehub/aqu_ob_share: Share my Obsidian techniques
  2. 按图下载示例库assets/Pasted image 20241216193415.png
  3. 解压此压缩包后,在obsidian中打开它
  4. 具体细节请见库中README.md,也就是用obsidian打开它之后根目录的那篇笔记。

跳转到我的数字花园

6 天前 4

Loading...
载入中

已到底部

没有可加载的页面

C
写微博
S
搜索
J
下一篇微博/评论
K
上一篇微博/评论
R
回复
E
编辑
O
显示隐藏评论
T
回顶部
L
登录
H
显示隐藏帮助
Ctrl+Enter
提交发布
ESC
取消并清除内容