Closed12

Zenn 記事の目次をターミナルでプレビュー

hankei6kmhankei6km

zenn-cli の記事プレビューには目次が表示されないので対応。

hankei6kmhankei6km

基本は CMS からデータを保存するスクリプト実行の段階でどうにかする。

対応案

  • nuxt-content の docs テーマ用にも変換させてプレビュー
  • 保存スクリプトで(ターミナル上)表示

docs テーマは以下の点でよくなさそう。

  • Zenn 独自の記法をサポートできない
  • 確認する画面(ウィンドウ)をこれ以上増やすのは避けたい

目次だけならターミナル上の表示でもよいかなと。

hankei6kmhankei6km

実装方法を考える。

見出しの抽出

grep でいけそうだが、以下の点で不具合がでそう。

  • FrontMatter にコメントがあった場合
  • コードブロックの中に # 形式のコメントがあった場合

本来なら gray-matter + remark あたりでやった方が確実。

今回は <h2> より深いものが対象なのでコメントに ## がなければ大丈夫そうか?

見出しから目次へ整形

sed で対応できると思う。

hankei6kmhankei6km

表示幅について

プレビューの範囲から外れそうだが、見出しが長すぎて「実環境での表示時に折り返される」状況になりそうなら警告出したい。

目次の項目が折り返されているスクリーンショット

厳密なチェックはできないが unicode の full-width とか考慮したらそれっぽくはできる?

本筋から外れるので余裕があれば対応。

hankei6kmhankei6km

テスト用のファイル

tmp/articles/test.md
---
id: native-esm-with-typescript-jest
title: TypeScript + Jest で native ESM
emoji: "\U0001F363"
type: tech
topics:
  - nodejs
  - npm
  - esm
  - typescript
  - jest
published: true
---

# head1

paragraph

## head2

paragraph

### head3

paragraph

#### head4

paragraph

## conclusion

paragraph
hankei6kmhankei6km

grep してみる。

grep
$ grep -e '^##\{1,2\} ' -- tmp/articles/test.md
## head2
### head3
## conclusion
hankei6kmhankei6km

sed で整形してみる。

sed
$ grep -e '^##\{1,2\} ' -- tmp/articles/native-esm-with-typescript-jest.md | sed -e 's/^## /+ /' -e 's/^### /| /'
+ モジュールの native ESM 対応
+ ts-jest の ESM 対応設定
+ Jest の native ESM 対応設定
+ native ESM での jest モックモジュール
+ VSCode 関連
| 構文チェック
| デバッグ
| コード補完と動的インポート
+ とりあえず

それっぽい表示なった。

hankei6kmhankei6km

やっつけでハイライト。

$ echo -e "\n=== 目次 ===\n" ; grep -e '^##\{1,2\} ' -- tmp/articles/native-esm-with-typescript-jest.md | sed -e 's/^## /'$(echo -e '\e[0m')'+ '$(echo -e '\e[1m')'/' -e 's/^### /'$(echo -e '\e[0m')'| '$(echo -e '\e[2m')'/'; echo

結果は以下のような感じ。判別しにくいのでもう少し色を考えた方がよい。

目次の階層でハイライトぽくしたスクリーンショット

まずはここまで。

hankei6kmhankei6km

表示幅のチェック対応

ブラウザー上の目次が折り返されるかは取得できないので、参考程度の値を取得。

Node.js だと string-width - npm で、 CLI だと wc --max-line-length でそれっぽい値が取得できるらしい。

emoji もとりあえずは大丈夫そう(いろいろ問題でるだろうけど)。

$ echo '👀 Preview:'| wc --max-line-length
11

今回は wc を使う方向で。

参考

hankei6kmhankei6km

だいたいできた。

toc.sh
#!/bin/bash
set -e

WARN_LEN="33"

COLOR_RESET='\e[0m'
COLOR_DEPTH2='\e[0m'
COLOR_DEPTH3='\e[2m'
COLOR_WARN='\e[33m'

grep -e '^\(##\|###\) ' -- | sed -e 's/^## /+ /' -e 's/^### /| /' | while read -r LINE
do
  HEADDING="${LINE::1}"
  TITLE="${LINE:2}"
  LEN="$(echo "${TITLE}" | wc --max-line-length)"

  # ヘッディング文字
  echo -n "${HEADDING} " 

  # 装飾
  if test "${LEN}" -gt "${WARN_LEN}" ; then
    echo -n -e "${COLOR_WARN}"
  elif test "${HEADDING}" = "+" ;then
    echo -n -e "${COLOR_DEPTH2}"
  else
    echo -n -e "${COLOR_DEPTH3}"
  fi

  # タイトル
  echo -n "${TITLE}"

  # 装飾リセット
  echo -n -e "${COLOR_RESET}"
  echo ""
done 
$ bash scripts/toc.sh < articles/native-esm-with-typescript-jest.md

スクリプトを実行して長いタイトルが警告色で表示されているスクリーンショット

長いタイトルに警告色が付くようになった。

hankei6kmhankei6km

保存スクリプトから実行できるようにもした。

とりあえずはこれで利用してみる予定。

CMS のコンテンツをローカルへ保存する時に目次をプレビューしているスクリーンショット

このスクラップは2021/12/27にクローズされました