返回

博文创建工具

#分享#
发布于 2023-07-26

简短来说

相比 WordPress 这种博客平台,使用 Git-based/Markdown 管理自己的内容,毫无疑问可控性更强,在各个平台迁移更灵活,但也增大了创建一篇博文的心智负担。虽然有hugo new这种命令行工具,但分类和标签还是需要手动编辑 fontmatters。

之前也做过类似的尝试,用fish shell做了个简单的工具。

functions/blog.fish
function blog
cd /dest/to/blog
set -Ux BLOG_SLUG $argv[2]
set c $argv[1]
argparse t/tag -- $argv
or return
set md (string split '"' (hugo new posts/$c/$argv[2].md) -f2)
sed -i '' 5s/\"\"/\"$c\"/ $md
if set -ql _flag_tag
sed -i '' 6s/\"\"/\"$argv[3]\"/ $md
end
echo $md
open $md
end

思路依然是通过 slug 创建文章,预先把现有的博文分类列出来,然后通过 Tab 完成补全,比在 frontmatters 里改,方便一些。

completes/blog.fish
complete -c blog -xa "comments drafts shares stories thoughs thoughts translations " -n '__fish_is_first_arg'

最近使用 astro 重构了博客,新增了i18n支持和短链等功能,需要副标题和 Id 等更多的抬头,这样就需要修改这个脚本,但是fish脚本维护起来有点费劲,所以决定用node脚本重构一下。

新的功能需求

实施路径

实现可交互的命令行工具

选择技术栈:

inquirer 用于交互命令,commander 用于解析命令行参数,初期考虑两个命令。

  1. create 创建博文
  2. upload 上传图片,一个 option --file -f 用于判断是上传文件还是直接上传剪贴板的文件。
  3. activate 切换当前编辑的文章(类似 conda 环境的管理)
  4. translate 翻译指定文章 //TODO

实现标题的自动翻译

经过实验,直接调用翻译效果很差,最后选择还是用 openai-3.5-turbo (azure),根据输入的标题先判断一下是中英文,然后给出相反的 prompt,根据输入的标题完成翻译。

{
"messages": [
{
"role": "system",
"content": "你是一个中英翻译助手,将下面这个博客文章的标题翻译成${dest}文。"
},
{ "role": "user", "content": "${title}" }
]
}

这样,不管是中文还是英文标题,只需要输入一次就好,另一个交给 AI。

实现短链的自动生成

考虑到自己的博文数量不会太大,只用三位区分大小写的字母来生成短链,这样可以保证短链的唯一性,而且不会太长。 使用short-uuid包,生成 uuid,但只取前三位,然后判断该 Id 是否已经存在,如果存在,重新生成。

const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
const translator = uuid(chars)
let id = translator.new().slice(0, 3)
while (keyExits(id)) {
id = translator.new().slice(0, 3)
}

短链最终使用 Vercel 的redirects来实现,这样只须更改根目录下的 vercel.json,重新部署即可。

{
"redirects": [{ "source": "/${id}", "destination": "/posts/${slug}" }]
}

图片管理

至于为什么不用现有的图床管理工具。

  1. 无法与现有的工作流完全适配
  2. 文件命名不符合自己的习惯

于是这里多做了这一步,在前面生成文章的时候,存一个全局的环境变量,这样图片管理的时候就在根据文章 slug 生成的文件夹下操作。

最后通过pbcopy将获取图片的链接,直接送到剪贴板里,这样就可以直接粘贴到博文中了,就像下面这样。

Terminal window
blog upload test-jpeg
URL: https://static.yuhang.ch/blog/blog-creation-tool/test-jpeg.jpeg

对于一个在剪切板中的截图来说,在这种模式下,自己只需要给他想一个 slug 就好了,工具帮助你把他传到对象储存的指定目录下,然后把链接放到剪贴板里。

结尾

这篇文章来自这个工具。

最后编辑于 2024-04-13