npm package

tate-chu-yoko

A small library that automatically wraps half-width alphanumerics inside vertical Japanese text so CSS `text-combine-upright` can compose them as tate-chu-yoko (縦中横). Authors write plain text; typesetting is handled for them.

v0.3.0MITSSR-safe

120264月、Webの縦書きは進化した。

What it solves

Japanese vertical writing (writing-mode: vertical-rl) leaves half-width Latin letters and digits lying on their side. The fix — text-combine-upright: all — exists, but the developer still has to decide *which* runs to apply it to, usually by wrapping them in <span class="tcy"> by hand. That chore leaks into manuscripts, CMSes, and Markdown. tate-chu-yoko does the wrapping for you, so authors can keep writing plain text.

Five packages

At the center is @love-rox/tcy-core, a framework-agnostic tokenizer. Pick whichever adapter (or adapters) suits your stack — core is pulled in automatically as a dependency.

One CSS rule everywhere

No matter which adapter you choose, the generated <span class="tcy"> elements need the same CSS. Including -webkit-text-combine keeps Safari happy.

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

What's true across the board

  • Runs are not joined across element boundaries — <em>12</em>34 produces two separate spans.
  • Full-width alphanumerics (A–Z / 0–9) are left alone because they already render upright in vertical text.
  • React, Vue, and the Astro <Tcy> are SSR-safe: server and client emit the same DOM.
  • The rehype plugin (and the Astro integration that wraps it) is idempotent — running it twice on the same HAST gives the same output as running it once.
  • Runs filtered out by maxLength or excludeWords are demoted back to plain text and merged into the surrounding text segment automatically.

Browser support

writing-mode: vertical-rl and text-combine-upright: all are supported in all modern browsers. For Safari it's still worth including -webkit-text-combine: horizontal alongside the standard property.

Shared version line

All five packages release on the same shared version line, anchored to @love-rox/tcy-core. Whenever any one of them changes, the others move to the same number — so you never have to wonder whether react@0.2.5 is compatible with core@0.3.0.

License

MIT License. Free to use in personal and commercial projects.

See it in action

The interactive demo lets you tweak options and compare the raw text with the <Tcy> output side by side.

Open the demo