0%

2023-03-20 如何实现多平台同步 markdown 格式博客

2023-03-20 如何实现多平台同步 markdown 格式博客

温馨提示:本文使用 ChatGPT 和 New Bing 润色

参考链接:

hexo:https://hexo.io/zh-cn/index.html

微信公众号同步助手官网:https://www.wechatsync.com/

mavon-editor:https://github.com/hinesboy/mavonEditor

前言

最近突发奇想,想要多平台发展,但笔者的主要博客都在自己部署的 hexo 上面。因此需要找到一个可以实现多平台同步 markdown 博客 的办法。

最终找到了“微信公众号同步助手(Wechatsync)”,部分地实现了想要的效果。

但微信公众号同步助手存在一个问题,那就是只能从浏览器端同步博客。直接从网页提取的文章存在格式问题。因此基于article-syncjs 二度封装,自己写了一个上传用的网页,并对微信公众号同步助手的浏览器插件端进行了修改:

  • 解决了文章末尾出现的广告
  • 解决了简书平台的 markdown 支持问题
  • 解决了知乎平台的多余换行问题

微信公众号同步助手

是什么

微信公众号同步助手是一个专为文章同步设计的工具,旨在提供一个简便的方式来同步文章到多个内容平台。下面将介绍该工具的安装方法和使用方法。

如何安装

从 Chrome 商店安装

如果可以访问 Chrome 商店,则可以直接从商店安装插件。插件链接:https://chrome.google.com/webstore/detail/%E5%BE%AE%E4%BF%A1%E6%96%87%E7%AB%A0%E5%90%8C%E6%AD%A5%E5%8A%A9%E6%89%8B/hchobocdmclopcbnibdnoafilagadion

从压缩包安装

如果无法访问 Chrome 商店,则可以从压缩包安装插件。插件链接:https://wpics.oss-cn-shanghai.aliyuncs.com/WechatSync.zip?date=20210318

自行编译安装

如果想自己从源码安装,则可以先 clone 源码,再编译后安装。源码链接:git clone https://github.com/wechatsync/Wechatsync.git

如何使用

安装完插件后,只需要在任意网页右键菜单中点击“提取正文”选项,即可提取到当前页面的文章。然后选择需要同步到的渠道即可做到互同步。具体操作见官网说明。
以下是使用效果截图:

img

存在的问题及解决方法

  1. 直接从网页提取的文章存在格式问题:建议自己写一个在线 Markdown 编辑器,以解决格式问题。
  2. 文章末尾出现插件自己的广告:可以通过修改插件源码,去除广告。
  3. 简书明明是支持 Markdown 格式的,但只提供了 HTML 的上传方式:可以通过修改插件源码,使简书优先上传 Markdown 格式。
  4. 发布到知乎时存在多余的空行:可以通过修改插件源码,使发布到知乎时没有多余的空行。

解决问题

既然已经确定了方案,那么就开始动手实现了。

1.手写在线 Markdown 编辑器

作为一个老前端,使用 Vue3 + element-plus 手写一个页面也很快。

为了实现 Markdown 编辑器,我使用了由国人程序员开发的 mavon-editor,它的样式看起来不错。

最终的效果如下:

image-20230320222125551

虽然样式有点简陋,但秉持着“能用就行”的态度,所以就这样吧。

接下来要引入 article-syncjs

image-20230320222218139

解决样式冲突问题

有个小问题就是,因为我自己用的是 element-plus,而 article-syncjs 中用到了 element-ui,两边的 CSS 样式会冲突。

我的解决办法就是直接去掉了 article-syncjs 的 CSS 样式,实际结果是没有什么影响,CSS 样式没有崩溃。毕竟“能用就行”,管什么样式。下面是去掉 article-syncjs 的 CSS 样式后的效果:

image-20230320222413287

实现上传 markdown 文件功能

由于我的博客都在本地,所以还需要导入文件到网页。

下面是一个简单的导入文件功能的代码:

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
const onImport = (e: any) => { // 导入
const file: File = e.target?.files?.[0]
if (!file) {
return
}
const reader = new FileReader()
reader.readAsText(file, 'utf-8')
reader.onload = () => {
const result = reader.result as string
if (!result) {
ElMessage.success('上传的内容为空!')
}

article.value.content = content

ElMessage.success('导入成功!')
}
reader.onabort = () => {
ElMessage.error('导入失败!')
}
reader.onerror = () => {
ElMessage.error('导入失败!')
}

}

由于在设计上只考虑了 hexo 格式的 Markdown 文件,也没有考虑开源,所以前端这块就不开源了。各位读者可自行实现。

2.解决文章末尾出现插件自己的广告

通过观察插件源码,可以看到插件处理文章格式的代码都在 packages\@wechatsync\drivers\src目录下。

找到对应的平台,直接注释掉添加广告的代码即可。

以下是示例代码:

1
2
3
4
addPromotion(post) {
// var sharcode = `<blockquote><p>本文使用 <a href="https://juejin.cn/post/6940875049587097631" class="internal">文章同步助手</a> 同步</p></blockquote>`
// post.content = post.content.trim() + `${sharcode}`
}

3.让简书支持 markdown 格式

通过观察插件源码,可以看处理简书的代码在 packages\@wechatsync\drivers\src\jianshu.js文件中。

参考Juejin.js的写法,使用turndown库将 html 转换为 markdown 格式格式。

以下是示例代码:

1
2
3
4
5
6
7
if (post.post_content) {
console.log('TurndownService', turndown)
var turndownService = new turndown()
turndownService.use(tools.turndownExt)
requestData.content = turndownService.turndown(post.post_content) // 转为 markdown
console.log('requestData.content', requestData.content)
}

4.解决发布到知乎存在多余的空行问题

通过观察插件源码,可以看处理知乎的代码在 packages\@wechatsync\drivers\src\zhihu.js文件中。

经过一番阅读源码,发现在 async preEditPost(post) 函数中处理文章内容,因此修改了部分代码,参考如下:

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
// 需要处理的是 <br /> 后出现 \n 的情况
// doc.find('br').each(processBr)

var tempDoc = $('<div>').append(doc.clone())
post.content =
tempDoc.children('div').length == 1
? tempDoc.children('div').html()
: tempDoc.html()

// 清除多余的空行
const nodes = $(post.content)
let result = ""; // 结果字符串
$.each(nodes, function (i, node) {
if (node.nodeType != 3 || node.nodeValue.trim() != "") { // 如果不是空白的文本节点
result += node.outerHTML; // 拼接到结果字符串
}
});

// 需要处理的是 <br /> 后出现 \n 的情况
result = result.replace(/<br\n\r?|<br>\r\n?/g, "\n")
// 处理 </blockquote> 前出现 \n 的情况
result = result.replace(/\n\r?(?=<\/blockquote>)|\r\n?(?=<\/blockquote>)/g, "</blockquote>")
// 处理 </code> 前出现 \n 的情况
result = result.replace(/\n\r?(?=<\/code>)|\r\n?(?=<\/code>)/g, "</code>")

post.content = result

console.log('preEditPost end post.content', post.content)

在知乎的文章中,<br>\n都会被认为是换行,所以需要去重。

改完之后如何使用

改完了源码之后,再重新执行 npm run build 打包一下插件,在浏览器里重新载入插件即可。

改完之后的源码已提交到个人的 fork中,有兴趣的可以自行 clone 下来编译一下。

本文作者:草梅友仁
本文地址: https://blog.cmyr.ltd/archives/62f903af.html
版权声明:转载请注明出处!

坚持原创技术分享,您的支持将鼓励我继续创作!