← All 41 libraries

CandyShine

🌟 CandyShine

Markdown → ANSI renderer

port of charmbracelet/glamour markdown ansi renderer themes

CandyShine code coverage

Built on league/commonmark + CandySprinkles. Word-wrap, OSC 8 hyperlinks, syntax highlighting, nine built-in themes plus custom JSON themes.

Install

composer require sugarcraft/candy-shine

Quickstart

use SugarCraft\Shine\{Renderer, Theme};

echo (new Renderer())->render(<<<MD
# Welcome

A few **bold** and _italic_ words, with `inline code` and a
[link](https://example.com).

- one
- two
- three

```php
echo "hello world";
```
MD);

// Custom theme
$theme = Theme::fromJson('./themes/my-theme.json');
echo (new Renderer($theme))->render($markdown);

What's in the box

CommonMark parserHeadings, paragraphs, lists, blockquotes, code blocks, tables, rules, links, images, HTML inline + block.
Nine themesansi, plain, notty, ascii, dark, light, dracula, tokyo-night, pink.
Custom JSONTheme::fromJson('./my-theme.json') — element-keyed style overrides. An unreadable file throws RuntimeException carrying the read error, rather than leaking a PHP warning; Theme::fromJsonString() takes the JSON directly.
Word-wrapConfigurable column width; honours SGR + grapheme cluster widths. List items and blockquotes charge only their own indent or 2-cell bar, so nested lines fit the wrap width as in glamour.
OSC 8 hyperlinksOptional --no-hyperlinks toggle for terminals that don't support them. Email autolinks render the address hyperlinked to mailto: with no href suffix.
Streamingstream(iterable $chunks) yields rendered sections as markdown arrives, byte-identical to render(). Link reference definitions carry across sections; a section with an unresolved [..] is held back until a later definition resolves it or the document ends.
Syntax highlightingCode blocks tokenised + coloured per language.

Source & demos

See also

Try the quickstart →

API

ClassMethodDescription
Renderernew Renderer(?Theme $theme = null, …)Create renderer with optional theme (also Renderer::ansi() / plain() / ascii() / fromEnvironment())
Rendererrender(markdown)Render markdown to ANSI string; a reused Renderer starts every render from a clean block stack
Rendererstream(iterable $chunks): Generator / writer(StreamSink)Incremental section-by-section rendering
RendererwithWordWrap(?int) / withHyperlinks() / withBaseURL() / withTableWrap() / withPreservedNewLines() / withEmoji() / withSanitize()Immutable option setters; withPreservedNewLines() keeps the source's blank-line runs between blocks
ThemefromJson(path) / fromJsonString(json)Load theme from a JSON file (RuntimeException with the read error on failure) or string
Themeansi(), plain(), notty(), ascii(), dark(), light(), dracula(), tokyoNight(), pink()Built-in theme presets; byName() looks one up by name

Demos.

VHS-recorded GIFs of every example shipped with the library. Regenerated automatically on every push that touches the source.

Render

Render

Markdown → ANSI with the default ansi theme.
Themes

Themes

Same document rendered through the six colour themes (ansi, dark, light, dracula, tokyo-night, pink).