rehype プラグイン

@love-rox/tcy-rehype

`unified` の HAST パイプラインに組み込んで、build 時に縦中横を適用する rehype プラグイン。Markdown / MDX / 静的 HTML — どこでも、クライアントランタイムなしで動きます。

v0.3.0MITbuild-time

インストール

@love-rox/tcy-core は依存として自動的に引き込まれます。unified ベースのビルド(remark / rehype / Astro / eleventy など)で使えます。Astro 専用に最適化された API が必要な場合は [Astro 版](./astro) を使ってください。

bun

bun add @love-rox/tcy-rehype

pnpm

pnpm add @love-rox/tcy-rehype

npm

npm i @love-rox/tcy-rehype

yarn

yarn add @love-rox/tcy-rehype

Markdown パイプラインに組み込む

remark-rehype のあと、HAST が確定したタイミングで rehypeTcy を挟むだけです。HTML として出力される時点で、縦中横ラッピングは済んでいます。

Markdown → HTMLts
import { unified } from "unified";
import remarkParse from "remark-parse";
import remarkRehype from "remark-rehype";
import rehypeStringify from "rehype-stringify";
import rehypeTcy from "@love-rox/tcy-rehype";

const html = String(
  await unified()
    .use(remarkParse)
    .use(remarkRehype)
    .use(rehypeTcy)
    .use(rehypeStringify)
    .process("第1章 2026年4月"),
);
// <p>第<span class="tcy">1</span>章 <span class="tcy">2026</span>年<span class="tcy">4</span>月</p>

HTML だけのパイプライン

Markdown を介さず、HTML in / HTML out なら同じ要領で:

HTML → HTMLts
import { unified } from "unified";
import rehypeParse from "rehype-parse";
import rehypeStringify from "rehype-stringify";
import rehypeTcy from "@love-rox/tcy-rehype";

const html = String(
  await unified()
    .use(rehypeParse, { fragment: true })
    .use(rehypeTcy)
    .use(rehypeStringify)
    .process("<p>第1章 2026年4月</p>"),
);

オプション

共通オプション(target / combine / include / exclude / maxLength / excludeWords)はすべて React / Vue / Astro と同じ意味で動きます。

共通オプション

オプション既定値説明
target'alphanumeric' | 'alpha' | 'digit' | 'ascii' | RegExp'alphanumeric'縦中横対象として扱う文字種。alphanumeric[0-9A-Za-z]ascii は印字可能な ASCII 全般。任意の RegExp も指定可能。
combinebooleantrue連続した対象文字を1つのスパンにまとめるか。false にすると1文字ずつ別々のスパンで包みます。
includestring | string[]undefinedtarget に含まれなくても対象として扱う追加の文字。
excludestring | string[]undefined対象から外したい文字。include より優先されます。
maxLengthnumberundefined縦中横セグメントの最大文字数。これを超える長さの英数字 run はプレーンテキストに戻ります。たとえば maxLength: 2 にすると 2026 のような4桁年は寝かせ、119 の短い run のみを縦中横にできます。
excludeWordsstring[]undefined縦中横にしたくない語を完全一致で指定(部分一致ではなくセグメント値全体のマッチ)。URL API のような固有の略号や、特定の年号だけを横倒しのまま残したいときに便利。

rehype プラグイン専用オプション

オプション既定値説明
tagNamestring'span'ラップに使用するタグ名。
classNamestring | string[]'tcy'ラップ要素に付与するクラス名(配列で複数指定可)。
skipTagsstring[]['code', 'pre', 'script', 'style']走査をスキップするタグ。<code> <pre> などコード表示中のテキストはデフォルトで処理されません。

挙動の注記

  • 冪等です。同じ HAST に2回プラグインを適用しても、出力は1回適用したときと同じ。span が二重になったりはしません。
  • skipTags のデフォルト(code / pre / script / style)が、コードサンプルや埋め込み JSON が縦中横化されるのを防ぎます。
  • <em>12</em>34 のように要素境界をまたぐ文字列は連結されず、別々のスパンになります。
  • maxLength / excludeWords で対象外になった run はプレーンテキストに戻り、隣接するテキストと自動的にマージされます。

Astro を使っているなら

Astro 4+ で .md / .mdx / .astro を扱うなら、Markdown パイプラインへの登録と <Tcy> コンポーネントが同梱された [Astro インテグレーション](./astro) のほうが手数が少なく済みます。