把GitHub作为图床

背景

最近又迷恋上了写博客,尤其是前一段时间很想要写点东西分享一些软件的使用感想。但当写完文章想要发表时就会碰到一个问题:由于我是现在本机的编辑器中用Markdown写好了全文的内容,再发表到各个平台(曾经是GitHub Pages搭建的博客,后来又多了简书,现在再加上SegmentFault)上的,因此文章里的图片都是引用在本地磁盘上的文件路径的。这么一来,如果直接将文章源码粘贴到博客平台上——比如粘贴到SegmentFault中,那么这些本地的图片链接就无法在发布后的文章中正常显示了。

如果一开始就在SegmentFault中写作也会遇到问题。SegmentFault上的文章插入图片后,并不是像普通的Markdown源码那般插入一条![]()形式的标记的,而是像下图这样

在SegmentFault中插入图片后的效果

显然,这样的文章源码复制到其它平台(GitHub Pages、简书)去发布的话,必然是需要针对其中的图片标记修改一番的——比刚开始的方法或许要更麻烦。

看来要解决这个图片链接在不同平台间共用的问题,必须有一处纯粹的用于存放图片文件的地方——也就是大家常说的图床了。刚开始我也放狗搜了一下,看看别人的推荐,印象中得到的答复不外乎是又○云、七○云、新○微博,以及sm.ms等。但它们要么需要注册并且实名认证,要么不纯粹,要么让人觉得随时会丢失。

某个晚上忽然想到,GitHub不就是一个很好的图床么?!在GitHub上建一个仓库专门存放博客中的图片,不仅免费、完全受自己管理,而且自带CDN加速,并且我的读者群(如果真的有这么一个群体的话)也应当可以畅通地访问GitHub。

放图片的仓库虽然有了,但用起来还不是很便利——因为作为写作素材的图片在我的电脑上是存放在一个单独的、非GitHub仓库的目录下的,所以如果要丢到图床上,就需要先将文件复制过去,然后执行git的add、commit、push三部曲,最后还要到GitHub上复制这张新图片的“raw”地址。

这个过程很机械化,完全可以用一个AlfredWorkflow来代劳。

编写Workflow

编写Workflow就像编写Common Lisp中的宏一样,总是从它们的用法入手的。在我的设想中,这个Workflow的使用方式应当是:

  1. 首先,按下快捷键调出Alfred的输入框,输入关键字(在我这里就叫做upload)来唤起这个Workflow;
  2. 然后,输入要上传的图片文件的绝对路径并按下回车,开始在后台处理
  3. 最后,上传完毕后,弹出通知来告诉我

整个Workflow的概貌其实很简单

upload Workflow的全貌

第二个节点所调用的External Script是长这样子的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash
# 将磁盘文件上传到GitHub

path=${1}

pictures_dir="${HOME}/Documents/Projects/riverbed/pictures"
cp "${path}" "${pictures_dir}"
echo '文件复制完毕'

file=$(basename "${path}")
cd "${pictures_dir}"
git add "${file}"
git commit -m '上传一张图片'
git push -u origin master
echo '文件已提交到GitHub'

/usr/local/bin/node -e "console.log(encodeURI('https://raw.githubusercontent.com/Liutos/riverbed/master/pictures/${file}'));" | tr -d '\n' | pbcopy

获取文件的绝对路径其实很简单,在Finder中选中文件后,按下Command+Option+C即可

这里使用basename命令获取文件名。并且,为了避免git打开文本编辑器要求输入commit message,向git-commit命令传递了-m选项。

因为文件名含有非ASCII的字符(毕竟会有中文),需要做一次URL编码,因此用了node来做转换。在Node.js代码中用console.log输出编码后的图片URL,结尾会有一个换行符,所以用tr将其去掉。最后,输出的内容重定向给pbcopy,就将上传后的图片URL复制到剪贴板中了。如果此时正在编辑文章,便可以粘贴这个图片的链接到源码中。

Alfred也提供Copy to Clipboard,用于将Workflow中上一个节点的输出复制到剪贴板中。之所以不使用,其实是因为刚开始的时候就是用的Alfred的Copy to Clipboard,结果发现git运行过程中的输出也被Alfred接收了,跟图片URL一起混进了剪贴板中。所以最后改为直接调用pbcopy

全文完。