remark-directive で textDirective 誤変換を戻す Astro プラグイン

Astro で remark-directive を使うと 18:30 のような時刻表記が誤って textDirective に変換されてしまうため、戻すプラグインを作った。

環境

  • astro: 5.16.6
  • remark-directive: 4.0.0
  • mdast-util-directive: 3.1.0
  • unist-util-visit: 5.0.0
  • @types/mdast: 4.0.4
  • typescript: 5.9.3

内容

remark-directive とは

remark plugin to support the generic directives proposal (:cite[smith04], ::youtube[Video of a cat in a box]{v=01ab2cd3efg}, and such).

というプラグインである。
このプラグイン中で :cite[smith04] という形式は textDirective として扱われる。

しかし、そのせいで 3/2 18:30 のように日時を書いたら :30 部分が textDirective として扱われてしまうことに気づいた。
これは面倒すぎるので、ホワイトリストで管理するプラグインを作った。

/// <reference types="mdast-util-directive" />

import { visit } from "unist-util-visit";
import type { Root, Text } from "mdast";

interface Options {
  allowedNames?: string[];
}

export default function remarkRevertTextDirective(options?: Options) {
  const allowedNames = options?.allowedNames ?? [];
  return function (tree: Root) {
    visit(tree, "textDirective", (node, index, parent) => {
      if (allowedNames.includes(node.name)) return;
      if (index === undefined || !parent) return;

      const textNode: Text = {
        type: "text",
        value: `:${node.name}`,
      };

      parent.children.splice(index, 1, textNode);
    });
  };
}

これを astro.config.js で remarkDirective の後に読み込めば、明示的に指定した name を持つ textDirective 以外は元のテキストに戻してくれる。

以上