obsidian插件开发从入门到应用(批量或单独删除笔记中图片)

本文最后更新于 2024年5月16日。

最近整理笔记的时候想删除笔记中的图片,但是一个一个删除链接太费时间了,搜索一下写没有相关插件。本来想着写个python脚本批量删除,后来一想,用python还得来回复制文本并且不能实时预览效果,如果有插件就好了,既然没有现成的,为什么不自己写一个试试呢,马上下手,于是有了这篇文章。
这篇文章包括五个部分:

obsidian安装插件教程:这部分是基础,需要提前了解

开发obsidian插件入门:这部分是入门,大概了解obsidian插件的开发流程

开发obsidian插件——删除当前笔记中的图片:正式实现需要的功能

开发obsidian插件——删除所有笔记中的图片:增加批量功能,提升效率

获取插件:不想自己开发的人可以直接获取使用

由于第一次写插件,还有很多不完善的地方,比如说,虽然有设置功能,实际是没用的,另外用圆圈这个图标也不太好,所以只是勉强可以使用,作为入门参考。

obsidian安装插件教程

安装核心插件

  • 安装Obsidian核心插件的方法比较简单,直接在设置窗口中启用即可。
  • 打开Obsidian,从工具栏,单击设置按钮,打开Obsidian的设置对话框。
  • 在设置对话框打开选项>核心插件页签。
  • 浏览插件,根据实际需要选择插件使用,将开关键设置为开启状态。
  • 部分插件带有选项按钮,可做进一步设置。

安装第三方插件

手动安装

  • 下载插件源码,复制到obsidian插件文件夹下:
 <你的obsidian文件夹></obsidian/plugin>/plugin/<你的插件文件夹>
  • 要在Obsidian中加载插件,首先需要启用它。
  • 在Obsidian中,打开“设置”。
  • 在侧菜单中,选择“社区插件”。
  • 选择“打开社区插件”。
  • 在Installed plugins下,通过选择其旁边的切换按钮来启用插件。

自动安装

需要启用代理 关闭安全模式,设置-社区插件-浏览-搜索插件名称-点击安装即可。

开发obsidian插件入门

准备

开发obsidian插件需要安装开发环境和开发工具:
nodejs环境
开发工具,我选用vscode作为开发工具

创建

进入一个想要开发插件的文件夹,随意新建一个即可,例如我新建一个obsidian-plugin-dev文件夹。

运行如下命令:

npx create-obsidian-plugin

在命令行的提示下输入插件id(我用的是delete-image-links),插件名称,作者,作者网站,是否存在样式表,插件描述,授权协议就可以创建一个样板插件了。

运行进入插件目录:

cd delete-image-links

打包

运行下面命令打包:

npm run build

安装插件

打包完成后,把dist文件夹下的文件复制到obsidian插件文件夹即可。

<你的obsidian文件夹></obsidian/plugin>/plugin/<你的插件文件夹>

然后在设置中安装这个插件即可使用。
安装详细教程: obsidian安装插件教程(全面)

创建过程

我的命令行记录如下:

(base) PS E:\obsidian-plugin-dev> npx create-obsidian-plugin
√ Enter the plugin id (lowercase, no spaces) ... delete-image-links
√ Enter the plugin name ... Delete Image Links
√ Write a short description of what the plugin does ... delete images in notes
√ Enter your name or username you'd like the plugin to show as the author ... weiyoun
√ Add your website or social media account (optional) ... weiyoun.com
√ Does your plugin include styles? ... no
√ Choose a license (type to filter, ↑ or ↓ to navigate) » MIT License
Creating a new obsidian plugin at ./delete-image-links
Installing plugin dependencies, this may take a little while.

added 194 packages in 3m

To get started developing on your plugin run

  cd delete-image-links
  npm run dev

Please check your LICENSE file to see if any updates are needed

(base) PS E:\obsidian-plugin-dev> cd delete-image-links
(base) PS E:\obsidian-plugin-dev\delete-image-links> npm run build

> delete-image-links@0.0.1 build
> obsidian-plugin build src/main.ts

(base) PS E:\obsidian-plugin-dev\delete-image-links> 

开发obsidian插件——删除当前笔记中的图片

之前介绍了obsidian插件开发入门
开发obsidian插件入门

以及怎么开发删除所有笔记的外部链接图片
开发obsidian插件——删除所有笔记中的图片
这次改成只删除当前笔记图片的插件。

源码

这次对代码进行修改,只删除当前笔记中的外部链接图片,修改项目中 /src/main.ts
的代码,主要增加一个遍历笔记并删除图片链接的函数并调用。
为了避免混淆,这里直接放出修改后的代码:

import {
  App,
  Modal,
  Notice,
  Plugin,
  PluginSettingTab,
  Setting,
} from "obsidian";
interface DeleteImageLinksSettings {
  mySetting: string;
}
const DEFAULT_SETTINGS: DeleteImageLinksSettings = {
  mySetting: "default",
};
export default class DeleteImageLinks extends Plugin {
  settings: DeleteImageLinksSettings;
  async onload() {
    console.log("loading plugin");
    await this.loadSettings();
    this.addRibbonIcon("circle", "delete images", () => {
      // new Notice("This is a notice!");
      this.deleteImageLinks();
    });
    this.addStatusBarItem().setText("Status Bar Text");
    this.addCommand({
      id: "open-sample-modal",
      name: "Open Sample Modal",
      // callback: () => {
      //    console.log('Simple Callback');
      // },
      checkCallback: (checking: boolean) => {
        let leaf = this.app.workspace.activeLeaf;
        if (leaf) {
          if (!checking) {
            new SampleModal(this.app).open();
          }
          return true;
        }
        return false;
      },
    });
    this.addSettingTab(new SampleSettingTab(this.app, this));
    this.registerCodeMirror((cm: CodeMirror.Editor) => {
      console.log("codemirror", cm);
    });
    this.registerDomEvent(document, "click", (evt: MouseEvent) => {
      console.log("click", evt);
    });
    this.registerInterval(
      window.setInterval(() => console.log("setInterval"), 5 * 60 * 1000)
    );
  }
  onunload() {
    console.log("unloading plugin");
  }
  async loadSettings() {
    this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
  }
  async saveSettings() {
    await this.saveData(this.settings);
  }

  async deleteImageLinks() {

      const note = this.app.workspace.getActiveFile();
      const content = this.app.vault.read(note);

      try {
        const resolvedString: string = await content; // 等待 Promise 解析为字符串
        const modifiedString: string = resolvedString.replace(/!\[[^\]]*\]\([^)]*\)/g, ''); // 使用 replace 方法对字符串进行修改
        console.log(modifiedString);
        this.app.vault.modify(note, modifiedString);
      } catch (error) {
        console.error(error);
      }

    // 提示删除成功
    new Notice('All image links have been deleted from your notes.');
  }

}

class SampleModal extends Modal {
  constructor(app: App) {
    super(app);
  }
  onOpen() {
    let { contentEl } = this;
    contentEl.setText("Woah!");
  }
  onClose() {
    let { contentEl } = this;
    contentEl.empty();
  }
}

class SampleSettingTab extends PluginSettingTab {
  plugin: DeleteImageLinks;
  constructor(app: App, plugin: DeleteImageLinks) {
    super(app, plugin);
    this.plugin = plugin;
  }
  display(): void {
    let { containerEl } = this;
    containerEl.empty();
    containerEl.createEl("h2", { text: "Settings for my awesome plugin." });
    new Setting(containerEl)
      .setName("Setting #1")
      .setDesc("It's a secret")
      .addText((text) =>
        text
          .setPlaceholder("Enter your secret")
          .setValue("")
          .onChange(async (value) => {
            console.log("Secret: " + value);
            this.plugin.settings.mySetting = value;
            await this.plugin.saveSettings();
          })
      );
  }
}

打包

运行npm run build打包。

开发obsidian插件——删除所有笔记中的图片

开发obsidian插件入门中介绍了怎么开始开发obsidian插件,并且获得了一个示例插件。目前示例插件只能在点击时出现一个提示语。
这次我们在示例插件基础上开发删除所有笔记中外部链接图片的插件。

源码

我们修改项目中/src/main.ts的代码,主要增加一个遍历笔记并删除图片链接的函数并调用。为了避免混淆,这里直接放出修改后的代码:

import {
  App,
  Modal,
  Notice,
  Plugin,
  PluginSettingTab,
  Setting,
} from "obsidian";
interface DeleteImageLinksSettings {
  mySetting: string;
}
const DEFAULT_SETTINGS: DeleteImageLinksSettings = {
  mySetting: "default",
};
export default class DeleteImageLinks extends Plugin {
  settings: DeleteImageLinksSettings;
  async onload() {
    console.log("loading plugin");
    await this.loadSettings();
    this.addRibbonIcon("circle", "delete images", () => {
      // new Notice("This is a notice!");
      this.deleteImageLinks();
    });
    this.addStatusBarItem().setText("Status Bar Text");
    this.addCommand({
      id: "open-sample-modal",
      name: "Open Sample Modal",
      // callback: () => {
      //    console.log('Simple Callback');
      // },
      checkCallback: (checking: boolean) => {
        let leaf = this.app.workspace.activeLeaf;
        if (leaf) {
          if (!checking) {
            new SampleModal(this.app).open();
          }
          return true;
        }
        return false;
      },
    });
    this.addSettingTab(new SampleSettingTab(this.app, this));
    this.registerCodeMirror((cm: CodeMirror.Editor) => {
      console.log("codemirror", cm);
    });
    this.registerDomEvent(document, "click", (evt: MouseEvent) => {
      console.log("click", evt);
    });
    this.registerInterval(
      window.setInterval(() => console.log("setInterval"), 5 * 60 * 1000)
    );
  }
  onunload() {
    console.log("unloading plugin");
  }
  async loadSettings() {
    this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
  }
  async saveSettings() {
    await this.saveData(this.settings);
  }

  async deleteImageLinks() {
    // 获取当前打开的所有笔记
    const notes = this.app.vault.getMarkdownFiles();

    // 遍历每个笔记
    for (const note of notes) {
      // 读取笔记的内容
      const content = this.app.vault.read(note);

      try {
        const resolvedString: string = await content; // 等待 Promise 解析为字符串
        const modifiedString: string = resolvedString.replace(/!\[[^\]]*\]\([^)]*\)/g, ''); // 使用 replace 方法对字符串进行修改
        console.log(modifiedString);
        this.app.vault.modify(note, modifiedString);
      } catch (error) {
        console.error(error);
      }

      // // 删除图片链接
      // const modifiedContent = content.replace(/!\[[^\]]*\]\([^)]*\)/g, '');

      // 将修改后的内容写回笔记
      // this.app.vault.modify(note, modifiedContent);

    }

    // 提示删除成功
    new Notice('All image links have been deleted from your notes.');
  }

}

class SampleModal extends Modal {
  constructor(app: App) {
    super(app);
  }
  onOpen() {
    let { contentEl } = this;
    contentEl.setText("Woah!");
  }
  onClose() {
    let { contentEl } = this;
    contentEl.empty();
  }
}

class SampleSettingTab extends PluginSettingTab {
  plugin: DeleteImageLinks;
  constructor(app: App, plugin: DeleteImageLinks) {
    super(app, plugin);
    this.plugin = plugin;
  }
  display(): void {
    let { containerEl } = this;
    containerEl.empty();
    containerEl.createEl("h2", { text: "Settings for my awesome plugin." });
    new Setting(containerEl)
      .setName("Setting #1")
      .setDesc("It's a secret")
      .addText((text) =>
        text
          .setPlaceholder("Enter your secret")
          .setValue("")
          .onChange(async (value) => {
            console.log("Secret: " + value);
            this.plugin.settings.mySetting = value;
            await this.plugin.saveSettings();
          })
      );
  }
}

打包

运行npm run build打包。

安装插件

打包完成后,把dist文件夹下的文件复制到obsidian插件文件夹即可。

 <你的obsidian文件夹></obsidian/plugin>/plugin/<你的插件文件夹>

然后再设置中安装这个插件即可使用。
安装详细教程: obsidian安装插件教程(全面)

安装完成后在obsidian面板区出现一个圆圈图标,点击之后会删除当前目录下所有笔记的外部链接图片,本地图片不受影响。要注意,该操作不可逆。如果只是测试,一定要提前备份。

获取插件

由于第一次写插件,还有很多不完善的地方,比如说,虽然有设置功能,实际是没用的,另外用圆圈这个图标也不太好,所以只是勉强可以使用,作为入门参考。

使用批量删除插件一定要谨慎,操作不可逆,如果没有想好要提前备份好自己的笔记。

github

obsidian-delete-image-links

https://github.com/WeiYoun/obsidian-delete-image-links

公众号

公众号:weiyounmimi
公众号weiyoun(id:weiyounmimi)后台回复“插件”即可获取。