Coming from slice-ansi
A slice-ansi alternative with a drop-in path: import sliceAnsi from linegauge/slice, graded 106 / 106 by slice-ansi 10's own test suite — then zero dependencies, grapheme clusters never halved, and one style stack shared with wrap.
linegauge is a slice-ansi alternative you adopt by changing one import.
linegauge/slice's default export is slice, call-compatible with slice-ansi's default, and
slice-ansi's own test suite is the grade.
Migrate from slice-ansi in one import
- import sliceAnsi from 'slice-ansi';
+ import sliceAnsi from 'linegauge/slice';The call is slice-ansi's — sliceAnsi(string, start, end), in display columns, end
optional. The same function is also the named export slice, from linegauge/slice or from
linegauge.
It also answers the questions slice-ansi's neighbours do, one subpath each:
| Incumbent | linegauge path |
|---|---|
string-width | linegauge (the default export) |
strip-ansi | linegauge/strip |
wrap-ansi | linegauge/wrap |
slice-ansi | linegauge/slice |
Is linegauge compatible with slice-ansi?
Graded, not claimed. slice-ansi's own suite, vendored at 10.0.0 and unmodified apart from the
import specifier, runs against linegauge/slice beside a control that runs it against the
real slice-ansi:
| passing | rate | |
|---|---|---|
linegauge/slice | 106 / 106 | 100.0% |
| slice-ansi itself (control) | 106 / 106 | 100.0% |
From Compatibility, which npm run compat:page generates from the
oracle's last run; that page is the authority.
Where a cut lands, slice counts the columns width counts, as slice-ansi 10 does: it takes
each cluster's width from string-width, so CRLF and every other cluster that draws nothing take
no column, and a lone regional indicator (🇦) takes one. slice-ansi 9 gave every cluster at
least one position and a lone indicator two, and slice followed it until 10.
slice-ansi 7's suite is graded too, at 14 / 15, and 7 is not claimed. The one it fails is the case where 7 and 9 contradict each other: 7 wants a wide character that runs one column past the end of the range included, and 9 wants it left out. linegauge leaves it out.
The same page grades linegauge against string-width 9.0.0 (466 / 466), linegauge/v8 against string-width 8.3.0 (233 / 233), linegauge/strip against
strip-ansi (8 / 8) and linegauge/wrap against wrap-ansi (85 / 85).
What you gain over slice-ansi
slice-ansi 10.0.0 depends on ansi-styles and string-width, which brings strip-ansi,
ansi-regex and get-east-asian-width. linegauge/slice depends on nothing, and it is pure: nothing in
linegauge reads process, so the same input slices the same way on a pipe, under --json and
in a test.
- A cluster is never halved. Columns are string-width 8.3.0's, which slice-ansi 10
measures with —
linegauge/v8, graded 233 / 233 by that release's suite — and cluster boundaries from the platform's ownIntl.Segmenter. A cluster that straddles either edge is left out whole, so a slice is never wider than the columns asked for and never returns half a family emoji or one letter of a flag. - One style stack, not two. slice-ansi and wrap-ansi each carry their own copy of
open/close/reopen, and they disagree at the edges.
linegauge/sliceandlinegauge/wrapshare one, so slicing and wrapping the same styled string agree. - The family measures with it. burgee, caique and flagstaff build on linegauge, so what they write for a pipe or an agent is cut the same way.
When to switch from slice-ansi
- Your output carries terminal hyperlinks, and a slice of it has to keep them.
- Your dependency tree carries slice-ansi beside string-width, strip-ansi or wrap-ansi, and you would rather it carried one package with no dependencies.
The API and the design notes are on linegauge; the width path is on Coming from string-width.
Coming from strip-ansi
A strip-ansi alternative with a drop-in path: import stripAnsi from linegauge/strip, graded 8 / 8 by strip-ansi's own test suite — then no ansi-regex underneath, and one escape scanner shared with width, wrap and slice, so what strip removes is exactly what they count as zero columns.
Aligning columns
Pad text to a column count with width() and widest(), so CJK names and emoji do not push a column out of line the way padEnd does.