← 一覧に戻る

著者: Roxチーム

tate-chu-yoko に Astro が加わりました - Markdown / MDX に自動縦中横を、設定1行で

tate-chu-yoko の5つ目のパッケージ @love-rox/tcy-astro を npm に公開しました ✨

5 パッケージは「shared version line」運用です。どれか一つでも変更があれば全部まとめて同じ番号に上がります。今回 Astro パッケージの追加にあわせて、5つ全部が 0.3.0 になりました。

なぜ Astro 専用パッケージを作ったか

前回 @love-rox/tcy-rehype を公開した記事 でも書いたとおり、rehype プラグインは「unified パイプラインを持っているなら、どこでも build 時に組版を済ませられる」という設計です。Astro は中で unified を使っているので、理屈の上では rehype を直接挿せば動きます。

ただ、実際にやってみると毎回同じセットアップを書くことになります:

  • astro.config.mjsmarkdown.rehypePlugins に追記
  • .mdx 用にも integrations: [mdx({ rehypePlugins: [...] })] を別途設定
  • .astro 直書きの本文には別の手段が必要(<Tcy> の代替がない)

5つ目のパッケージは、ここを「組み立てる必要のないもの」にする役割です。

astro.config.mjs に1行

import { defineConfig } from "astro/config";
import tcy from "@love-rox/tcy-astro";

export default defineConfig({
  integrations: [tcy()],
});

これだけで、.md.mdx の本文中の半角英数字 run が、ビルド時に <span class="tcy"> で包まれます。Astro 側の Markdown 構成と MDX 構成、両方を内部でフックします。

クライアントランタイムは0です。Astro が SSG でビルドした時点で HTML には縦中横ラッピングが既に入っているので、ページに React も Vue も載りません。

オプションは rehype と完全に同じ

integrations: [
  tcy({
    maxLength: 2,
    excludeWords: ["URL", "API", "2026"],
  }),
],

@love-rox/tcy-rehype に渡せるオプション(target / combine / include / exclude / maxLength / excludeWords / tagName / className / skipTags)はそのまま透過します。

インテグレーション専用のオプションは1つだけ:

  • markdown(既定値 true)— Markdown / MDX パイプラインへの登録を行うか。false にすると <Tcy> コンポーネントだけ使う構成にできます。

.astro 直書きにも <Tcy>

Markdown を介さずに .astro ファイルに直接本文を書くこともあります。そういうケース用にコンポーネントも同梱しています。

---
import Tcy from "@love-rox/tcy-astro/Tcy.astro";
---

<p style="writing-mode: vertical-rl">
  <Tcy>第1章 2026年4月、Webの縦書きは進化した。</Tcy>
</p>

内部では同じ tcy-rehype を呼んでいるので、Markdown 経由と .astro 直書きで挙動はぴったり揃います。

ラインアップの中での位置づけ

@love-rox/tcy-core    — framework-agnostic トークナイザー(脳)
@love-rox/tcy-react   — React 用 `<Tcy>`(描画時にラップ)
@love-rox/tcy-vue     — Vue 3 用 `<Tcy>`(描画時にラップ)
@love-rox/tcy-rehype  — `unified` プラグイン(build 時にラップ)
@love-rox/tcy-astro   — Astro インテグレーション + `<Tcy>` コンポーネント ← 新規

tcy-astro は中で tcy-rehype を呼んでいて、tcy-rehype は中で tcy-core を呼んでいます。「縦中横にすべき run はどれか」の判定はどのアダプタでも同一です。違うのは「いつ・どこで」ラップが起きるか、それだけです。

ドキュメントページも整理しました

5パッケージ全部を1ページに詰め込むとそろそろ読みにくくなってきたので、/packages/tate-chu-yoko を core を主としたランディングに作り直し、各アダプタを別ページに分けました。

各ページの上部に5パッケージのナビが出るので、横移動はそこから1クリックです。

試してみる

bun add @love-rox/tcy-astro
# pnpm / npm / yarn でも同じ

astro.config.mjs に1行加えて、CSS で .tcy を組版したら完了です。

.tcy {
  -webkit-text-combine: horizontal;
  text-combine-upright: all;
}

詳細は Astro パッケージ紹介ページGitHub の README にあります。

フィードバック歓迎です

Astro での縦組み × 縦中横は、まだ実例が多いとは言えない領域です。「ここで意図しない挙動になった」「この語は寝かせたい / 起こしたい」のような実装現場の判断が、ライブラリ側のデフォルトをよくするための一番の手がかりです。

GitHub Issues でお待ちしています。

愛がロックする。Rox。