PHPackages                             sugarcraft/candy-ansi - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Parsing &amp; Serialization](/categories/parsing)
4. /
5. sugarcraft/candy-ansi

ActiveLibrary[Parsing &amp; Serialization](/categories/parsing)

sugarcraft/candy-ansi
=====================

ECMA-48 VT500 state machine — ANSI byte-stream parser with abstract Handler interface. Shared extraction from candy-vt.

02.0kPHP

Since Jul 12Pushed 1w agoCompare

[ Source](https://github.com/sugarcraft/candy-ansi)[ Packagist](https://packagist.org/packages/sugarcraft/candy-ansi)[ RSS](/packages/sugarcraft-candy-ansi/feed)WikiDiscussions master Synced 1w ago

READMEChangelogDependenciesVersions (1)Used By (0)

CandyAnsi
=========

[](#candyansi)

`composer require sugarcraft/candy-ansi`

ECMA-48 VT500 ANSI parser state machine — the shared byte-stream interpreter extracted from `candy-vt`. Feeds raw bytes through the Paul-Williams state machine, dispatching abstract `Handler` events. Handles partial input naturally; multi-byte UTF-8 runes arrive at the handler as complete grapheme clusters.

Upstream: [charmbracelet/x/ansi](https://github.com/charmbracelet/x/tree/main/ansi/parser)

Status
------

[](#status)

🟢 Working port. The VT500 state machine plus the abstract `Handler`, `CsiHandler`, and `OscHandler` boundaries live here and are the shared source of truth for downstream consumers (`candy-vt`, `sugar-spark`, `candy-hermit`, `candy-freeze`, `candy-pty`). `CsiHandler` now covers the full emulator CSI-final set (cursor, erase, scroll, insert/delete line &amp; char, repeat, SCO save/restore, CR/LF) so `candy-vt` can implement this interface directly instead of forking its own parser.

Quickstart
----------

[](#quickstart)

```
use SugarCraft\Ansi\Parser;
use SugarCraft\Ansi\Parser\DebugHandler;

$handler = new DebugHandler();
$parser  = new Parser($handler);

// parseComplete() feeds then guarantees end-of-stream flush so trailing
// sequences (OSC/DCS/incomplete UTF-8 runes) are not silently lost.
// For streaming/chunked input, use feed() + flush() separately.
$parser->parseComplete("hello\x1b[31mworld\x1b[0m");

// $handler->log now contains every parse action:
// print 'h', 'e', 'l', 'l', 'o', csi(['31']), print 'w', 'o', 'r', 'l', 'd', csi(['0'])
```

Handler interface
-----------------

[](#handler-interface)

Implement `SugarCraft\Ansi\Parser\Handler` to consume parse events:

```
interface Handler
{
    public function printChar(string $rune): void;           // grapheme cluster
    public function execute(int $byte): void;                 // C0/C1 control char
    public function csiDispatch(int $final, array $params, int $prefix, int $intermediate): void;
    public function escDispatch(int $final, int $intermediate): void;
    public function oscDispatch(string $data): void;
    public function dcsDispatch(int $final, array $params, int $prefix, int $intermediate, string $data): void;
    public function sosPmApcDispatch(string $kind, string $data): void;
}
```

Packages
--------

[](#packages)

BadgeDescription[![CI](https://github.com/sugarcraft/candy-ansi/actions/workflows/ci.yml/badge.svg)](https://github.com/sugarcraft/candy-ansi/actions/workflows/ci.yml)Unit tests[![codecov](https://camo.githubusercontent.com/cdc9310f4f83e822d24dfa0011770144c436f45f7637416ef96bc541544b932b/68747470733a2f2f636f6465636f762e696f2f67682f737567617263726166742f63616e64792d616e73692f6272616e63682f6d61737465722f67726170682f62616467652e7376673f666c61673d63616e64792d616e7369)](https://app.codecov.io/gh/sugarcraft/candy-ansi)Coverage

###  Health Score

27

—

LowBetter than 46% of packages

Maintenance64

Regular maintenance activity

Popularity23

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity11

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/b1036e0717211b8030b83cbe729e8ba6ba442fdbd5285fb97a39d7dcfe339342?d=identicon)[detain](/maintainers/detain)

---

Top Contributors

[![detain](https://avatars.githubusercontent.com/u/1364504?v=4)](https://github.com/detain "detain (23 commits)")

### Embed Badge

![Health badge](/badges/sugarcraft-candy-ansi/health.svg)

```
[![Health](https://phpackages.com/badges/sugarcraft-candy-ansi/health.svg)](https://phpackages.com/packages/sugarcraft-candy-ansi)
```

###  Alternatives

[sauladam/shipment-tracker

Parses tracking information for several carriers, like UPS, USPS, DHL and GLS by simply scraping the data. No need for any kind of API access.

9843.5k](/packages/sauladam-shipment-tracker)[jstewmc/rtf

Read and write Rich Text Format (RTF) documents with PHP

45153.1k6](/packages/jstewmc-rtf)[tcds-io/php-jackson

A lightweight, flexible object serializer for PHP, inspired by FasterXML/jackson

113.2k10](/packages/tcds-io-php-jackson)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
