ansi - terminal styling
Import with import "ansi.j" as ansi;. Wraps a string in ANSI SGR escape
codes for colour, background colour, text style, and 24-bit truecolor -
and strips them back off. Pure Jennifer (no Go), so it runs on either
binary.
Styling is TTY-aware: it suppresses itself when stdout is not a
terminal (redirected to a file or a pipe), so the wrapped text stays clean
either way. The NO_COLOR / FORCE_COLOR
environment convention overrides the gate.
use io;
import "ansi.j" as ansi;
io.printf("%s\n", ansi.bold(ansi.red("error:")) + " something broke");
io.printf("%s\n", ansi.green("ok") + " / " + ansi.yellow("warn"));
io.printf("%s\n", ansi.rgb("truecolor orange", 255, 128, 0));
io.printf("%s\n", ansi.underline(ansi.cyan("nested + underlined")));
Runnable: examples/modules/ansi_demo.j.
Surface
| Call | Returns | Notes |
|---|---|---|
ansi.color(s, name) | string | Wrap s in the named foreground colour. Unknown name throws. |
ansi.bgColor(s, name) | string | Wrap s in the named background colour. |
ansi.style(s, name) | string | Wrap s in a text style: bold / dim / italic / underline / reverse. |
ansi.rgb(s, r, g, b) | string | 24-bit truecolor foreground; each channel 0-255. |
ansi.strip(s) | string | Remove every SGR escape - the inverse of the wrappers. |
Wrapping composes and nests (ansi.bold(ansi.red(s))); each wrapper emits
its own code and a reset, so an inner reset never truncates an outer style.
Colour and style names
- Foreground / background (
color/bgColor):black,red,green,yellow,blue,magenta,cyan,white.coloralso accepts the brightgray(aliasgrey). - Styles (
style):bold,dim,italic,underline,reverse.
An unrecognized name is a thrown Error (kind: "value"), catchable with
try / catch.
Shortcuts
Each common colour and style has a one-argument shortcut - ansi.NAME(s)
is exactly ansi.color(s, "NAME") (or ansi.style for a style name):
- Colours:
black,red,green,yellow,blue,magenta,cyan,white,gray. - Styles:
bold,dim,italic,underline,reverse.
When styling is emitted
ansi decides per call (it is stateless - there is no toggle to store):
NO_COLORset (to anything) - off, always.- else
FORCE_COLORset - on, always. - else on when
os.isTerminal("stdout")is true; off when it is false. - If the host cannot tell whether stdout is a terminal, defaults on.
strip ignores this gate - it removes escapes unconditionally, so it
cleans up already-styled text (or a captured subprocess’s output)
regardless of the current terminal state.
def styled as string init ansi.bold(ansi.blue("styled"));
io.printf("stripped: [%s]\n", ansi.strip($styled)); # stripped: [styled]
See also
- os.md -
os.isTerminal, the TTY gate, andos.getEnvfor theNO_COLOR/FORCE_COLORreads. - regex.md -
stripusesregex.replaceto drop escape sequences. - modules/index.md - the module catalog and import rules.