这是一篇过期文章 [2024.04.12]

本篇文章已过期。

  • 本文为文章 Hexo 博客适配 Obsidian 新语法 中双链语法部分的分离,强烈建议使用新方法适配双向链接。
  • 在没有合适插件的情况下,我自己探索了一套方法实现这个效果。但是这套方法安装插件较多,依赖性复杂,不易维护。于是我自己写了一个更好的插件完成了这个效果,更多故事详见 第一次写 Hexo 插件
  • 这套工作链服务了半年,成功见证了数十篇文章诞生。截至光荣退休时它还能工作😀。

文章介绍了在 Hexo 中成功渲染双向链接的方法。

相关插件安装

对于 OFM 语法中的 [[ ]],需安装以下三个插件。

确保安装了 Hexo 第三方插件 hexo-abbrlinkhexo-abbrlink 是一个生成文章永久链接的插件,平时写博客就很建议你使用。后续插件将基于 hexo-abbrlink 进行工作。

仓库地址:rozbo/hexo-abbrlink: create one and only link for every post for hexo (github.com)

Obsidian 第三方插件 link-info-server

从 GitHub 仓库下载压缩包:moelody/link-to-server (github.com)(理论上应该在 Obsidian 第三方插件市场找,但是找不到)。安装了插件之后记得启用。

Hexo 第三方插件 hexo-link-obsidian

仓库地址:moelody/hexo-link-obsidian (github.com)。此插件还支持更多双向链接功能,具体可查看仓库说明文档。

该插件目前存在的问题:

  • 关于网络图片的问题 · Issue #3
  • 关于生成的链接问题 · Issue #5
  • 不支持 webp 图像的识别 Pull Request #6
  • 必须保证 Obsidian 软件的运行(临时解决方法:详看下一小节)
  • 混淆了接口类型的图片(临时解决方法:修改源代码中的图片正则匹配,彻底弃用该插件的图片功能)
  • 不支持形如 [](![]()) 的格式识别。纯文本中存在这种字符就报错,就比如这里我用的是粗体加反斜杠转义而不是使用行内代码格式表示。(临时解决方法:修改源代码中的图片正则匹配,彻底弃用该插件的图片功能)

【可选】自写脚本实现 hexo 静态网页生成前自动检查

注意到,要想运行正常,得先打开 Obsidian 软件启动 3333 端口。为了避免疏忽造成链接生成的失误,我写了一个脚本对相关端口和插件进行了检查。

写好 js 脚本

使用脚本前需要安装本脚本依赖的 npm 包。也就一个 npm inastall -g yamljs(全局安装还是局部安装自己看着办),读 yaml 文件用的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// Writer: uuanqin
// At: 2023.07.27

const { exit } = require('process');
YAML = require('yamljs');
var exec = require('child_process').exec;
const package_json = require('./package.json')

function execute(cmd){
return new Promise((resolve, reject)=>{
exec(cmd, function(error, stdout, stderr) {
if(error){
console.error(error);
}
else{
// console.log(stdout)
console.log(`PRE-CHECK: excuse command - ${cmd}`)
return resolve(stdout)
}
return reject("err")
})
})
}

// 参考
// https://github.com/moelody/hexo-link-obsidian
// https://github.com/moelody/link-to-server
// 插件默认监听的端口号
var port = 3333

// 查看有没有自定义port
function update_custom_port(){

// Load yaml file using YAML.load
nativeObject = YAML.load('_config.yml');
jsonstr = JSON.stringify(nativeObject);
jsonTemp = JSON.parse(jsonstr, null);

// 有没有自定义过监听端口,有则改
if(jsonTemp.easy_images!==undefined && jsonTemp.easy_images.port){
port = jsonTemp.easy_images.port
}
}

function main(){
var pid_arr,pid_port_open_arr;
execute(`tasklist /FI "IMAGENAME eq Obsidian.exe" /NH`)
// PID 检查程序是否启动
.then((str)=>{
const reg1 = RegExp(/obsidian.exe/gi);
if(str.search(reg1)<0){
throw "Obsidian.exe is not running."
}
console.log(str)
pid_arr = str.match(/(?<=obsidian.exe\s+)[0-9]+(?=\s)/gi)
})
// Hexo插件安装检查
.then(()=>{
var version = package_json.dependencies["hexo-link-obsidian"]
if(version !== undefined){
console.log(`PRE-CHECK: Your hexo-link-obsidian version - ${version}`)
return;
}else{
throw "You haven't install hexo-link-obsidian plugin or just install it in global."
}
})
// 目标端口更新
.then(()=>{
update_custom_port()
console.log("PRE-CHECK: Target port - ",port)
})
// 查询目标端口对应开放的PID
.then(()=>{
// console.log(pid_arr)
return execute(`netstat -ano | findstr ":${port}"`)
})
// PID_PID 匹配
.then((str)=>{
console.log(str)
pid_port_open_arr = str.match(/(?<=\s+)[0-9]+(?=\r)/g)
// console.log(pid_port_open_arr)
const pid_set = new Set(pid_arr)
// console.log(pid_set)
for (num of pid_port_open_arr){
if (pid_set.has(num)){
return;
}
}
throw "Target port is not listening by Obsidian. Please check your settings."
})
.then(()=>{
console.log("PRE-CHECK: All checks are done.")
exit(0);
})
.catch((error)=>{
// 命令执行抛出err
if(error==="err"){
console.error(`ERROR: Please contact developer to seek for solutions.`)
}
else{
console.error("ERROR: ",error)
}
exit(1);
})
}

main()

这个脚本主要做以下事情:

  • 检查 Obsidian 程序是否启动
  • 检查 hexo-link-obsidian 插件是否安装
  • 确认 hexo-link-obsidian 插件监听的端口
  • 查询对应端口占用的进程是否为 Obsidian 程序

在这里,我将脚本命名为 check_obsidian.js

package.json 的配置

package.json 中的 script 有以下特点:

  • 具有钩子性质
  • 其中一条命令异常退出(返回非零值)后续命令则终止

由于在每一次本地部署和网站发布前我们都需要检查一下 Obsidian 是否打开,我们可以这样设置钩子。

什么是钩子?比如,我们设置的本地部署命令为 hexo 三连 "start": "hexo clean && hexo g && hexo s",那么我们可以新建一个命令:"prestart": "node check_obsidian.js"。当我们每次执行 npm run start 时,都会先执行 prestart、再执行 start。

当 prestart 过程出现错误时,start 就不会执行。这样我们就实现了部署前的检查。

分享一下我目前的 script 配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
"scripts": {
"build": "hexo generate",
"clean": "hexo clean",
"deploy": "hexo deploy",
"server": "hexo server",
"prepublish": "npm run check-obsidian && npm run check-markdown-filename",
"publish": "hexo clean && hexo g && npm run gen-cosma && hexo d",
"postpublish": "hexo algolia && npm run flush-cdn",
"prestart": "npm run check-obsidian && npm run check-markdown-filename",
"start": "hexo clean && hexo g && npm run gen-cosma && hexo s",
"check-obsidian": "node my_scripts/check_obsidian.js",
...
},
注意

hexo algolia 放在 hexo d -g 后,否则报错

提示

&& 表示与,根据“短路效应”。只有前面的命令执行成功,后面的命令才会继续执行。
& 表示两条命令同时执行。

本文参考