Markdown and links
Label, description and note text is more than a flat string: it can carry a clickable link, and - when you opt in - a small, safe subset of markdown. Both adapt to the terminal, degrading to clean plain text where a terminal (or your color switch) cannot show the real thing, so the same form reads well everywhere.
Links
A [text](url) link is recognized in field labels, descriptions, notes and the summary report - no opt-in needed. On a capable terminal it renders as a clickable OSC 8 hyperlink showing just its text; elsewhere it degrades to text (url) so the address is never lost.
$p->text('item', 'Item')
->description('Full list in the [orchard index](https://example.com/orchard).');
Only an addressable target is linked - the URL must carry a scheme (https://, mailto:, tel: and the like) - so incidental bracket-and-paren prose such as [note](see step 3) stays literal. Links honor the color switch: with color off (the NO_COLOR convention, TERM=dumb, or ->color(FALSE)) every link degrades to text (url).
The summary resolves links too: $answers->toSummary() follows the terminal's color capability - the same NO_COLOR / TERM=dumb signal the interactive TUI uses - emitting a hyperlink on a capable terminal and text (url) otherwise.
Markdown
Turn on ->markdown() and field descriptions and note bodies render a small subset of markdown, each construct mapped to one of the theme's style atoms:
$answers = (new Tui($form))->markdown()->run();
| Markup | Renders as |
|---|---|
**bold** | bold |
*emphasis* | italic |
`code` | the theme's code color |
[text](url) | a hyperlink (as above) |
- item / * item | a bullet list |
$p->note('intro', 'Fresh produce order')
->description("Pick what is **ripe** today:\n- crisp apples\n- sweet pears\nSee the [seasonal guide](https://example.com/seasonal-guide).")
->border();
$p->number('quantity', 'Quantity')->min(1)->max(99)
->description('Baskets hold up to **99**; order more in a *second* basket.');
The subset is deliberately small and inline - no headings, tables or nested blocks - so a description stays a description. Because each construct maps to a theme atom, a custom theme restyles bold, emphasis, code, links and bullets by overriding strong(), emphasis(), code(), link() and bullet().
Markdown honors both the color and the Unicode switches. With color off the markers drop and the text renders plain (bold **ripe** becomes ripe, a link becomes text (url)); with ASCII glyphs the bullet falls back from • to -. Headless collection never renders descriptions or notes at all, so it is unaffected. Links stay recognized whether or not markdown is on - ->markdown() only adds the rest of the subset.
The same markdown note in all four display modes - the color-off column drops the styling and degrades the link to text (url), the ASCII row falls back to a - bullet:
| ANSI | No ANSI | |
| Unicode | ||
| ASCII |
A runnable example is playground/11-display-modes-markdown.php.