Comments (28)
右键是可以看到“替换反斜杠为正斜杠”的选项,但实际没效果
from typora_plugin.
你好,感谢反馈。
整体流程是没有问题的。应该是你的 callback 函数体写得有问题。
this.utils 里并没有 File 这个对象,具体你可以看一下 .\plugin\global\core\plugin.js 文件里的 utils 类
我将上面的 callback 改成如下,发现是可以的:
callback = anchorNode => {
alert("this is ReplaceBackslash callback")
}
from typora_plugin.
你好,感谢反馈。
整体流程是没有问题的。应该是你的 callback 函数体写得有问题。
this.utils 里并没有 File 这个对象,具体你可以看一下 .\plugin\global\core\plugin.js 文件里的 utils 类
我将上面的 callback 改成如下,发现是可以的:
callback = anchorNode => { alert("this is ReplaceBackslash callback") }
谢谢大佬,这是我的相关文件,看不太懂,没理解如何修改,有没有可以凭借学习的文档可以查看。
plugin.zip
from typora_plugin.
我帮你打了个样:
class ReplaceBackslash extends BaseCustomPlugin {
callback = async anchorNode => {
const filepath = this.utils.getFilePath();
const content = await this.utils.Package.Fs.promises.readFile(filepath, 'utf-8');
const replacedContent = this.replaceBackslash(content);
await this.utils.Package.Fs.promises.writeFile(filepath, replacedContent);
File.reloadContent(replacedContent, {fromDiskChange: false});
}
// 在这里写主要的逻辑代码
replaceBackslash = content => {
const replacedContent = content.replace(/\\/g, '/');
return replacedContent
}
}
module.exports = { plugin: ReplaceBackslash };
上面代码功能是【将文件中所有的 \ 转换为 /】,并不符合您的预期。
实际上需要修改replaceBackslash方法,先把图片匹配出来,再来替换。
你可以参考 .\plugin\custom\plugins\resourceOperation.js 的做法,它就是先将文件中的图片使用正则匹配出来,再进行其他操作的。
from typora_plugin.
注意,上面 callback 方法代码的最后一行我写错了,
应该是 File.reloadContent(replacedContent, {fromDiskChange: false});
,而不是 File.reloadContent(content, {fromDiskChange: false});
from typora_plugin.
File.reloadContent(replacedContent, {fromDiskChange: false});
!!!!谢谢大佬,功能已经可以正常实现了,接下来就只剩下图片匹配了,谢谢大佬
from typora_plugin.
File.reloadContent(replacedContent, {fromDiskChange: false});
!!!!谢谢大佬,功能已经可以正常实现了,接下来就只剩下图片匹配了,谢谢大佬
匹配图片有个难点:
- 此插件的难点在于如何才能匹配到正确的 markdown 图片
- 比如 ![image](assets/image (30).png) ,使用正则很容易匹配成 ![image](assets/image (30
- 此时需要使用贪婪匹配,然后逐个匹配
- 可以使用如下正则去匹配
regexp = new RegExp("!\\[.*?\\]\\((?<src1>.*)\\)", "g")
具体可以参考 .\plugin\custom\plugins\resourceOperation.js 的做法
from typora_plugin.
- regexp = new RegExp("!\[.?\]\((?.)\)", "g")
谢谢大佬,我的问题已经解决了,您真是我的救星
from typora_plugin.
class ReplaceBackslash extends BaseCustomPlugin {
callback = async anchorNode => {
const filepath = this.utils.getFilePath();
const content = await this.utils.Package.Fs.promises.readFile(filepath, 'utf-8');
const replacedContent = this.replaceBackslash(content);
await this.utils.Package.Fs.promises.writeFile(filepath, replacedContent);
File.reloadContent(replacedContent, {fromDiskChange: false});
}
// 在这里写主要的逻辑代码
replaceBackslash = content => {
const regexp = /!\[(.*?)\]\((.*?)\)/g;
const replacedContent = content.replace(regexp, (match, desc, src) => {
// 对图片路径中的反斜杠进行替换
const replacedSrc = src.replace(/\\/g, '/');
return `![${desc}](${replacedSrc})`;
});
return replacedContent;
}
}
module.exports = { plugin: ReplaceBackslash };
这是代码
from typora_plugin.
好的。此 issue 关闭,有问题麻烦在下面留言,或者另开 issue。
from typora_plugin.
好的。此 issue 关闭,有问题麻烦在下面留言,或者另开 issue。
大佬你好,还有一个新的疑问,我如何把写好的功能添加到typora右下角的按钮中,开发文档里没有找到相关的介绍
from typora_plugin.
负责此功能的是 quickButton 插件,你可以通过修改配置添加。
对于你的情况,你可以在 custom_plugin.user.toml 添加如下配置:
[quickButton]
[quickButton.config]
# disable: 禁用此按钮
# coordinate: 按钮坐标。往上为x轴正方向,往左为y轴正方向,从零开始计数
# icon: 按钮图标。填入css class。支持font-awesome-4.1.0和ionicons-2.0.1,所有的图标及其对应的css class请参考:https://www.adfwebmagazine.jp/wp-content/uploads/test_v4.1.pdf 和 https://ionic.io/ionicons/v2
# size(可选): 图标大小。默认17px
# color(可选): 图标颜色。默认跟随当前主题的配色方案
# bgColor(可选): 图标背景色。默认跟随当前主题的配色方案
# hint: 提示信息
# callback: 回调函数。采用pluginName.MethodName的形式(功能就像hotkey.default.toml中的plugin参数和function参数的合体)
# MethodName请通过阅读源码查找。如果您不懂代码,但还是想添加按钮,有个碰运气技巧:在【右键菜单->常用插件->自定义插件下的插件】基本都是XXX.callback,其余插件基本都是XXX.call
# evil(危险): 自定义回调函数。功能同hotkey.default.toml中的evil参数(它能用的,这里也能用)。这里的文本内容会被eval()。如果设置此参数,callback参数会失效
buttons = [
# 默认的按钮
{ disable = false, coordinate = [0, 0], hint = "直达底部", size = "28px", icon = "fa fa-angle-down", callback = "go_top.goBottom" },
{ disable = false, coordinate = [1, 0], hint = "直达顶部", size = "28px", icon = "fa fa-angle-up", callback = "go_top.goTop" },
{ disable = false, coordinate = [2, 0], hint = "文字风格", size = "17px", icon = "fa fa-font", callback = "text_stylize.call" },
{ disable = false, coordinate = [3, 0], hint = "混排优化", size = "17px", icon = "fa fa-align-justify", callback = "md_padding.call" },
{ disable = false, coordinate = [0, 1], hint = "思维导图", size = "22px", icon = "fa fa-code-fork", callback = "markmap.onButtonClick" },
{ disable = false, coordinate = [1, 1], hint = "图片管理", size = "17px", icon = "fa fa-image", callback = "imageReviewer.callback" },
{ disable = false, coordinate = [2, 1], hint = "书签管理", size = "17px", icon = "fa fa-bookmark", callback = "scrollBookmarker.callback" },
{ disable = false, coordinate = [3, 1], hint = "高亮搜索", size = "17px", icon = "fa fa-search", callback = "search_multi.call" },
# 你的按钮
{ disable = false, coordinate = [4, 1], hint = "正斜杠替换斜杠", size = "17px", icon = "fa fa-book", callback = "ReplaceBackslash.callback" },
]
from typora_plugin.
我不会pr,稍后我可能会写个文档发在issues,因为我做这个插件是用来替换Hexo博客图片路径的,希望能帮到同样有这个需求的的Hexo用户
from typora_plugin.
- 刚刚上面的配置又写错了 😂,是
# 默认的按钮
,不是// 默认的按钮
,请看一下编辑历史 - 具体的参数你可以看一下上面的注释中的说明
- 如有必要,你可以删除默认的按钮(disable置为true),全部都是可配置的。
from typora_plugin.
- 刚刚上面的配置又写错了 😂,是
# 默认的按钮
,不是// 默认的按钮
,请看一下编辑历史- 具体的参数你可以看一下上面的注释中的说明
- 如有必要,你可以删除默认的按钮(disable置为true),全部都是可配置的。
没有造成什么错误,大佬修改的很快,我看到的时候就已经改正确了🤭
谢谢大佬的耐心回复,又是一次酣畅淋漓的学习
from typora_plugin.
稍后我可能会写个文档发在 issues,因为我做这个插件是用来替换 Hexo 博客图片路径的,希望能帮到同样有这个需求的的 Hexo 用户
好的。麻烦你了。
from typora_plugin.
//————注意————,这里的 img 路径可以替换为你自己实际的路径
给个建议,插件本身是可以添加配置选项的,可以将硬编码的配置提到 custom_plugin.user.toml 中
示例代码:
# ./plugin/custom/custom_plugin.user.toml
[helloWorld]
name = "你好世界"
enable = true
[helloWorld.config]
show_message = "this is hello world plugin"
// ./plugin/custom/plugins/helloWorld.js
class helloWorld extends BaseCustomPlugin {
callback = anchorNode => {
alert(this.config.show_message);
}
}
module.exports = { plugin: helloWorld };
from typora_plugin.
还有英雄所见略同的一点就是,几年以前,我也整过 hexo 的自动化部署,果然大家都比较懒 😂
事实是,就算有了自动化部署工具,我的博客也停在了 2022 年(悲
from typora_plugin.
//————注意————,这里的 img 路径可以替换为你自己实际的路径
给个建议,插件本身是可以添加配置选项的,可以将硬编码的配置提到 custom_plugin.user.toml 中
示例代码:
# ./plugin/custom/custom_plugin.user.toml [helloWorld] name = "你好世界" enable = true [helloWorld.config] show_message = "this is hello world plugin"// ./plugin/custom/plugins/helloWorld.js class helloWorld extends BaseCustomPlugin { callback = anchorNode => { alert(this.config.show_message); } } module.exports = { plugin: helloWorld };
没太懂大佬的意思,是说插件本身是有相关配置可以提示信息的吗?
from typora_plugin.
还有英雄所见略同的一点就是,几年以前,我也整过 hexo 的自动化部署,果然大家都比较懒 😂
事实是,就算有了自动化部署工具,我的博客也停在了 2022 年(悲
我自从到24年,就已经逐渐开始走脚本化Hexo了😂,部署啥的指令全让我写成sh脚本了,鼠标点两下就完事
from typora_plugin.
给个建议,插件本身是可以添加配置选项的,可以将硬编码的配置提到 custom_plugin.user.toml 中
我懂了,其实我想中的提示信息是可以实现[通过]样式的提示弹窗,alert的弹窗是警告,有种没执行成功的感觉😂
百度了一下发现js没有类似通过的弹窗(好像)
from typora_plugin.
其实我的意思是,你的新的 issue 中,可以将代码中硬编码的 /img/ 改成一个配置选项,毕竟每个人的 hexo 配置都不一样
from typora_plugin.
其实我的意思是,你的新的 issue 中,可以将代码中硬编码的 /img/ 改成一个配置选项,毕竟每个人的 hexo 配置都不一样
明白了,这样写可以吗,对插件的配置刚接触,目前我只想到了这种方式
[ReplaceBackslash.config]
img = "img"
然后this.config.img
作为代码中的变量
然后让使用者去改对应的值
from typora_plugin.
对的
from typora_plugin.
对的
我已经重写完了,实现了这个功能,稍后我修改一下文档
from typora_plugin.
@obgnail
大佬,我刚刚测试的时候发现,图片路径匹配还是写的不好,没法精准匹配到图片路径,这个操作连我的代码块,其他斜杠也给改掉了,实在是不会解决了,求助一下
#469
from typora_plugin.
其实这个需求还蛮难的:
- 需要考虑到
<img src="example.jpg">
的 HTML 图片的情况 - 需要考虑到图片的路径中存在右括号的情况:
![image](assets/image (1).png)
,此时图片路径中的右括号会和图片语法中[]()
的右括号造成歧义 - 需要考虑特殊格式的图片(如base64)和网络图片
重点说明一下如何解决第二点:
- 贪婪匹配。如下内容
![image](assets/image (30).png)asdasdasdasd)aaaaa
,使用贪婪匹配会得到![image](assets/image (30).png)asdasdasdasd)
- 从右往左依次重新贪婪匹配,然后挨个检测文件是否存在,一旦检测到文件存在,则返回:
![image](assets/image (30).png)asdasdasdasd)
,检测是否存在文件assets/image (30).png)asdasdasdasd
![image](assets/image (30).png)
,检测是否存在文件assets/assets/image (30).png
![image](assets/image (30)
,检测是否存在文件assets/image (30
爬起来帮你写了一个框架,我没仔细测试,我并不了解具体业务,需要你自行编写replaceBackslash函数:
[ReplaceBackslash]
name = "替换反斜杠为正斜杠"
enable = true
[ReplaceBackslash.config]
# 是否忽略html标签<img src="example.jpg">里的资源(markdown是支持插入html的,此选项问是否要忽略img标签)
ignore_image_div = false
img_folder = "img"
class ReplaceBackslash extends BaseCustomPlugin {
callback = async anchorNode => {
const filepath = this.utils.getFilePath();
const content = await this.utils.Package.Fs.promises.readFile(filepath, 'utf-8');
const replacedContent = await this.format(content);
await this.utils.Package.Fs.promises.writeFile(filepath, replacedContent);
File.reloadContent(replacedContent, {fromDiskChange: false});
}
format = async content => {
const dir = this.utils.getCurrentDirPath();
const regexp = this.config.ignore_image_div
? new RegExp("!\\[.*?\\]\\((?<src1>.*)\\)", "g")
: new RegExp("!\\[.*?\\]\\((?<src1>.*)\\)|<img.*?src=\"(?<src2>.*?)\"", "g")
return await this.asyncReplace(content, regexp, async (match, src1, src2) => {
const src = src1 || src2;
// 跳过特殊格式的图片(如base64)和网络图片
if (!src || this.utils.isSpecialImage(src) || this.utils.isNetworkImage(src)) return match;
// 检测图片是否存在于当前电脑中,若不存在,则不处理
// 如果不希望检测,可以注释掉下面两行
const realPath = await this.checkImageExist(dir, src);
if (!realPath) return match;
return this.replaceBackslash(match, src, realPath);
})
}
// TODO: 我并不了解具体业务,需要你自行编写(下面函数代码是瞎写的)
// 当前可以使用的变量
// 1. match: 匹配到子串,如: ![image](assets/image (30).png)
// 2. src: 匹配到的路径,如:assets/image (30).png
// 3. realPath: 图片在电脑中的绝对路径,如:D:\\assets\\image (30).png
replaceBackslash = (match, src, realPath) => {
const imgFolder = this.config.img_folder;
if (src.includes('/' + imgFolder + '/')) {
const newSrc = '/' + imgFolder + src.substring(src.indexOf('/' + imgFolder + '/') + imgFolder.length + 1);
const index = match.indexOf(src);
return match.slice(0, index) + match.slice(index).replace(src, newSrc)
}
return match
}
asyncReplace = (content, regexp, placement) => {
let match;
let lastIndex = 0;
const reg = new RegExp(regexp);
const promises = [];
while ((match = reg.exec(content))) {
const str = content.slice(lastIndex, match.index);
lastIndex = reg.lastIndex;
const args = [...match, match.index, match.input];
if (match.groups) {
args.push(match.groups);
}
const promise = placement(...args);
promises.push(str, promise);
}
promises.push(content.slice(lastIndex));
return Promise.all(promises).then(results => results.join(""))
}
checkImageExist = async (currentDir, path) => {
let absolutePath = this.utils.Package.Path.resolve(currentDir, path);
while (!(await this.utils.existPath(absolutePath))) {
const idx = absolutePath.lastIndexOf(")");
if (idx === -1) {
return new Promise(resolve => resolve(null))
} else {
absolutePath = absolutePath.slice(0, idx);
}
}
return new Promise(resolve => resolve(absolutePath))
}
}
module.exports = {plugin: ReplaceBackslash};
from typora_plugin.
@obgnail
😭😭😭😭
大佬太强了,大佬给写的轮子已经实现了,我只吧路径路径简单修改了一下就完全实现了,代码我已经同步更新到文档了
#469
看了一下和之前提到的图片匹配的脚本,还是不会复刻,发现这还真是我知识盲区了,没接触过js,都是凭借着编码经验+大佬的帮助+ChatGPT解决的
大佬新年快乐
from typora_plugin.
Related Issues (20)
- window_tab 改进建议 HOT 2
- 使用 Typora_plugin 实现 Hexo 博客绝对路径一键替换相对路径|正斜杠替换为反斜杠 HOT 9
- 【bug】在只读模式下,依旧可以删除图片 HOT 1
- 使用 Typora_plugin 实现 Markdownd 代码块一键填充指定编程语言 HOT 4
- 【咨询】typora软件升级后插件除了重新安装还有其他办法保留不动吗? HOT 2
- 右上角markdown语法检查:1、没有关闭按钮;2、不能基于更新内容重新检查语法 HOT 4
- 标签怎么关掉啊? HOT 3
- 每次打开typora,会自动给目录与标题自动编号,需要每次手动禁用,可以设置默认禁用吗 HOT 5
- 每次升级,在代理设置中都会显示一个ip HOT 2
- 混排优化、代码栏优化 HOT 19
- 如何参与插件开发 HOT 12
- I completely follow the tutorial to the author, but the right-click does not appear after the plugin logo HOT 2
- 只读的小问题 HOT 3
- 如何取消自动编号 HOT 1
- 关于导出和查找的几点小优化和一个疑惑 HOT 3
- 请问callouts插件可以应用在hexo博客中吗, 如果可以该怎么使用? HOT 2
- 是否可加入同步数据功能 HOT 3
- 导出为HTML。代码块的没有复制按钮。 HOT 2
- 安装的插件能够正常运行,但是按照插件快速起步中编写的插件无法运行与显示。 HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from typora_plugin.