InkdropのノートをAstroサイトに簡単に同期する方法

live-exportというノートをProgrammaticallyに出力するツールを作りました

Takuya Matsuyama
週休7日で働きたい

--

こんにちは、Inkdrop作者のTAKUYAです。

僕はMarkdownのシンタックス拡張を必要とするような機能要望にノーと言い続けてきました。なぜならInkdropは ‘Markdown’のノートアプリであり、その普及率の高さによる利用可能性を最大限に活かせるように作っているからです。例えば、Markdownは多くの静的サイトジェネレータで広く採用されています。Astro、Gatsby、Jekyll、Hugoなどなど。御存知の通り、既に多くの人がMarkdownでブログ記事を書いています(より厳密にはGitHub-flavored Markdown)。つまり、それは技術ノートだけでなく技術記事の投稿にも適しているのです。

Inkdropはプラットフォームとデバイスをまたいでシームレスな体験を提供します。それによりどこでもMarkdownを閲覧・執筆できます。しかしながら、その同期機能のためにファイルシステムとの親和性を犠牲にしました。それがInkdropからブログ記事を投稿する妨げになっていました — — これまでは。ここで、live-exportをご紹介します。これは、ローカルのファイルシステムにProgrammaticallyにノートをエクスポートできるツールです。以下、詳しく説明していきます。

柔軟にファイルシステムで作業するための方法

なぜlive-exportが必要なのでしょうか?Inkdropはノートをメニューからエクスポートする機能を既に持っています。しかし、メタデータに従ってファイル名のフォーマットやディレクトリ構造、どのノートを出力するか否かなどを自由に決められません。live-exportは柔軟なAPIを提供することでその問題を解決します。更に、名前の通り、これはInkdrop内で変更がある度に ‘continuously(継続的)’ に出力します。それは、結果をブラウザで確認しながら記事が書けるということです。このように:

Live export demo

なかなか便利ではないでしょうか。今回に向けて、デモも用意しました。こちらは、Astroで構築した僕のブログです:

ソースコードはこちらにあります:

いい感じでしょう :) 英語ですがYouTubeにチュートリアルもあります:

データやデザイン、デプロイ先まで全てコントロール可能

どのように動作するのでしょうか。live-exportはInkdrop内部で動くプラグインではありません。ターミナル上で別個に動作し、ローカルInkdropサーバ経由でノートのデータにアクセスします。

こちらがノートブックからノートをインポートするコードの例です:

import { LiveExporter, toKebabCase } from '@inkdropapp/live-export'const liveExport = new LiveExporter({
username: 'foo',
password: 'bar',
port: 19840
})
const sub = await liveExport.start({
live: true,
bookId: '<YOUR_BOOK_ID>',
// Pre-process the specified note. It is useful to update the frontmatter information based on the note metadata
preProcessNote: ({ note, frontmatter, tags }) => {
frontmatter.title = note.title
// Convert note title to kebab case (eg. "kebab-case-note-title")
frontmatter.slug = toKebabCase(note.title)
frontmatter.tags = tags.map(t => t.name)
},
// Generate a path to export the specified note
pathForNote: ({ /* note, */ frontmatter }) => {
// export only if it's public
if (frontmatter.public) {
return `./<PATH_TO_EXPORT_NOTES>/${frontmatter.slug}.md`
} else return false
},
// Generate a URL for the specified note. It is necessary to link from the note to another note
urlForNote: ({ frontmatter }) => {
if (frontmatter.public) {
return `/<URL_TO_LINK_NOTES>/${frontmatter.slug}`
} else return false
},
// Generate a path and URL to export the specified image file
pathForFile: ({ mdastNode, /* note, file, */ extension, frontmatter }) => {
if (frontmatter.slug && mdastNode.alt) {
const fn = `${frontmatter.slug}_${toKebabCase(
mdastNode.alt
)}${extension}`
const res = {
filePath: `./<PATH_TO_EXPORT_IMAGES>/${fn}`,
url: `./<URL_TO_LINK_IMAGES>/${fn}`
}
// If the `alt` attribute of the image is 'thumbnail', use it as a hero image
if (mdastNode.alt === 'thumbnail') {
frontmatter.heroImage = res.filePath
}
return res
} else return false
},
// Post-process the specified note right before writing the note to a file. It is useful to tweak the Markdown data
postProcessNote: ({ md }) => {
// Remove the thumbnail image from the Markdown body
const md2 = md.replace(/\!\[thumbnail\]\(.*\)\n/, '')
return md2
}
})

ご覧の通り、live-exportはツール非依存であり、基本的にどの静的サイトジェネレータとも動作します。データからディレクトリ構造、サイトのデザイン、どこにデプロイするかも自由自在です。仮にInkdropを使うのをやめてしまっても、ブログ記事はgitリポジトリの中に存在し続けます。ノー・ロックインです。

テンプレートからブログを作成する

使用方法について学んでいきましょう。先述の通り、live-exportはローカルのInkdropサーバ経由でデータにアクセスします。まずはそれを有効化します。ユーザデータディレクトリにある config.cson を編集します。

  • macOS: ~/Library/Application Support/inkdrop/config.cson
  • Windows: %APPDATA%\inkdrop\config.cson
  • Linux(deb/rpm): ~/.config/inkdrop/config.cson
  • Linux(Snap): ~/snap/inkdrop/current/.config/inkdrop/config.cson

Inkdropを終了し、以下の行を追記します:

"*":
core:
server:
enabled: true
port: 19840
bindAddress: "127.0.0.1"
auth:
username: "foo"
password: "bar"

そしてアプリを再起動します。以下のコマンドを実行すれば、サーバが正しく動いていることを確認できます:

curl http://foo:bar@localhost:19840/
# => {"version":"5.5.1","ok":true}

これでlive-exportを使う準備が整いました!ブログをすぐに作れるようにテンプレートを用意しました:

このテンプレートはAstroで組まれています。Astroは静的サイトジェネレータの一つで、スピードに特化しています:

テンプレートをあなたのディレクトリにcloneします:

git clone git@github.com:inkdropapp/inkdrop-blog-template.git ./your-blog
cd ./your-blog

次に依存モジュールをインストールします:

npm install
# Or, yarn install

そして、以下のような.env ファイルをプロジェクトのルートに作成してください:

DEBUG='inkdrop:export:info,inkdrop:export:error'
INKDROP_USERNAME='foo'
INKDROP_PASSWORD='bar'
INKDROP_PORT=19840
INKDROP_BOOKID='<BOOKID>'

ここで、出力したいノートブックのIDが必要になります。このIDを簡単に取得するには、dev-toolsというプラグインをインストールします。Preferences → Plugins/Installの画面からインストールしてください。

Install dev-tools

インストールできたら、早速目的のノートブックを右クリックして「Copy Notebook ID」を選択してください:

Copy a notebook ID

.env ファイルに戻り、コピーしたノートブックIDを貼り付けます。

DEBUG='inkdrop:export:info,inkdrop:export:error'
INKDROP_USERNAME='foo'
INKDROP_PASSWORD='bar'
INKDROP_PORT=19840
INKDROP_BOOKID='book:r8KUw7SBx'

よし、ではAstroのdev serverを立てましょう。

npm run start

ブログがhttp://localhost:3000/ で走っているはずです:

Dev server

ではブログ用ノートブックに新規ノートを作成しましょう。

Example post

ここで、ノートがYAML frontmatterという —--ブロックで始まっている事に注目してください:

---
public: true
---

public: true をそこで指定することで、live-exportはそのノートがエクスポート対象であると認識します。ではlive-exportを別のターミナルで実行しましょう:

npm run live-import> inkdrop-blog-template@0.0.1 live-import
> node --experimental-vm-modules tools/import.mjs
(node:59628) ExperimentalWarning: The Fetch API is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
inkdrop:export:info Exporting note: note:_F3VsSEhJ Convert mp4 to webm +0ms
inkdrop:export:info Watching changes.. +6ms

するとノートがファイルにインポートされ、以下のように新しい記事が見えるようになったはずです:

記事をクリックします:

live-exportが走っている間は、ほぼリアルタイムにInkdrop側の変更がブログ側に反映され続けます。

添付画像にも対応しています。一つ画像ファイルをノートに追加してみましょう。

---
public: true
---
![rocket](inkdrop://file:3Z5LUBZk5)```sh
ffmpeg -i masthead-bg.mp4 -c:v libvpx-vp9 -crf 30 -b:v 0 -b:a 128k -c:a libopus masthead-bg.webm
```

すると、画像ファイルは <PROJECT_ROOT>/public/posts/配下に出力され、ブログ側にも画像が現れたはずです。しかし記事一覧にはまだ出てきません。この画像を記事のサムネイルとして使用したいですね。その場合は、画像のalt部分を “thumbnail” に変更します:

![thumbnail](inkdrop://file:3Z5LUBZk5)

すると、記事一覧にも画像が現れました!

次にノートにタグを追加してみましょう。ブログはノートに付与されたタグを自動で検出してページを生成してくれます。

ノートにタグを追加すると、タグ一覧ページ http://localhost:3000/tags にそれが現れたはずです。

もしタグが見えない場合は、live-exportを再実行してみてください。これであなたのブログを執筆する準備ができました。もちろん、ナビゲーションバーのロゴやタイトル、配色など全てあなたの好きにカスタマイズ可能です。エンジョーイ!

以下はいくつか想定されるFAQです。

どこに私のブログをデプロイすれば良いですか?

Astroのドキュメンテーションに詳しいガイドが記載されています。

ローカルサーバのアクセスログはどうやったら見れますか?

Inkdropを --enable-logging フラグを付加して実行してください。詳しくはドキュメンテーションを参照ください。

ノートをInkdropにインポートして戻せますか?

いいえ。live-exportはあなたのプロジェクトに合わせてノートを変形させます。よってInkdropとの互換性が失われます。

以上です。Inkdropでのブログ公開を楽しんでください :D いつもInkdropのサポートありがとうございます。

Follow me online

--

--