Typora-Picgo

简述

Markdown是什么,不用多说了吧。语法简洁、格式化简单、代码高亮,处处是技术的福音。

笔记软件

编写Markdown笔记的软件有很多,Cmd Markdown、MWeb、Atom、Typora等等等等,包括各笔记软件,相信大家都了解过很多了。

Typora与左右2个窗口的编辑器不同,是真正的即时预览型,也是本人比较喜欢的。

图床

图床是啥?就是个存图片的地方!

Markdown笔记里的图片,是通过一个链接指向的: <img src="...">![name](src)

本地编写笔记时,图片都是用的本地链接,可以是相对路径,也可以是绝对路径。这样一来,如果创作者想要将笔记分享给别人:

  • 要么得将图片和笔记一起打包发出去
  • 要么得找个博客类网站上传,分享文章链接(这里需要搞定图片存储)

第一种方法,想必大家都不会选吧,需要手动打包分享,这绝对不是一个合格的技术该做的事(笑)。

那第二种,选择博客上传,选谁呢?既然你在这里读到了我的文章,想必就知道了我的选择。曾经试过:

  • 简书,发布了Markdown笔记后,发现没有目录。。。。。。
  • CSDN,界面太花,广告太多了,把我的目录都挤下去了,哎
  • 博客园,界面样式比较简洁,但复古,第一眼不喜欢。后来看到有的博客页面不一样,才知道可以客制化,这一点挺好。
    而且第一次写博客前,要打个申请,大概等一小时可以通过。嗯,给人一种很正式很认真的感觉,就你了!

说到这,博客上传Markdown笔记要解决的就一个问题了:图片存储。

博客园自带个很好的处理,本地Markdown笔记复制到编辑框后,点击右下角的提取图片

image-20230102113257496

博客园就会将引用到的本地图片上传到自己网站,并转为网址链接,替换到笔记里,人性化!

不过这样一来,本地文章与博客园发布的就不一样了。

本文将介绍的是另一项专门处理图片存储的软件Picgo,可以与Typora完美集成,自动处理图片。

按本文配置完后,每次写完一篇文章,只要点击菜单栏里的上传,就可以一键上传文章内所有图片了!

另有一篇文章Picgo-博客园,讲述实现Typora一键导出笔记到博客园,支持分类标签

Picgo

官方介绍文档

下载

Typora支持Picgo客户端和命令行2种方式。前者有可视化界面,友好性好一些:

image-20230102132953279

不过我用的是Mac OS,客户端有点问题,点开后不能像其他软件停留在前端,切了别的软件就切不回来了,只能从菜单栏再次点开,有点麻烦。

命令行模式就是没界面,单纯通过后台命令实现设置、上传,其实是与手动在客户端设置是一样的,只是少了界面。对于技术人员来说,这都是小事。

Windows系统,点开Typora的图片设置,选择Picgo-Core,选择框下面就有下载链接(Mac版没有。。):

image-20230102133802992

Mac版在终端运行命令:

npm install picgo -g

如果想选用客户端,在上图的图片上传设置里选Picgo.app,然后选择框下有下载按钮,Win/Mac都是。

不过只在中文下可选到:

image-20230102134451532

图床选择

Picgo默认支持的图床有:GitHub、七牛云、又拍云、Imgur、SM.MS、腾讯云COS、阿里云OSS

  • Github是海外网站,试过效果不好,图片加载慢;
    类似的国内有Gitee,但官方好像限制了API调用,有插件也无法使用了
  • 七牛云,需要自己先开个域名
  • Imgur/SM.MS,国外的,免费,有上传大小和数量限制;稳定性也不能保证,有博主图片加载不出来过 - -

最后在腾讯云和阿里云里随机选了后者,都是国内大厂,有保障。

不过这两个都是付费的,但相对每月开的那些视频会员,这点存储费根本不贵,对自己知识付费才是正确的消费观,你说是吧!

阿里云OSS

购买存储包

选择了阿里云OSS,需要先购买存储包,点此链接。我这里其他默认,时间选择1年,才¥9:

image-20230102143811100

后续外网访问存储中的图片时,还是会按流量计费的,我上个月流量600M+,额外花费¥0.2。

创建Bucket

Bucket是啥?就是你的一个存储仓库,不同类型的数据(如图片、视频)想分开存,就建不同的Bucket好了。
或者同一Bucket,分目录存储。

购买完存储包,进入到OSS管理控制台,点开Bucket列表,点击创建:

image-20230102144758823

输入Bucket名称、选择地域:

image-20230102145333729

Bucket名应该是全用户内唯一的,因为要拼接到图里的Endpoint前,作为自己的存储域名,建议不要太长。

记一下此处的Bucket名、Endpoint值(仅第一个点之前的值,图里为oss-cn-hangzhou),后续配置Picgo要用到。

下划到读写权限部分,选择公共读,以供外网读取:

image-20230102145629661

其他默认即可。

创建子账户

本步生成阿里云的访问ID。

点击右上角的账户,选择AccessKey管理:

image-20230102153834389

弹出的页面,建议选择子账户:

image-20230102154030888

点击创建用户:

image-20230102154125620

输入用户名、显示名,勾选OpenAPI访问控制:

image-20230102154240460

勾选后,Picgo就可以通过此用户,使用阿里云公开的API上传图片了。

建好用户后,记下这里的AccessKey ID及Secret,后续Picgo设置要用到

image-20230102155050961

点击用户右侧的添加权限

image-20230102154620500

点击AliyunOSSFullAccess行,添加到右侧(我这里已添加过):

image-20230102154733401

最后确定就行啦。

配置

如果使用客户端,则打开软件,选择阿里云OSS图床:

image-20230102132953279
  • 设定KeyId、设定KeySecret:为创建子账户一步中,创建的用户访问ID
  • 存储空间名、存储区域:为创建Bucket一步中,创建的Bucket名及对应Endpoint
  • 存储路径:阿里云OSS中的文件是可以分目录存储的,这里配的路径就是根目录名。这个功能我很喜欢,我们会在下文利用这一功能,实现图片自动分目录存储。

如果使用命令行,在终端运行picgo set uploader:

image-20230102161100701

可以上下键选择图床,回车选定。

选定后,会逐项弹出设置项,与客户端界面显示的一致,挨个输入就好了:

image-20230102161302856

使用

在Typora的图片上传设置里,点击下图位置的按钮,测试就行了~(Mac版又没有命令行的测试按钮,害)
image-20230102161602698

当时设置完,一次就通过了!不像Github、Gitee之类的总是报错。

上传后,可以在OSS管理控制台查看:

image-20230102164849564

注意图里圈出的话,文件名里"/"分隔出的将会视作目录,后续有大用!

另外,可以对复制到笔记中的图片设置为立即上传:

image-20230102165953102

但是不建议使用此项,一般写笔记的过程中,图片可能会删了又换。

我们先设置为固定路径,同一笔记的图片先按笔记文件名自动创建目录存储(${filename}为笔记文件名):

image-20230103111514472

等到基本定稿后,再统一上传即可:

image-20230102170221242

分目录存图片

完成前面步骤后,我们就可以实现将本地图片自动上传到阿里云了!

但是有个问题,所有笔记的所有图片,都上传到了一个目录下,对于我这种略有强迫症的人来说,感受不太好,像个大杂烩,所以想将图片按照笔记的目录存储。
比如/pardir/dir1/note1.md的图片,上传到阿里云的/dir1/note1目录下。

想要实现这种不在Picgo自身功能内的效果,就得通过Picgo的插件来做了。

Picgo插件能做的事很多,甚至可以完全客制化出来一个图床,当然,这个门槛有点高,参考官方资料

Picgo插件收录在了Awesome-Picgo项目中,为了实现分目录存储,在其中翻了遍,都没有找到合适的,只有一个folder-name较为相近。但他可设置的路径层数是固定的:

image-20230102170431968

如果笔记的层级数不统一,就不太好搞。另外,批量上传时,层数的设置会失效 - -

在Github上给作者提了层数失效的Issue,虽然回复了,但是2个多月过去了,似乎很忙,一直没处理,那只好我自己来了!

安装

插件

客户端安装比较简单,直接在插件设置里搜索folder-name就好了:

image-20230102172249288

然后点击插件右下角的安装即可。

如果是命令行,执行命令picgo install folder-name。

Node

插件运行还要依赖于Node.js环境,Mac OS一般自带了,Windows需要到官网下载安装

修改

找到下载后的插件源码父目录:

  • 客户端版: 在Picgo设置中,点击打开配置文件:
    image-20230103102337939
    父路径即为该配置文件所在目录
  • 命令行版:
    • Windows: C:\Users\username\.picgo
    • Mac: ~/.picgo

在父目录下,找到源码文件:node_modules/picgo-plugin-folder-name/src/index.js,修改内容为:

const path = require('path')

const config = ctx => {
  let userConfig = ctx.getConfig('picgo-plugin-folder-name')
  if (!userConfig) {
    userConfig = {}
  }
  return [
    {
      name: 'img_ignore_path',
      type: 'input',
      alias: '图片忽略路径',
      default: userConfig.img_ignore_path || "",
      message: '忽略的图片前缀路径',
      required: true
    },
    {
      name: 'mkd_ignore_path',
      type: 'input',
      alias: '笔记忽略路径',
      default: userConfig.mkd_ignore_path || "",
      message: '忽略的Markdown文件前缀路径',
      required: true
    }
  ]
}

/*
 * 前缀加上 'xxx/' 即可实现云端文件夹新建或分类
 */
module.exports = (ctx) => {
  const register = () => {
    // uploader 是将来自转换器的输出上传到指定的地方,所以需要在转换器之后,在上传之前对这个地方(地址)进行修改
    ctx.helper.beforeUploadPlugins.register('folder-name', {
      async handle(ctx) {
        let userConfig = ctx.getConfig('picgo-plugin-folder-name')
        if (!userConfig) {
          userConfig = {
            img_ignore_path: "",
            mkd_ignore_path: ""
          }
        }
        // 获取忽略路径
        const img_ignore_path = userConfig.img_ignore_path
        const mkd_ignore_path = userConfig.mkd_ignore_path
        if (!img_ignore_path || !mkd_ignore_path) throw new Error('未定义全忽略路径!')
        ctx.log.info('img_ignore_path: ' + img_ignore_path)
        ctx.log.info('mkd_ignore_path: ' + mkd_ignore_path)
        // 判断是否以指定路径开头
        var pathIndex = ctx.input[0].indexOf(img_ignore_path)
        if (pathIndex != 0) {
          throw new Error('图片路径不以对应忽略路径开头!')
        }

        var pathIndex = process.env.MKD_FILE_PATH.indexOf(mkd_ignore_path)
        if (pathIndex != 0) {
          throw new Error('Markdown笔记路径不以对应忽略路径开头!')
        }

        var prefix = process.env.MKD_FILE_PATH.slice(mkd_ignore_path.length + 1, -3) + "/"
        ctx.log.info('prefix: ' + prefix)
        // 添加前缀
        for (var i = 0; i < ctx.output.length; i++) {
          ctx.output[i].fileName = prefix + ctx.output[i].fileName
        }
      },
      config
    })
  }
  return {
    register,
    config
  }
}

这里使用的是JavaScript语言,内容不复杂,就是基本的字符串处理,不清楚的语法百度下就好了。

配置项有2个:

  • 笔记父路径:所有笔记都放到了同一个父目录下,然后再分子目录存笔记,如父目录为/Users/username/Summary,笔记目录为/Users/username/Summary/Java/语法/基础语法.md
  • 图片父路径:通过前面的设置,所有图片都放到了同一父目录下,将这个目录配到Picgo插件中。

主要逻辑在43-66行:

  • 获取配置项,若发现有空值,通过throw new Error命令抛出错误,中断图片上传
  • ctx.input是个数组,存放了所有待上传图片的绝对路径。这里只是判断一下,传入的图片是否与设置中的父路径一致,不是则抛错;
  • process.env.MKD_FILE_PATH是取环境变量MKD_FILE_PATH的值,这是个客制化的变量,存放的笔记名全路径,下文会介绍怎么设置。
    将该变量去掉配置中的笔记父路径后,拼上"/"作为图片名前缀,也就是图片的目录了;
  • 最后遍历数组ctx.output,这里存的是所有图片名,不包含路径。我们对其每个值增加上一步生成的前缀。

配置

插件的配置很简单:

  • 客户端版:在插件设置中,点击对应插件右下角的齿轮,选择配置就行了
  • 命令行版:终端运行picgo set plugin folder-name

Typora设置:

image-20230103132447070

客制化命令:upload.sh ${filepath}

${filepath}是Markdown笔记文件的全路径,upload.sh是自定义的脚本:

export MKD_FILE_PATH=${@:1:1} #获取Markdown文件全路径
/usr/local/bin/node /usr/local/bin/picgo upload ${@:2} #上传图片

因为我想用Markdown笔记的路径作为图片分类目录,而picgo插件的上下文ctx没有笔记路径,所以就在调用picgo命令前,通过客制化脚本设置一个环境变量MKD_FILE_PATH,值就是Markdown笔记文件的全路径。
在前面介绍插件源码index.js时,提到了这个变量,就是在此处赋值的。

本人用的是Mac OS,Windows的命令不熟悉,此处未放置Windows版本脚本。

若是有园友做了Windows版本的,可以下方留言你的文章链接,到时我把链接放这里!

使用

好啦,到此为止,我们的功能就实现啦!想要用一个文件测试的话,就找个笔记中的图片,右键上传:

image-20230103133334060

如果有问题,可以查看Picgo日志,与Picgo配置文件在同一目录。

附上本文中图片批量上传至阿里云的实例:

  • 笔记路径:
    image-20230103134256238
  • 本地图片路径:
    image-20230103135405191
  • 插件设置:
    image-20230103135548522
  • Picgo上传图片日志
    image-20230103134615852
  • 阿里云存储
    image-20230103134842021

总结

感谢读到最后,怎么样,其实是不是很简单?

不过还有一个缺陷,就是Markdown笔记的目录名、文件名一旦变更,再上传的新图片,会放到图床的另一目录下,同一个笔记的图片就会存到多个目录去了。不过,能做到当前这样,也挺不错了!

大家要是有自己的想法或需求,插件又不能实现的,可以试试文中的思路,自己搞一个出来,源码里多用ctx.log.info打日志测试哦。

通过自己的手,实现自己所想,这难道不是一名技术人员的幸福么,哈哈哈!

posted @ 2023-01-03 14:04  水木夏  阅读(143)  评论(0编辑  收藏  举报