Obsidian插件安装与开发
大概背景
事情的起因还是因为做笔记,我喜欢利用插件Obsidian Git自动同步笔记到Gitee
,写md
文档有个问题就是关于图片如何存储。
我个人习惯是将所有图片都保存到指定的文件夹下,如图👇
由于Obsidian
对粘贴图片默认格式为这样的:![[Pasted image 20240802143131.png]]
这是Obsidian
特有的,并不对md
文档通用,于是在码云上在线浏览,图片将无法展示。
于是就迫切的希望有一种插件,能够将粘贴得图片进行格式化,比如
这种markdown
通用语法。
实际上,还真有:Image Classify Paste
,然而此插件并没有完成全部的功能,于是有了下面的插件开发正文。
插件安装
Obsidian
的插件和其他应用程序略有差别,每一个Vault
仓库对应了自己的所属插件,比如我新建一个Vault
仓库,那么这个仓库默认是没有插件的。
关于vault
的概念,对应本地的一个文件夹,为obsidian
中的顶级目录。
可以看到目录中存在一个隐藏文件.obsidian/plugins
,实际上这就是插件目录,每个vault
仓库都有自己的插件。通过在Obsidian
应用程序中安装插件(设置 > 第三方插件 > 插件市场浏览安装
),其实就是下载插件文件夹到此目录下。
由于各种原因,国内有时候无法正常访问,应该说大部份时候都无法浏览插件和安装插件,需要git
加速,这里推荐使用dev-sidecar。
也可以通过插件obsidian-proxy-github实现,但是由于长时间无人维护,内置的一些加速网址其实已经不好用了,或者说完全用不了了,因此并不推荐。
安装方式
Obsidian
内直接安装
前提是你已经可以Git
加速正常访问插件市场。
直接下载文件安装
无论你从哪里找到的资源,通常来讲都是github
,你只需要下载下来解压缩,然后将此插件目录放到你的vault
仓库下的.obsidian/plugin
目录下即可。
Mac通过Command + Shift + .
在访达中查看隐藏文件
插件启动和设置
无论哪种方式安装的插件,最后都需要启用(默认是不启用的)。
左下角第三方插件可进行设置。
插件开发
插件本质是JavaScript
,所以进行Obsidian plugin
的开发其实就是js
语言的使用。
官方有很好的指导手册:Obsidian Docs
插件目录结构
正常插件目录结构如下:
main.js
核心部分,所有插件功能都在这里实现。
快速入门参考官方指导:# Obsidian Developer Docs
manifest.json
插件的描述信息,这些信息将在社区插件市场浏览展示用。
{ "id": "image-classify-paste", "name": "Image Classify Paste", "version": "0.1.4", "minAppVersion": "0.15.0", "description": "paste your image like typora, the image link name not `![[Paste xxx]]` but ``with a relative directory. 类比于typora的方式粘贴图片到本地,存放在以当前md文档命名的文件夹里。", "author": "tianfx", "authorUrl": "https://github.com/ostoe", "isDesktopOnly": true
}
社区插件市场
data.json
在设置插件功能后,会自动生成此文件,用于保存用户的设置,比如我的设置👇
生成的data.json
{ "defaultSetting": "default", "imageNamePattern": "{{fileName}}", "dupNumberAtStart": false, "dupNumberDelimiter": "-", "dupNumberAlways": false, "autoRename": false, "handleAllAttachments": false, "excludeExtensionPattern": "", "disableRenameNotice": false, "IsShowCustomPath": true, "PasteImageOption": "tocustom", "CustomPath": "static", "IsEscapeUriPath": true, "IsAddRelativePath": true, "IsApplyLocalImage": true, "IsApplyNetworklImage": true, "IsRelativePath": true
}
可以看到CustomPath
的目录为我指定的static
。
插件调试debug
Obsidian
提供了内置的调试工具,可以很好的支持插件开发调试,通过快捷键Windows
用户Win + Shift + I
或者Mac
用户Command + Shift + I
。但也可能是其他的,比如我的Command + Option + I
,无论哪种,最通用的是通过View
菜单栏查看。
打开后调试窗口如下👇
在Console
输入app.plugins.plugins['Plugin ID']
就可以获取到插件对象了,也就是main.js
中定义的变量和函数,其中Plugin ID
为定义在manifest.json
中的ID
。
热更新插件
每次修改main.js
要想在console
控制台看到效果都需要进行插件的停用和启用(需要程序重新加载文件),可以利用插件hot-reload进行热更新,实现每次修改自动更新插件的目的,关于此插件的安装只能通过github
网站下载安装,插件市场无此插件。
此插件有个特别注意的点就是,需要在进行热更新的插件目录添加.hotreload
文件。比如我的插件目录为myPlugin
,具体存放在MyVault/.obsidian/plugins/myPlugin
,那么在myPlugin
目录下就需要存在文件.hotreload
。
这样每次修改内容都可以即时的在obsidian
内置的开发工具中调试查看内容了。
修改插件
如果你也跟我一样有这样的需求,将粘贴的图片格式化Markdown
标准语法格式,那么下面对插件Image Classify Paste
的修改同样也适合你。
前提,在设置中进行自定义,并且图片存在在指定目录下。
关键方法入口
getRenameFilePath(mdFile, filename)
方法参数如下:
参数mdFile
其实就是当前的md
文档对象。
参数fileName
就是当前的md文档
的文件名。
修改部分
在getRenameFilePath(mdFile, filename)
方法内修改:
// 改动1: 这一行实际没有用到,注释了
// const linkName = this.settings.IsEscapeUriPath ? encodeURI(path.join(dirPath, newFilename)) : path.join(dirPath, newFilename);// 改动2: 新增相对路径生成方法 path.relateJoin()
//添加相对路径,比如dirPath为:/static,mdFile为:/a/b/c/demo.md newFileName为:imageDemo,则输出==> ../../../static/imageDemoconst IsAddRelativePath = this.settings.IsAddRelativePath ? path.relateJoin(dirPath,mdFile,newFilename) : "";const newLinkText = "";
这里进行了IsAddRelativePath
判断是否进行相对路径引用,但是原作者并没有实现此功能,这里做了变动。
relateJoin()
/**
* 返回相对目录
*
* 场景1:mdFile为顶级目录
* mdFile
* dirPath: a/b
* a
* b
* 返回 ==> ./dirPath/imageName 即 ./a/b/imageName
*
* 场景2: mdFile和dirPath同级目录(非顶级同级)
* mdFile:a/mdFile
* dirPath:a/b
* a
* mdFile
* b
* 返回 ==> ./b/imageName
*
* 场景3: mdFile在深层目录
* mdFile:a/mdFile
* dirPath:b/c
* a
* mdFile
* b
* c
* 返回 ==> ../dirPath/imageName 即 ../b/c/imageName
*
* @param dirPath 图片存储路径
* @param mdFile 当前操作的MD文件
* @param imageName 图片名称
* @returns {string} 图片相对路径引用
*/relateJoin(dirPath,mdFile,imageName){// 如果为顶级mdFile直接返回 ./if(mdFile.parent.path == "/"){return "./" + dirPath + "/" + imageName;}// 如果为同级目录,比如 a/b/static a/b/mdFile ==> ./static/imageNamelet mdFileParts = mdFile.parent.path.split("/")let dirPathParts = dirPath.split("/");// 比如 dirPath: a/b/static ==> 得到 a/b 父目录数组const dirPathLastName = dirPathParts.pop();if(mdFileParts.length == dirPathParts.length){let flag = true;for(let i = 0; i< mdFileParts.length; i++){if(mdFileParts[i] != dirPathParts[i]){flag = false;}}if(flag){return "./" + dirPathLastName + "/" + imageName;}}// 其他情况,mdFile需要../到父目录层级let prefix = ""for (let i = 0; i < mdFileParts.length; i++) {prefix += "../"}return prefix + dirPath + "/" + imageName;
},
将此方法添加到path
变量中即可。
如果出现其他问题也可按照上面的插件开发内容自行调试。
插件推荐
obsidian git
将笔记内容自动同步到远程仓库(github
或者gitee
)都可以。
安装教程参考:# 【Obsidian】【Git】使用gitee同步/保存obsidian笔记
Image Classify Paste
如果你也和我一样想要同步的笔记能够在线查看图片,那么大概率也会存在我这种问题,利用这个插件进行粘贴图片的格式化。
Clear Unused Images
从名字就知道,用来清除没有用到的图片,比如我粘贴一张图片,默认就会保存到/static
目录,但是发现图片有问题,于是重新截屏了一张,但是原来的图片并不会删除,也就是无效文件的存在。这个插件会在侧边栏生成一个Ribbon
,需要手动点击清除,会弹出清除文件的日志。
相关文章:

Obsidian插件安装与开发
大概背景 事情的起因还是因为做笔记,我喜欢利用插件Obsidian Git自动同步笔记到Gitee,写md文档有个问题就是关于图片如何存储。 我个人习惯是将所有图片都保存到指定的文件夹下,如图👇 由于Obsidian对粘贴图片默认格式为这样的&…...

lvs的dr模式实现
目录 一、实验环境准备 1、五台红帽9系统的主机 2、关闭所有的防火墙以及关闭selinux 二、在lvs中配置 1、在lvs中安装lvs软件并设置开机启动 2、在lvs中打开内核路由功能,并把它写入/etc/sysctl.conf文件中 3、webserver1和webserver2下载httpd 4、在lvs主机…...

免费写作神器,自动生成高质量文章
在当今数字化的时代,信息的传播和创作变得前所未有的重要。无论是企业的营销推广、个人的博客写作,还是学术研究报告,优质的文章都能发挥巨大的作用。而随着人工智能技术的飞速发展,免费的ai写作工具应运而生,为我们带…...
C#属性
属性(property)的概念是:它是一个方法或一对方法,在客户端代码看来,他(们)是一个字段。 下面把前面示例中变量名为_firstName的名字字段改为私有。FirstName属性包含get和set访问器,来检索和设置支持字段的…...
Spring的代理模式
目录 1、什么是代理模式? 2、为什么要用代理模式? 3、有哪几种代理模式? 4、静态代理 5、动态代理 (1)Proxy动态代理 (2)Enhancer动态代理 (3)dbUtil和动态代理的…...
el-table合计放在标题上方且合并列以及渲染后端返回的数据
el-table二次封装的父组件中的属性 <y-table :table-data"tableData" :table-model"tableModel" :isShowSummary"true" :getSummaries"getSummaries"></y-table>el-table合计放在标题上方 <style lang"scss"…...

magic-api相关应用与配置
目录 项目启动 工具:IDEA 运行项目 关于配置 项目启动 工具:IDEA 新建——》项目——》导入——》运行 运行项目 http://localhost:9999/magic/web/index.htmlhttp://localhost:9999/magic/web/index.html 关于配置 配置多数据源 在线配置多数据…...

AI大模型赋能开发者|海云安创始人谢朝海受邀在ISC.AI 2024大会就“大模型在软件开发安全领域的应用”主题发表演讲
近日,ISC.AI 2024 第十二届互联网安全大会在北京国家会议中心盛大开幕。作为全球规格最高、规模最大、影响力最深远的安全峰会之一,本次大会以“打造安全大模型 引领安全行业革命”为主题,聚焦安全与AI两大领域,吸引了众多行业领袖…...

基于Kahn算法|动态线程池,支持扩展点并发执行|召回|过滤
背景 在《分布式领域扩展点设计稿》一文中,我们提到针对业务横向扩展点和纵向扩展点的编排能力。 那有这样的一种场景:针对于一次会话,同时会调很多外部服务,同时这些RPC服务会有多种直接或间接的关系,是否有更高效的…...
Bootstrap 4 表头固定,tbody滚动条
表格 <div class"row" style"background-color: #fff;overflow: auto;max-height: 500px;"> <table class"table table-striped table-bordered scrolltable text-nowrap"> <thead> …...
MYSQL知识点(持续更新)
数据库 文章目录 数据库Mysql基础篇数据库相关概念MYSQL启动数据库类型关系型数据库 SQL语法SQL通用语法SQL分类DDL - 数据库操作 Mysql基础篇 数据库相关概念 数据库、 存储数据的仓库,数据是组织的进行存储 数据库管理系统 操纵和管理数据库的大型软件 SQL语句…...

html+css网页设计 酷狗首页1个页面 (无js)
htmlcss网页设计 酷狗首页1个页面无js功能 页面还原度80% 网页作品代码简单,可使用任意HTML编辑软件(如:Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作)。 …...

用户体验至上:9款软件界面设计工具分享
你知道如何选择正确的UI设计软件吗?您知道哪些界面设计软件需要设计美观的用户界面,以及带来良好用户体验的APP吗?根据APP界面的不同功能,制作软件界面的选择也会有所不同。但是,并非要非常精通所有的制作软件界面&…...
Lambda 表达式:解锁编程世界的魔法之门
引言 在这个技术日新月异的时代,编程语言不断进化以适应日益复杂的软件开发需求。其中,Lambda表达式作为一门现代编程语言的重要特性,已经成为了提升代码效率与可读性的关键工具。无论你是刚刚踏入编程领域的新手,还是已经在软件…...

【python】Pandas处理Excel表格用法分析与最佳实践
✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…...

KL 散度(python+nlp)
python demo KL 散度(Kullback-Leibler divergence),也称为相对熵,是衡量两个概率分布之间差异的一种方式。KL 散度是非对称的,也就是说,P 相对于 Q 的 KL 散度通常不等于 Q 相对于 P 的 KL 散度。 一个简…...

四种推荐算法——Embedding+MLP、WideDeep、DeepFM、NeuralCF
一、EmbeddingMLP模型 EmbeddingMLP 主要是由 Embedding 部分和 MLP 部分这两部分组成,使用 Embedding 层是为了将类别型特征转换成 Embedding 向量,MLP 部分是通过多层神经网络拟合优化目标。——用于广告推荐。 Feature层即输入特征层,是模…...

鹏鼎控股:最新面试求职SHL逻辑测评笔试题库讲解及真题分享
鹏鼎控股(深圳)股份有限公司,成立于1999年4月29日,是一家专业从事印制电路板(PCB)设计、研发、制造与销售的企业。公司产品广泛应用于通讯、消费电子、汽车、服务器等多个领域,服务全球市场。鹏…...

【Git】git 不跟踪和gitignore区别
文章目录 不跟踪(Untracked):.gitignore 文件:总结 在 Git 中,不跟踪(untracked)和 .gitignore 文件有不同的作用和用途: 不跟踪(Untracked): 不…...

51单片机—智能垃圾桶(定时器)
一. 定时器 1. 简介 C51中的定时器和计数器是同一个硬件电路支持的,通过寄存器配置不同,就可以将他当做定时器或者计数器使用。 确切的说,定时器和计数器区别是致使他们背后的计数存储器加1的信号不同。当配置为定时器使用时,每…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...

MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...

网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...

回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...

逻辑回归暴力训练预测金融欺诈
简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...