解决ob的发布问题

我的一个强需求是: 将 ob 上管理的这些文档,发布到 web 中。

  • 在发布的页面中,要解决 双向链接 的识别问题 [强需求]
  • 在发布的页面中,要解决 悬浮阅读 的问题 [中强需求]
  • 在发布的页面中,要解决 段落引用 的问题 [中等需求]
  • 在发布的页面中,我需要有 知识关联图谱 存在 [弱需求]
  • 解决文档发布的多平台分发问题 TODOs #tasks
    • 解决 github 的发布问题 ✅ 2022-07-16
    • 解决 blog 站 的发布问题 ✅ 2022-07-16
    • 解决 infoq 写作平台的发布问题
    • 解决 掘金 的发布问题
    • 解决 简书 的发布问题
    • 解决 CSDN 的发布问题
    • 解决 gitee 的发布问题
  • 修改 hexo-backlink 的代码,以适应我的需求 解决ob的发布问题 ✅ 2022-07-16
  • 发布的文章中,有图片比没图片的阅读心理压力小,增加图片 ✅ 2022-07-16 自动解决文章的图片问题
  • 解决 悬浮阅读 的发布问题 ✅ 2022-07-30
  • 通过 CICD 完成现有平台的发布

由于我的 博客 渲染,采用的是 hexo 体系,因此发布问题的解决,需要结合 hexo 的生态。

hexo 解决双链问题

最简单的方案是: npm install hexo-backlink项目地址

由于 社区的 hexo-backlink 不支持子路径,因此借鉴一下自己改改。

hexo 采取的插件机制,估计是用的类似于 quickjs 或者 v8 的沙盒,可由开发者自行开发插件,而 hexo 只需要把所有的插件代码组织起来,运行一遍,就能实现插件对内容的处理。沙盒技术可以参考 虚拟机随谈 #插件机制 #quickjs #js引擎

考虑到将来可能会有比较多的 hexo 的适配问题,因此希望能更全面了解 hexo 的插件能
力,可以阅读 hexo extend

不得不说,hexo 的文档写得是真的烂……
根本不知道每个阶段有什么参数,会影响什么……
最后,通过 两次 before_post_render 解决了全局变量获取的问题,虽然不怎么优雅,但算是能解决问题。

代码如下:

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
// data 为 
// [
// [{},{}], posts
// [] about,index
// ]
function doreplace(data) {
let { content, title } = data;
let result = content.match(/\[\[.*?\]\]/g);
if (result && result.length > 0) {
result.forEach((linkName) => {
let [realName, showName] = (linkName + "")
.replace("[[", "")
.replace("]]", "")
.split("|");
let anchor = null;
[realName, anchor] = realName.split("#");

let doc = hexo.locals.get(realName)
// console.log("path : ", doc.path);
console.log(doc)

if (doc) {
let path = getsubpath(doc.permalink)
content = content.replace(
linkName,
`<a href="${path}${anchor ? "#" + anchor : ""}" name="${realName}" >${showName || realName}</a>`
);
} else {
content = content.replace(
linkName,
`<a href="/notpublish/index.html" name="${realName}" >${showName || realName}</a>`
);
}
});
}

data.content = content;
return data;
}

// 先统计
hexo.extend.filter.register("before_post_render",
function (data) {
if (ignore(data)) {return}

hexo.locals.set(data.title, () => data)
}, 0)

// 后替换
hexo.extend.filter.register("before_post_render",
function (data) {
if (ignore(data)) {return}

doreplace(data)
}, 0)

function ignore(data) {
var sourceFileName = data.source;
var ext = sourceFileName.substring(sourceFileName.lastIndexOf(".")).toLowerCase();
return !data.publish || ext != '.md';
}


function getsubpath(p) {
if (p.match(/^(http|https):\/\//)) {
let u = new URL(p)
return u.pathname
}
return p
}

解决 blog 站的发布问题

方案: 采用 七牛云 的 qshell,发布到某个 bucket 下即可:

1
qshell qupload quploadconfig.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
➜  blog git:(master) ✗ cat quploadconfig.json 
{
"src_dir" : "publish/",
"bucket" : "bloglong",
"key_prefix" : "",
"ignore_dir" : false,
"overwrite" : true,
"check_exists" : false,
"check_hash" : true,
"check_size" : false,
"rescan_local" : true,
"skip_file_prefixes" : "test,demo,",
"skip_path_prefixes" : "temp/",
"skip_fixed_strings" : ".svn,.git,.vscode",
"skip_suffixes" : ".DS_Store",
"log_rotate" : 1,
"log_stdout" : false,
"file_type" : 0,
"resumable_api_v2" : false,
"resumable_api_v2_part_size" : 4194304
}

解决 github 发布问题

方案: 采用 docs 目录,作为 github pages 的入口。

目前可以先这样用着,之后觉得 基于分支 的发布方式更好的话,到时再调整一下就行。

解决悬浮阅读的问题

实际上,这是一个和发布本身没太多相关性的问题,甚至可以认为,这个功能通过加一个浏览器插件就能解决。

确实如此,因此通过在生成的 html 中,添加自定义的 js 引用来达到目的。代码比较粗糙,将来有更多更清晰的需求时,再进行统一改造。

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
let allowSubs = ["/archives/", "/posts/", "/categories/", "/tags/"]
let matchpath = window.location.pathname.match(/\/.*\//) || []
let firstPath = matchpath[0]
let shouldOpen = false

// 在允许的路径中
if (allowSubs.includes(firstPath) && self == top) {
let longiframeStyle = document.createElement("style")
longiframeStyle.innerText = `.long-frame{width:500px;height:600px;border:none;position:absolute;z-index:9999;display:block;}.frame-on{display:block}`

let longiframe = document.createElement("iframe")

longiframe.id = "longframe"
longiframe.classList.add("long-frame")

let body = document.getElementsByTagName("body")[0]

body.append(longiframeStyle)
body.append(longiframe)

runscript()
}

function runscript() {

let longframe = document.getElementById("longframe"); // 目前只有一个 iframe
this.document.querySelectorAll("main a").forEach(a => {
a.addEventListener("mouseover", e => showInIframe(longframe, e))
});

this.document.onclick = function (e) {
shouldOpen = false
if (longframe.src != "") {
longframe.style.height = 0
longframe.style.width = 0
longframe.style.display = "none"
}
};
}

function showInIframe(iframe, e) {
if (shouldOpen) { // 防止闪动
return
}
shouldOpen = true

let src = e.target.href || ""
if (!src) { return }

// 得去掉锚点,否则 fluid 主题的 scroll 会有问题
src = src.split("#")[0]

// 外链
if (src.trimStart().startsWith("http")) {
// 同源
if (window.location.host == src.replace(/^(http|https):\/\//, "").split("/")[0]) {
iframe.onload = function () {
if (!shouldOpen) {
return
}

let posx = e.pageX; let posy = e.pageY;

iframe.style.top = posy + 30 + "px";
iframe.style.left = posx + 50 + "px";
iframe.style.width = "500px"
iframe.style.height = "600px"
iframe.style.display = "block"
}
iframe.src = src
}
}
};

现在悬浮阅读有一些不方便的地方:

  1. 仅有一个预览框 (无法多个预览)
  2. 预览框的位置和大小太死板
  3. 仅适用于一级结构 (层级内是关闭的)
  4. 内嵌页面的格式不够友好 (header 部分太长)
  5. 无法自定义是否开启或关闭

之后看情况解决下这些问题。【TODO】

hexo 与 ob 的目录结构组织问题

我目前的绝大多数文章,都是 技术相关 的文章,所以在写的时候,都是直接扔到一个统一的 _posts 目录下,因为这也是 hexo 直接的文章管理方式。

随着文章范围的扩展,有一些其他类型的文章独立成体系,就不太方便统一扔到一个目录下,比如 生产力建设 下有一系列 ob 的文章。

从期望来看,一个目录,就对应着一个 分类
从 ob 和 hexo 的职责来看,ob 负责 知识库管理 ,hexo 负责 blog 渲染和发布

hexo 需要用到 ob 中的各种文档。 目前我的解决方式是,把原有的 hexo 下的 source 目录,软链到 ob 的根目录下。 这样的问题在于,想发布的文档,只能被拖到另一个目录下。 这是不友好的。

可以探索另一种方式,所有的文档全部放到 ob 中,把要发布的文章,统一加上一个特定的 meta 信息,要发布之前,用脚本跑一次,把相关文档 软链/复制 到对应的 hexo 目录下,然后再进行渲染和发布操作。

值得参考的文档:


归属:


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!