Description
Note: I'm not confident in my written English, so this issue was translated with the help of an AI assistant. Please excuse any unnatural phrasing.
Symptom
Even when a width is specified via WordWrap, paragraphs, headings, and list items written in a language without ASCII spaces (such as Japanese) are never wrapped at all. The output ignores the specified width and renders everything on a single line.
Steps to reproduce
r, _ := glamour.NewTermRenderer(
glamour.WithStandardStyle("dark"),
glamour.WithWordWrap(40),
)
out, _ := r.Render("これは日本語のように単語間にスペースを含まない言語で書かれた非常に長い段落です。")
out is not wrapped despite WordWrap: 40, and stays on a single line:
これは日本語のように単語間にスペースを含まない言語で書かれた非常に長い段落です。
Root cause
ansi/paragraph.go and ansi/heading.go use github.com/muesli/reflow/wordwrap. ansi/blockelement.go (which margin-bearing blocks such as lists and blockquotes go through) uses charmbracelet/x/ansi.Wordwrap.
Both are designed to only break at word boundaries, with no hard-wrap fallback for a "word" that itself exceeds the given width. In languages like Japanese that don't separate words with spaces, an entire block of text is treated as a single "word," so no line break ever occurs regardless of the configured width.
By contrast, ansi/table.go delegates table rendering to lipgloss/table, which internally uses ansi.Wrap — a function that does have a hard-wrap fallback for oversized words — so tables are not affected. I verified this behavioral difference between ansi.Wrap and ansi.Wordwrap directly against real Japanese text:
- ansi.Wrap: correctly wraps within the specified width
- ansi.Wordwrap / muesli/reflow/wordwrap: neither wraps at all, and both produce lines far exceeding the specified width (in one real-world example, a width of 100 was requested but lines of width 314–372 were produced)
Note: already fixed on the v2 line
On the master branch (the v2 line), paragraph.go has already moved to lipgloss.Wrap (refactor(ansi): drop reflow and use cellbuf.Wrap), so this issue does not occur there. However, it has not been backported to the currently tagged release line (v0.10.x — the version fetched via go get, and also the version charmbracelet/glow currently depends on).
Environment
- glamour v0.10.0
- Example of a downstream consumer affected: glow v2.1.1 (rendering Markdown containing CJK text, e.g. some-command | glow -, breaks paragraphs, headings, and list items)
Fix
I plan to submit a separate PR that switches paragraph.go, heading.go, and blockelement.go to use ansi.Wrap.
Version
v0.10.0
Environment
Ubuntu 24.04.4 LTS (WSL2, Linux 6.6.114.1-microsoft-standard-WSL2, x86_64), go1.26.3, glamour v0.10.0, glow v2.1.1
Description
Symptom
Even when a width is specified via
WordWrap, paragraphs, headings, and list items written in a language without ASCII spaces (such as Japanese) are never wrapped at all. The output ignores the specified width and renders everything on a single line.Steps to reproduce
out is not wrapped despite WordWrap: 40, and stays on a single line:
これは日本語のように単語間にスペースを含まない言語で書かれた非常に長い段落です。
Root cause
ansi/paragraph.go and ansi/heading.go use github.com/muesli/reflow/wordwrap. ansi/blockelement.go (which margin-bearing blocks such as lists and blockquotes go through) uses charmbracelet/x/ansi.Wordwrap.
Both are designed to only break at word boundaries, with no hard-wrap fallback for a "word" that itself exceeds the given width. In languages like Japanese that don't separate words with spaces, an entire block of text is treated as a single "word," so no line break ever occurs regardless of the configured width.
By contrast, ansi/table.go delegates table rendering to lipgloss/table, which internally uses ansi.Wrap — a function that does have a hard-wrap fallback for oversized words — so tables are not affected. I verified this behavioral difference between ansi.Wrap and ansi.Wordwrap directly against real Japanese text:
Note: already fixed on the v2 line
On the master branch (the v2 line), paragraph.go has already moved to lipgloss.Wrap (refactor(ansi): drop reflow and use cellbuf.Wrap), so this issue does not occur there. However, it has not been backported to the currently tagged release line (v0.10.x — the version fetched via go get, and also the version charmbracelet/glow currently depends on).
Environment
Fix
I plan to submit a separate PR that switches paragraph.go, heading.go, and blockelement.go to use ansi.Wrap.
Version
v0.10.0
Environment
Ubuntu 24.04.4 LTS (WSL2, Linux 6.6.114.1-microsoft-standard-WSL2, x86_64), go1.26.3, glamour v0.10.0, glow v2.1.1