markup-carve / carve-php
PHP parser for Carve, a human-centered lightweight markup language derived from Markdown and Djot.
Fund package maintenance!
Requires
- php: ^8.2
Requires (Dev)
- brianium/paratest: ^7.8
- nikic/php-fuzzer: ^0.0.11
- php-collective/code-sniffer: ^0.6.8
- phpstan/phpstan: ^2.1.32
- phpunit/phpunit: ^11.0 || ^12.0 || ^13.0
Suggests
- ext-intl: Recommended for heading-ID transliteration: enables ICU romanization of non-Latin scripts (e.g. CJK, Arabic). Without it, a baked map covers Latin/Cyrillic/punctuation identically and other scripts fall back to the generated `section` id.
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-03 13:18:48 UTC
README
PHP parser and renderer for Carve, a post-Markdown lightweight markup language with visual mnemonics and human-centered design.
Implements Carve spec 0.1 (see Versioning & Changelog).
Origins
Carve-PHP is a hard fork of djot-php by the PHP Collective. The fork preserves the architecture, AST, renderer pipeline, profiles, and extensions, and replaces Djot's syntax rules with Carve's. The MIT license carries over; copyright lines remain in LICENSE.
For the original Djot implementation, use php-collective/djot instead.
Installation
composer require markup-carve/carve-php
Usage
use MarkupCarve\Carve\CarveConverter; $converter = new CarveConverter(); $html = $converter->convert('# Hello /Carve/');
HTML migration can include an explicit loss report: HTML, Markdown, Djot and BBCode convert in as well. Only the HTML importer drops anything, and only it takes a mode and a loss report - see docs/html-import.md.
Besides HTML the converter renders Markdown, plain text and ANSI. The Markdown writer's options are in docs/markdown-output.md, and every node can carry its source line - docs/source-lines.md.
CLI
vendor/bin/carve README.crv > README.html # render (HTML by default) vendor/bin/carve --markdown README.crv # or --plain, --ansi, --json vendor/bin/carve lint README.crv # report problems, change nothing vendor/bin/carve migrate --from html p.html # convert into Carve
Every subcommand and flag is in docs/cli.md.
Sandbox
Try this implementation live in the Carve sandbox - explore syntax and extensions, inspect output, and share snippets via pastebin-style links. It also powers the wp-carve WordPress plugin.
ProseMirror / Tiptap
The AST converts to a ProseMirror document and back, so a Tiptap editor in the browser and PHP rendering on the server share one source of truth with no Node runtime. See docs/prosemirror.md.
Untrusted input
Rendering attacker-controlled Carve needs the safe path, which escapes raw HTML instead of emitting it and bounds nesting depth. The threat model, the defaults and the full checklist are in docs/security.md.
Linting
carve lint reports constructs that parse but render differently from what
the author intended. The rules and options are in docs/lint.md.
Documentation
- Importing HTML - the loss report and the diagnostic path locator.
- Extensions - the extension set, and writing a parse-stage matcher.
- Command line - every subcommand and flag.
- Untrusted input - the threat model and the safe path.
- Linting - the lint rules and options.
- Markdown output - the Markdown writer's options.
- Source-line tracking - carrying source positions on the AST.
- Stored documents - spec versions and stored content.
- ProseMirror / Tiptap - editor interchange.
- AST JSON - the interchange format.
- Integrated definition layout - the definition-list layout.
- Configured conversion fast path - reusing a configured converter.