MakefileでZennCLIを対話型っぽく使う
はじめに
最近Zennの執筆モチベが高いので、GitHub連携とZennCLIを利用してローカルで記事を書けるようにセットアップしました。
以前からGitHub連携をすればVSCodeで記事を書けることはぼんやり知りつつも、ブラウザでも書けるしなあと設定をサボっていましたが、プレビューを見ながら記事を書けたほうが楽だなと思って今回設定しました。
公式の記事でちゃんと説明されており、特に難しいことはなく設定できたのでまだ設定されていない方はぜひ設定してみてください!
下記のようにPreviewを見ながら執筆できます。
今回やりたいこと
今回ZennCLIを利用し始めた際にSLUGの文字数を12文字以上にする必要があるのを見落としており、何度か弾かれてしまいました。また、記事を作成するのか本を作成するのかもZennCLIのコマンドで入力するためコマンドオプションの書き方を覚える必要があり、対話型で入力できたらと思いMakefileを書きました。(GPTが)
やり方
使い方はZennに連携しているリポジトリのルートディレクトリにMakefileを作成し、そのMakefileに下記をコピペしてください!(少し長いので折りたたんでいます。)
Makefile
.PHONY: new
new:
@/bin/bash -c 'echo "Select the type of content ([a]/article for article, b/book for book, default is article): "; \
read TYPE; \
if [[ -z $$TYPE ]] || [[ $$TYPE == "a" ]] || [[ $$TYPE == "article" ]]; then \
TYPE="article"; \
elif [[ $$TYPE == "b" ]] || [[ $$TYPE == "book" ]]; then \
TYPE="book"; \
else \
TYPE="article"; \
fi; \
echo "Selected type: $$TYPE"; \
while true; do \
echo -n "Enter slug for the new $$TYPE (12〜50 characters, a-z, 0-9, -, _): "; \
read -e SLUG; \
if [[ $$SLUG =~ ^[a-zA-Z0-9_-]{12,50}$$ ]]; then \
if [[ $$TYPE == "article" ]] && { [ -f "articles/$$SLUG.md" ] || [ -d "books/$$SLUG" ]; }; then \
echo "An article or book with that slug already exists. Please try a different slug."; \
elif [[ $$TYPE == "book" ]] && { [ -d "books/$$SLUG" ] || [ -f "articles/$$SLUG.md" ]; }; then \
echo "A book or article with that slug already exists. Please try a different slug."; \
else \
break; \
fi; \
else \
echo "Invalid slug. It must be 12〜50 characters, a-z, 0-9, -, _. Try again."; \
fi; \
done; \
if [[ $$TYPE == "article" ]]; then \
npx zenn new:article --slug $$SLUG; \
elif [[ $$TYPE == "book" ]]; then \
npx zenn new:book --slug $$SLUG; \
fi'
Makefileを置いたら、make newコマンドをターミナルに打つだけで対話型で記事や本を作成できます。
make newをすると記事タイプを聞かれます。
記事ならaかarticle、本ならbかbookと入力します。また、記事の方が作成機会が多いと思うので何も入力せずにEnterを押したら記事が選ばれます。
次にslugを聞かれます。
今回はsample-zenn-articleとしました。
またこのMakefileを利用することで、slugの入力で失敗した場合に再入力できるようになっています。例えば、下記の2通りだと記事の作成が失敗します。
・Slugのルール(12〜50 characters, a-z, 0-9, -, _)に従っていない。
・すでに存在するSlugとかぶっている。
このような場合は再度入力ができます。
Ctrl+Cで途中でも抜けることができます。
おまけ
previewもMakefileから実行できたら嬉しいのでやってみます。
まずpreview.shを用意します。
#!/bin/bash
npx zenn preview
make fileの一行目を.PHONY: new preview
に変更し、
末尾の行に下記を追加することで make previewでpreviewを開けるようにもなります。
preview:
./preview.sh
make preview
./preview.sh
(node:11102) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
👀 Preview: http://localhost:8000
最初はシェルスクリプトを介さずに直接ZennCLIのpreviewコマンドを叩いていましたが、変更の自動反映がされなくなってしまったので、シェルスクリプトを介してpreviewを呼ぶようにしています。
最終的なMakefileはこんな感じ
.PHONY: new preview
new:
@/bin/bash -c 'echo "Select the type of content ([a]/article for article, b/book for book, default is article): "; \
read TYPE; \
if [[ -z $$TYPE ]] || [[ $$TYPE == "a" ]] || [[ $$TYPE == "article" ]]; then \
TYPE="article"; \
elif [[ $$TYPE == "b" ]] || [[ $$TYPE == "book" ]]; then \
TYPE="book"; \
else \
TYPE="article"; \
fi; \
echo "Selected type: $$TYPE"; \
while true; do \
echo -n "Enter slug for the new $$TYPE (12〜50 characters, a-z, 0-9, -, _): "; \
read -e SLUG; \
if [[ $$SLUG =~ ^[a-zA-Z0-9_-]{12,50}$$ ]]; then \
if [[ $$TYPE == "article" ]] && { [ -f "articles/$$SLUG.md" ] || [ -d "books/$$SLUG" ]; }; then \
echo "An article or book with that slug already exists. Please try a different slug."; \
elif [[ $$TYPE == "book" ]] && { [ -d "books/$$SLUG" ] || [ -f "articles/$$SLUG.md" ]; }; then \
echo "A book or article with that slug already exists. Please try a different slug."; \
else \
break; \
fi; \
else \
echo "Invalid slug. It must be 12〜50 characters, a-z, 0-9, -, _. Try again."; \
fi; \
done; \
if [[ $$TYPE == "article" ]]; then \
npx zenn new:article --slug $$SLUG; \
elif [[ $$TYPE == "book" ]]; then \
npx zenn new:book --slug $$SLUG; \
fi'
preview:
./preview.sh
おわりに
今回はZennCLIをより使いやすくするMakefileを書きました。こんなに執筆体験の良いサービスを開発してくださったcatnoseさんと運営してくださっているクラスメソッドさんには感謝しても仕切れないですね。
2024年は技術発信も頑張ろうと思っているので、記事が参考になった方はいいねとフォローをしていただけると励みになります!GitHubのフォローも!
よろしくお願いします!
Discussion