northrook/ansi-formatter
Composer 安装命令:
composer require northrook/ansi-formatter
包简介
Format strings with ANSI colour codes for terminal output based on embedded tags
README 文档
README
Format strings with ANSI colour codes for terminal output based on lightweight markup tags.
Requires PHP 8.4+.
Installation
composer require northrook/ansi-formatter
Quick start
use Northrook\AnsiFormatter;
$format = new AnsiFormatter();
echo $format->string('<blue b>Hello</blue> <b>World</b>!');
When STDOUT is a TTY, tags become ANSI escape codes.
When output is piped or redirected, tags are stripped and no codes are emitted.
TTY detection uses stream_isatty(STDOUT); pass assumeTTY: true or assumeTTY: false to override.
Markup reference
Tags are case-insensitive and may be nested.
Combine styles with attributes on the opening tag.
Styles
| Tag | Effect |
|---|---|
<b> | Bold |
<dim> | Dim |
<i> | Italic |
<u> | Underline |
<blink> | Blink |
<reverse> | Reverse video |
<conceal> | Concealed |
Foreground colours
black, red, green, yellow, blue, magenta, cyan, white, gray
Background colours
bg-black, bg-red, bg-green, bg-yellow, bg-blue, bg-magenta, bg-cyan, bg-white
Examples
$format->string('<blue b>Hello</blue>'); // bold blue
$format->string('<red bg-blue>Alert</red>'); // red on blue background
$format->string('<blue><b>hi</b> there</blue>'); // nested styles
Close tags are required. A missing close tag is logged as a warning and the style is not reset at the end of the element.
Non-TTY output
When output is not a TTY:
- Tag-shaped markup is removed from the result
- No ANSI escape codes are emitted
- Unsupported-markup warnings are suppressed (even when a logger is configured)
This keeps piped and log-captured output clean.
Literal < characters
A < is only parsed as markup when it appears at the start of the string or is not immediately preceded by a letter, digit, ., or _.
Everything else stays literal.
$format->string('array<int>'); // array<int>
$format->string('Array.<int>'); // Array.<int>
$format->string('Generic<Foo>'); // Generic<Foo>
$format->string('2 < 3'); // 2 < 3
$format->string(' <blue>x</blue>'); // styled (space before <)
Dynamic content
Pass dynamic values as arguments so they are inserted raw and never parsed as markup.
// Positional
$format->string('<red>Error:</red> {%}', $userMessage);
// Named
$format->string('<red>{%label}</red> {%detail}', label: 'Error:', detail: $userMessage);
// Placeholder in a tag attribute
$format->string('<blue {%style}>hi</blue>', style: 'b');
{%} consumes positional arguments in order. {%name} looks up a named argument.
Values are inserted verbatim — they are not escaped and may contain ANSI sequences or angle brackets.
Only pass trusted content through placeholders.
Use the template for markup; use placeholders for data.
Escaping
| Input | Output |
|---|---|
\{%} | {%} |
\{%name} | {%name} |
\\ | \ |
Without matching arguments, {%} and {%name} in the template stay literal.
AnsiOutput
AnsiOutput buffers multiple formatted fragments and joins them on output().
Use it when building multi-line CLI output.
use Northrook\AnsiFormatter\AnsiOutput;
$out = new AnsiOutput();
$out
->line('<blue>Starting</blue>')
->line('<green>Done</green>');
echo $out->output();
| Method | Description |
|---|---|
append() | Add a formatted fragment to the end |
prepend() | Add a formatted fragment to the start |
line() | Append a newline (if non-empty) then a fragment |
output() | Join fragments; caches until the buffer changes |
__toString() | Same as output(flush: true) |
The object is callable — $out('<red>x</red>') delegates to append().
When no formatter is injected, one is created with deferred STDERR flushing (see below).
Pass your own AnsiFormatter instance to customise logger, TTY, or warning behaviour.
Post-processor
Apply a callback to each fragment before joining:
$out = new AnsiOutput(
postProcessor: static fn (string $chunk, int $index): string => "[{$index}]{$chunk}",
);
Unsupported markup
Unknown tags and attributes are stripped from the output. Missing or mismatched close tags are also reported.
When output is a TTY, a warning is logged via the configured PSR-3 logger.
Control STDERR output with OnUnsupported:
| Mode | STDERR behaviour |
|---|---|
IGNORE | Never writes to STDERR |
STDERR | Flushes warnings at the end of each string() call |
DEFER | Queues warnings; flushes on writeUnsupportedToStderr(), AnsiOutput::output(), or formatter destruct |
Default when constructing AnsiFormatter directly:
| Logger provided | Default mode |
|---|---|
| No | STDERR |
| Yes | IGNORE |
AnsiOutput autovivifies a formatter with DEFER so warnings from multiple fragments are written once on output().
use Northrook\AnsiFormatter\OnUnsupported;
use Psr\Log\LoggerInterface;
$format = new AnsiFormatter(
logger: $logger,
onUnsupported: OnUnsupported::STDERR,
assumeTTY: true,
);
Flush a deferred queue manually:
$format->writeUnsupportedToStderr();
Development
composer test
composer phpstan
License
BSD-3-Clause. See LICENSE.
统计信息
- 总下载量: 1
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 2
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: BSD-3-Clause
- 更新时间: 2026-07-08