Jekyll + VSCode でいい感じの執筆環境を構築する

最近、このブログに書くほどでもないような日々の進捗を記録する用に、静的サイトジェネレータ Jekyll を利用して GitHub Pages を立ち上げた。導入は こちら を参照するのがよいとして、ここでは毎日の投稿を容易にする工夫を述べていく。環境は WSL (Ubuntu 18.04.4) である。

実現したいこと

新しいブログポストを投稿する場合、posts_ ディレクトリに まず YYYY-MM-DD-NAME-OF-POST.md という名前の Markdown ファイルを準備し、さらにそのファイル先頭に

layout: post
title: "POST TITLE"
date: YYYY-MM-DD hh:mm:ss +0900
categories: diary

という YAML frontmatter を追加しなくてはならない。title はその日の日付、つまり YYYY-MM-DD でよいので、ここまでの作業をすべて自動化したい。

拡張機能の導入

jekyll-post という拡張機能を用いれば、上記を多少簡略化することができる。新規投稿作成手順は以下の通り。

これを行うだけで、以下の YAML frontmatter を持った 2020-09-08-new-post.md というファイルが posts_ ディレクトリに生成される。

---
layout: post
title: 
date: 2020-09-08 10:27
category: 
author: 
tags: []
summary: 
---

上記の気に入らない点

  • タイトルはその日の日付だし、category も diary に決まっているので、その辺を自動入力してほしい
  • デフォルトの new-post.md という名前が気に入らない。dairy.md とかがいい
  • もっといえば拡張子は .mdに決まっているのだから、diary を入力するだけで勝手に .md を付けたファイルを生成してほしい
  • 投稿は # Progress という文字列で始めることに決めているので、それも自動入力してほしい
  • わざわざエクスプローラを開いて posts_ ディレクトリを右クリックするのがダルい。どうせ posts_ ディレクトリにしか作らないので、ショートカット一発で新規ファイル作成できるようにしてほしい

この拡張機能で生成される YAML frontmatter はルートディレクトリに .post-template をいうファイルを作成することによってある程度のカスタマイズが可能だが、さすがに上記のわがまま全てに応えきれるものではないのでここでは拡張機能のソース (/home/ubuntu/.vscode-server/extensions/rohgarg.jekyll-post-0.0.1/ 内のファイル) を直接弄ることにした。

VSCode での設定

Utils.js

  • デフォルトのテンプレを変えるため、14 行目のテンプレを以下のように置換する。TITLE というのはあとで日付文字列に変換する (後述)。
exports.postSnippet = `---
layout: post
title: TITLE
date: YYYY
category: diary
---

# Progress`;
  • デフォルトのファイル名を変更し、さらに .md をつけなくてよいように getFileNameFromUser() を変更する。
function getFileNameFromUser() {
    return __awaiter(this, void 0, void 0, function* () {
        const defaultFileName = "diary";
        let question = `What's the name of the new post?`;
        let filePath = yield vscode.window.showInputBox({
            prompt: question,
            value: defaultFileName,
        });
        if (filePath === null || filePath === undefined) {
            return undefined;
        }
        filePath += ".md";
        return filePath || defaultFileName;
    });
}
  • タイトル用日付を出力する関数を追記する。
function getFormattedDate() {
    var today = new Date();
    var dd = String(today.getDate()).padStart(2, '0');
    var mm = String(today.getMonth() + 1).padStart(2, '0');
    var yyyy = today.getFullYear();
    return yyyy + '-' + mm + '-' + dd;
}
exports.getFormattedDate = getFormattedDate;

Extension.js

  • activate() を書き換える。常に決まったディレクトリにファイルを作成するため dirName を変更し、さらにさきほど仮置きした TITLE を置換する処理を加える。
function activate(context) {
    let disposable = vscode.commands.registerCommand('extension.jekyllPost', (uri) => __awaiter(this, void 0, void 0, function* () {
        const dirName = '/mnt/c/Users/aiwas/Dropbox/diary/_posts/';
        let filename = yield utils_1.getFileNameFromUser();
        if (filename === undefined) {
            return;
        }
        const userFilePath = utils_1.addDateToFilename(filename);
        try {
            let editor = yield utils_1.openFile(yield utils_1.createFile(dirName, userFilePath));
            // Insert snippet only if the user did not provide a template file and
            // a new post file had to be created
            if (utils_1.shouldInsertFrontMatter()) {
                const snippetStr = utils_1.postSnippet.replace('YYYY', utils_1.getDateTime()).replace('TITLE', utils_1.getFormattedDate());
                editor.insertSnippet(new vscode.SnippetString(snippetStr));
                utils_1.setFrontMatter(false);
            }
        }
        catch (err) {
            vscode.window.showErrorMessage(err);
        }
    }));
    context.subscriptions.push(disposable);
}

上記の作業が終わったら VSCode を再起動する。

  • 最後に、keybings.json でお気に入りのショートカットを設定すればおしまい。
{
    "key": "ctrl+j ctrl+k",
    "command": "extension.jekyllPost"
}

実現できた動作

ルートディレクトリを開いた状態で ctrl+j ctrl+k とすると、ファイル名の入力を促すプロンプトが表示される。

f:id:I-was-a-Ki:20200908181026p:plain

ここでそのまま Enter を押下すると、以下のような新規ファイルが _posts ディレクトリに作成される。やったね!

f:id:I-was-a-Ki:20200908180957p:plain