【Quickadd脚本】修复Canvas中的失效文档或文件

针对 Canvas 中大量失效的笔记或文件进行修复的脚本,借用 Quickadd 的 Capture 进行运行。

IMG-20240106225212102

背景

我一般采用 Obsidian 的尽可能简短形式的 Wiki 的链接形式,这样 Obsidian 里面的笔记链接不容易失效:

Canvas 中笔记失效的原因:因为我对 Obsidian 的文件夹列表操作实在不感冒,所以经常会在系统的资源管理器中对 文件夹笔记 进行一定修改移动 (PS:千万不要在ob外部更改 md 的名称,不然你会后悔的),虽然 简短的 Wiki 链接 会保持 md 笔记间的联系不会失效,但是 Canvas 则会直接失效,因为 Canvas 里面采用的是基于 Obsidian 库的相对路径,而不支持 Wiki 链接。

所以有一次我从资源管理器进行一番操作后,发现 Canvas 中大量的笔记失效,也没有备份记录,能修复的方法只有手动操作,但一个 Canvas 中有几十甚至上百个小卡片笔记,为了节省时间,写了这个修复 Canvas 失效的笔记或者文件的脚本。

:red_circle:脚本运行的注意事项

  1. Canvas 中的笔记不要有相同文件名的其他笔记存在,如果有则该脚本会跳过修复。
  2. 脚本只是从文件列表性质上的检索,所以会对 Canvas 中的所有笔记进行检测,如果你发现脚本运行后出现特别多的改变,请通过 Ctrl + Z 退回。

Quickadd 的脚本配置

添加 Quickadd 的 Capture 选项

Capture::recycle:FixCanvas 的配置

Capture::recycle:FixCanvas 的脚本

```js quickadd
const path = require('path');
const fs = require('fs');

// 获取笔记的基本路径
const file = app.workspace.getActiveFile();
const fileFullPath = app.vault.adapter.getFullPath(file.path);
const isFixCanvasFileLink = confirm(`是否强制修复\n${fileFullPath}\n的内部文件链接`);
if (isFixCanvasFileLink && file.extension == 'canvas') {
    new Notice('🔴修复 Canvas 中失效的文件');

    // 获取库所有文件列表
    const files = app.vault.getFiles();
    // wikiPath = getFilePath(files, selectionEmbed); // 匹配Wiki链接
    // console.log(wikiPath);

    // 读取JSON格式的canvas文件并修改nodes中的object.file后再写回原文件
    fs.readFile(fileFullPath, 'utf8', (err, data) => {
        if (err) throw err;
        const canvasData = JSON.parse(data);

        // 处理nodes中的object.file,例如将其替换为其他文件
        canvasData.nodes.forEach(node => {
            // 进行处理,例如替换为其他文件
            const baseName = path.basename(String(node.file));
            const filePath = getFilePath(files, baseName);

            if ((filePath.length > 1 || !filePath) && (baseName.length > 1)) {
                new Notice(`🟡文件:${baseName},有${filePath.length}个重复文件,因此跳过修复`, 5000);

            } else if (baseName.length > 1) {
                node.file = String(filePath);
            }

        });
        // 将修改后的canvasData写回原文件
        fs.writeFile(fileFullPath, JSON.stringify(canvasData, null, 2), 'utf8', (err) => {
            if (err) throw err;
            new Notice('🟢Canvas失效文档已更新');
        });
    });

}

function getFilePath(files, baseName) {
    let files2 = files.filter(f => path.basename(f.path) === baseName);
    let filePath = files2.map((f) => f.path);
    console.log(filePath);
    return filePath;
}
```

希望这个脚本能够帮助有缘人 :smirk: