Stringwrap is a Go package for wrapping strings by visual width with optional word splitting and full ANSI + grapheme cluster support.
General Wrapping
- Ignores ANSI escape codes for width calculations while preserving them in the output.
- Correctly processes Unicode grapheme clusters.
- Supports configurable tab sizes.
- Respects hard breaks (
\n
) in the input string. - Provides optional word splitting for finer-grained control.
- Handles non-breaking spaces (
\u00A0
) to prevent unwanted line breaks.
Wrapped-Line Metadata
- Byte and rune offsets within the original string.
- The visual width of the wrapped line.
- The index of the segment from the original line that this wrapped line belongs to.
- An indication of whether the line ended due to a hard break or soft wrapping.
- A flag indicating if the segment ends with a word that was split during wrapping.
Both StringWrap
and StringWrapSplit
use Unicode grapheme cluster parsing (via the uniseg
library) along with rune iteration.
go get github.com/galactixx/stringwrap@latest
import "github.com/galactixx/stringwrap"
wrapped, meta, err := stringwrap.StringWrap("Hello world! 🌟", 10, 4)
fmt.Println(wrapped)
Hello
world! 🌟
wrapped, meta, err := stringwrap.StringWrapSplit("Supercalifragilisticexpialidocious", 10, 4)
fmt.Println(wrapped)
Supercali-
fragilist-
icexpiali-
docious
for _, line := range meta.WrappedLines {
fmt.Printf(
"Line %d: width=%d, byteOffset=%v\n",
line.CurLineNum,
line.Width,
line.OrigByteOffset
)
}
Wraps a string at a visual width limit. Words are not split.
Same as StringWrap
, but allows splitting words across lines if needed.
Metadata for one wrapped segment.
type WrappedString struct {
CurLineNum int
OrigLineNum int
OrigByteOffset LineOffset
OrigRuneOffset LineOffset
SegmentInOrig int
NotWithinLimit bool
IsHardBreak bool
Width int
EndsWithSplitWord bool
}
Contains all wrapped lines and wrap configuration.
type WrappedStringSeq struct {
WrappedLines []WrappedString
WordSplitAllowed bool
TabSize int
Limit int
}
This project is licensed under the MIT License. See the LICENSE file for more details.
If you have any questions or need support, feel free to reach out by opening an issue on the GitHub repository.