前言

之前尝试使用过不少笔记工具,例如 macOS 的 Bear,界面很好看,付费后同步数据的功能也挺实用,然鹅不支持全平台。

还有 Windows 上的 EverNote,插件优化都不错,不过存储容量堪忧,而且后期迁移成本过高。

新兴的 Notion 以 Block 和创意吸引了我,一开始使用起来兴趣满满,为此捣鼓了一个 Notion-blog,不过后面愈发慢的启动速度以及臃肿的关系,慢慢搁置了。

以上使用体验各有千秋,不过因为数据上传云端的关系,总有一种隐隐的不安全感。

直到接触开源的 Joplin,可以加密并上传到自建数据库,甚至可以借助 Joplin Utils 实现数据交互。

目前我自己搭建的 Blog 就是在 Joplin 记录,使用 mami 转换并输出 Vuepress。 记得当时无法做到自定义 meta 数据,求助琉璃才实现的自定义数据。 这次变更太棒了。

mami

mami 是一个转换工具,可以连接不同的基于 markdown 的框架和工具,可以将一个工具的数据转换到另一个工具,对于跨应用迁移和多平台发布非常有帮助,目前支持joplin/obsidian/hexo/hugo/docsify/vuepress/raw。

安装方法

yarn add -D @mami/cli @mami/plugin-joplin @mami/plugin-local typescript

package.json 文件中新增命令:

{
  ...
  "scripts": {
    "gen": "mami"
  },
  ...
}

举个栗子

创建 mami.config.ts 文件

import { defineConfig, OutputPlugin } from "@mami/cli";
import * as joplin from "@mami/plugin-joplin";
import { token } from "./.joplin-blog.json";
import * as local from "@mami/plugin-local";
import { PageFrontmatter } from "vuepress-vite";
import path from "path";

export default defineConfig({
  input: [
    joplin.input({
      baseUrl: "http://127.0.0.1:41184",
      token: token,
      tag: "blog",
    }),
  ],
  output: [
    output({
      root: path.resolve(__dirname, "./blog"),
    }),
  ],
});

/**
 * 新增meta,输出文本
 * @param options 
 * @returns 
 */
function output(options?: { root?: string }): OutputPlugin {
  const root = options?.root ?? path.resolve("docs");
  const postsPath = path.resolve(root, "p");
  const resourcePath = path.resolve(root, "resources");
  const p = local.output({
    rootNotePath: postsPath,
    rootResourcePath: resourcePath,
    meta: (item) =>
      ({
        layout: "Post",
        author: "Kilien",
        subtitle: item.id,
        useHeaderImage: true,
        headerImage: `https://picsum.photos/seed/${item.id}/1920/1080`,
        headerMask: `rgb(14, 21, 5, 0.2)`,
        tags: [...item.tags.map((item) => item.title)],
        permalink: `/p/${item.id}`,
        title: item.title,
        date: new Date(item.createAt).toISOString().slice(0, 10),
        updated: new Date(item.updateAt).toISOString().slice(0, 10),
      } as PageFrontmatter),
    noteLink: ({ linkNoteId }) => `/p/${linkNoteId}`,
    resourceLink: ({ resource }) =>
      `../resources/${resource.id}${path.extname(resource.title)}`,
    notePath: (note) => path.resolve(postsPath, note.id + ".md"),
    resourcePath: (resource) =>
      path.resolve(resourcePath, resource.id + path.extname(resource.title)),
  });
  p.name = "vuepress";
  return {
    ...p,
    async handle(note) {
      await p.handle(note);
    },
    async end() {
      await p.end?.();
    },
  };
}

上面所需的 Token 来自 web clipper 插件

在命令行输入 yarn gen 就可以把 Joplin 上文件转换为需要的 Vuepress 文件了。接着就可以使用 Vuepress 愉快的玩耍了。

Last Updated: