runemarkv0.10.0

Colour policy

When runemark emits styles, how NO_COLOR is honoured, and how to get deterministic output for tests.

Colour modes

Mode Rust Node Behaviour
Auto ColorMode::Auto color: 'auto' (default) Styles only when writing to an interactive terminal, NO_COLOR is unset or empty, and TERM is not dumb
Always ColorMode::Always color: 'always' Styles regardless of the destination
Never ColorMode::Never color: 'never' Plain text – for tests, snapshots and logs

NO_COLOR follows the no-color.org convention: when it is set to a non-empty value, Auto emits no styles. An empty NO_COLOR counts as unset. TERM=dumb also turns Auto off. Always and Never ignore both variables.

runemark does not read FORCE_COLOR or CLICOLOR_FORCE, on purpose: the application decides, for example by mapping its own --color flag or environment variable to a mode.

Which stream

In Rust, create the console for the stream you write to, so Auto checks the right terminal:

use runemark::{ColorMode, Console};

let out = Console::stdout(ColorMode::Auto); // results
let err = Console::stderr(ColorMode::Auto); // progress and diagnostics

In Node, rendering returns strings and your code writes them. auto checks stdout unless you pass stream: 'stderr' for text you write with process.stderr.write. isTerminal overrides the detection altogether when you know better, for example in a test harness:

const { RunemarkConsole, renderError } = require('@casoon/runemark')

// Treat the destination as not a terminal, for example in a test harness
const plain = new RunemarkConsole({ color: 'auto', isTerminal: false })

// Text written to stderr is checked against stderr
process.stderr.write(renderError({ heading: 'Build failed' }, { stream: 'stderr' }))

Symbols

Symbols follow the colour decision. Where colour is on, status symbols are Unicode (✔, ⚠, ✖); where it is off (Never, redirected output, NO_COLOR), they are ASCII markers ([OK], [WARN], [FAIL], [INFO], [ACT], [SKIP]), so the outcome survives without colour.

Override the choice with Console::with_theme and a SymbolTheme in Rust, or symbols: 'unicode' or symbols: 'ascii' in Node:

use runemark::{ColorMode, Console, SymbolTheme, Verdict};

let plain = Console::new(ColorMode::Never, false);
assert_eq!(Verdict::Passed.render(plain, "Done"), "[OK] Done");

let unicode = plain.with_theme(SymbolTheme::Unicode);
assert_eq!(Verdict::Passed.render(unicode, "Done"), "✔ Done");

OSC 8 links for locations follow the colour decision too: they appear exactly where styling does. Console::with_hyperlinks(bool) in Rust and hyperlinks: true | false in Node decide independently of colour, for example links without colour, or colour without links. See Security for what a link target contains.

Width

runemark never queries the terminal itself. Pass a known width and reports adapt: narrow layouts stack summary metrics and wrap finding messages with a hanging indent.

use runemark::{ColorMode, Console, RenderOptions, Report, Verdict};

let report = Report::new("Site audit", Verdict::Info);
let output = report.render_with_options(
    Console::stdout(ColorMode::Auto),
    RenderOptions::new().with_width(80),
);
report.render({ width: process.stdout.columns })

Deterministic output

With Never, identical input produces identical text: no escape sequences, no terminal-dependent behaviour. That is the mode for golden tests and snapshots.

Edit this page on GitHub · Docs for v0.10.0