Search by

markup-carve / carve-php

dereuromark

PHP parser for Carve, a human-centered lightweight markup language derived from Markdown and Djot.

Package info

github.com/markup-carve/carve-php

Homepage

pkg:composer/markup-carve/carve-php

Fund package maintenance!

dereuromark

Statistics

Installs: 6 235

Dependents: 8

Suggesters: 0

Stars: 4

Open Issues: 0

0.1.9 2026-09-19 09:41 UTC

README

CI Coverage Latest Stable Version Total Downloads PHPStan PHP Version Software License

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, Markdown, Djot and BBCode can return a versioned migration-fidelity report through each converter's convertWithFidelityReport() method. It uses one preserved, normalized, degraded, and dropped vocabulary while retaining format-specific diagnostic codes. HTML also has its detailed import report; see docs/html-import.md. Until Markdown, Djot and BBCode provide construct-level evidence, their reports fail closed with a dropped / fallback fidelity-unverified diagnostic. The migration CLI writes this envelope with --report FILE (or --report - for stderr), and --check-loss exits non-zero for degraded or dropped content. Opaque raw HTML is degraded even when its bytes survive because it is not modeled or editable by the importer.

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.

A document can pull in other files with {{ chapter.crv }}. It is opt-in and off by default - the core parser performs no file I/O - and the resolver you supply is the security boundary: docs/includes.md.

Source-aware tools can prepare stale-safe structured formatting changes through CarveConverter::toCarvePatch(); see the source-preserving patch guide.

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