🐺

fmext という frontmatter を解析するツールを作成した話

に公開

はじめに

markdownファイルのfrontmatterを解析し、topic毎にまとめてシュッと探せるようにしたくなりCLIツールを作成しました。

Zennやその他のマークダウンベースのCMSを使っていると、記事数が増えてくると特定のトピックやタグを持つ記事を見つけるのが大変になってきます。
そんな時に、frontmatterを効率的に解析し、確認したい内容に絞り込みができるようなツールを目指して開発しました。

モチベーション

私がこのツールを作成した背景としては、markdownファイルのfrontmatterを解析し、topic毎にまとめて素早く探せるようにしたいという思いからでした。

特に以下のような場面で困っていました:

  • 大量のマークダウンファイルから特定のトピックを含む記事を見つけたい
  • frontmatterの内容を一覧で確認したい
  • 特定のキーや値でフィルタリングしたい
  • 統計情報(カウント)を取得したい

作成したCLI

作成したツールは以下のリポジトリで公開しています。

https://github.com/Pianoopera/fmext

https://www.npmjs.com/package/fmext

DenoとTypeScriptで実装しております。

機能

fmextは以下のオプションでfrontmatterを解析できます

Usage: fmext [files...]

Description:

  Front matter extraction tool

Options:

  -h, --help              - Show this help.             
  -c, --count             - Count mode                  
  -k, --key     <key>     - Extract specific key        
  -v, --value   <value>   - Filter by value             
  -f, --filter  <filter>  - Filter by key=value format  

Commands:

  help     - Show help             
  version  - Show version          
  alias    - Manage command aliases

主な機能

  1. 基本的な解析機能: マークダウンファイルのfrontmatterを解析し、JSON形式で出力
  2. 特定キーの抽出: -kオプションで特定のキーのみを抽出
  3. 値によるフィルタリング: -vオプションで特定の値を持つ項目のみを抽出
  4. キー=値でのフィルタリング:
    -fオプションでkey=value形式での詳細フィルタリング
  5. カウント機能: -cオプションで統計情報を取得

使用例と出力例

基本的な使用方法

# 単一ファイルの解析
fmext tests/fixtures/test1.md

# 複数ファイルの解析
fmext tests/fixtures/test1.md tests/fixtures/test2.md

# ディレクトリ内の全てのマークダウンファイルを解析
fmext tests/fixtures/*.md

特定キーの抽出

# tagsキーのみを抽出
fmext -k tags tests/fixtures/test1.md

出力例:

[
  {
    "file": "tests/fixtures/test1.md",
    "output": [
      {
        "value": "markdown"
      },
      {
        "value": "yaml"
      },
      {
        "value": "test"
      }
    ]
  }
]

値によるフィルタリング

# "react"という値を持つ項目のみを抽出
fmext -k tags -v "react" tests/fixtures/*.md

複合的なフィルタリング

# 公開済みの記事の中から特定のタグを持つものを抽出
fmext -k tags -v "typescript" -f "status=published" tests/fixtures/*.md

カウント機能

ファイル内のfrontmatterで使用されるキーの出現回数をカウントする機能です。
※他のオプションと組み合わせて使用することも可能です。

# 統計情報を取得
fmext --count tests/fixtures/*.md
{
  "output": [
    {
      "key": "typescript",
      "value": 2
    },
    {
      "key": "web",
      "value": 2
    },
    {
      "key": "programming",
      "value": 4
    }
  ]
}

フィルタリング機能

frontmatterの特定のキーと値でフィルタリングする機能です。
-fもしくは--filterオプションを使用して、key=value形式で指定します。

# 特定のキーと値でフィルタリング
fmext -f "status=published" tests/fixtures/*.md

出力例(statuspublishedの記事のみを抽出):

[
  {
    "file": "tests/fixtures/test-1.md",
    "output": {
      "title": "React Tutorial",
      "author": "John Doe",
      "tags": [
        "react",
        "typescript",
        "web",
        "tutorial"
      ],
      "categories": [
        "programming",
        "frontend"
      ],
      "status": "published",
      "difficulty": "intermediate"
    }
  },
  {
    "file": "tests/fixtures/test-2.md",
    "output": {
      "title": "TypeScript Guide",
      "author": "Jane Smith",
      "tags": [
        "typescript",
        "javascript",
        "web"
      ],
      "categories": [
        "programming",
        "backend"
      ],
      "status": "published",
      "difficulty": "advanced"
    }
  }
]

alias機能

fmextでは、よく使うコマンドをエイリアスとして登録し、簡単に実行できる機能も提供しています。

# コマンドのエイリアスを設定
fmext alias --set myalias "-k:tags,-v:react"

# エイリアスの一覧を表示
fmext alias --list

# エイリアスを使用してコマンドを実行
fmext alias run myalias tests/fixtures/*.md

# エイリアスを削除
fmext alias --remove myalias

# 全てのエイリアスを削除
fmext alias --remove-all

実際の活用場面

このツールのユースケースは以下のような場面を想定しています。

1. 記事の分析

# 特定のトピックを持つ記事数を確認
fmext --count -k topics -v "react" articles/*.md

2. 公開状態の確認

# 未公開の記事を確認
fmext -f "published=false" articles/*.md

3. 執筆者別の記事数

# 作成者別の記事数を確認
fmext --count -k author articles/*.md

出力される値の整形について

出力される値はJSON文字列で出力されるため、必要に応じてjqなどのツールを使って整形することができます。

# 出力を整形して表示
fmext -k tags articles/*.md | jq '.[]'

まとめ

fmextは、markdownファイルのfrontmatterを効率的に解析するためのシンプルなCLIツールです。
日々の記事管理や分析作業において、手軽に使えるツールとして活用できています。

特に、複数のオプションを組み合わせることで、柔軟な条件での検索や統計情報の取得が可能になり、
大量のマークダウンファイルを扱う際の作業効率が向上しました。

同じような課題を抱えている方は、ぜひ試してみてください。

Discussion