Skip to content

fix: wrap Chinese, Japanese and Korean text by display width - #112

Merged
hownowstephen merged 1 commit into
mainfrom
fix_wrap_cjk_by_width
Oct 12, 2026
Merged

hownowstephen merged 1 commit into
mainfrom
fix_wrap_cjk_by_width

Conversation

@hownowstephen

@hownowstephen hownowstephen commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Text in Chinese, Japanese and Korean has no spaces to break at, so long lines never wrapped, and wide characters counted as one column although they take two. Line length is now measured in display columns: CJK and other East Asian wide characters and common emoji take two, combining marks take none. A line holding wide characters may also break between CJK characters, keeping closing punctuation and small kana off the start of a line and opening brackets off the end.

WordWrap("日本語日本語日本語日本語", 10)  →  日本語日本 / 語日本語日 / 本語
WordWrap("あいうえおかきくけ。こ", 18)    →  あいうえおかきく / け。こ

Heading rules and data table columns use the same widths, so a <h2>日本語</h2> rule is six columns and CJK table cells line up.

Lines without wide characters keep the existing fast path. Finding wide characters costs one extra pass over each line longer than the line length: on BenchmarkWordWrap, ASCII prose is ~1µs (16%) slower per 15KB and prose with curly quotes ~2µs. Full conversions of the benchmark corpus are unchanged within noise, and their output is byte-identical. CJK text costs about 8ns a character now that it actually wraps.

The width table is a hand-written approximation rather than golang.org/x/text/width, to avoid a new dependency; emoji joined with U+200D count each part. It is marked with a ponytail: comment.

@hownowstephen
hownowstephen marked this pull request as ready for review October 12, 2026 03:27
@hownowstephen
hownowstephen merged commit 9282a8e into main Oct 12, 2026
5 checks passed
@hownowstephen
hownowstephen deleted the fix_wrap_cjk_by_width branch October 12, 2026 03:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant