PHPackages                             markup-carve/symfony-carve - 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. [Templating &amp; Views](/categories/templating)
4. /
5. markup-carve/symfony-carve

ActiveSymfony-bundle[Templating &amp; Views](/categories/templating)

markup-carve/symfony-carve
==========================

Symfony bundle to render Carve markup to HTML via carve-php.

0.1.3(2w ago)026MITPHPPHP ^8.2CI passing

Since Jul 9Pushed 1w agoCompare

[ Source](https://github.com/markup-carve/symfony-carve)[ Packagist](https://packagist.org/packages/markup-carve/symfony-carve)[ Docs](https://github.com/markup-carve/symfony-carve)[ GitHub Sponsors](https://github.com/dereuromark)[ RSS](/packages/markup-carve-symfony-carve/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (5)Dependencies (20)Versions (6)Used By (0)

symfony-carve
=============

[](#symfony-carve)

[![CI](https://github.com/markup-carve/symfony-carve/actions/workflows/ci.yml/badge.svg)](https://github.com/markup-carve/symfony-carve/actions/workflows/ci.yml)[![PHP](https://camo.githubusercontent.com/4c9421bf016581aac0112f63a2129afceb2884079cd2f90859fb6c21972cdd30/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f6d61726b75702d63617276652f73796d666f6e792d6361727665)](https://packagist.org/packages/markup-carve/symfony-carve)[![License](https://camo.githubusercontent.com/f6e7ac5a930a29b1123f1e587a104833ff406a7d009d982e513c37d93392fca3/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6d61726b75702d63617276652f73796d666f6e792d6361727665)](LICENSE)

Symfony bundle that renders [Carve](https://github.com/markup-carve/carve) markup to HTML using [carve-php](https://github.com/markup-carve/carve-php).

Carve is "Djot minus the footguns": a lightweight markup language with consistent, unambiguous syntax.

Installation
------------

[](#installation)

```
composer require markup-carve/symfony-carve
```

Register the bundle (Symfony Flex does this automatically; otherwise add it to `config/bundles.php`):

```
return [
    // ...
    MarkupCarve\SymfonyCarve\CarveBundle::class => ['all' => true],
];
```

Usage
-----

[](#usage)

### Service

[](#service)

```
use MarkupCarve\SymfonyCarve\CarveRenderer;

public function show(CarveRenderer $carve): Response
{
    $html = $carve->render('# Hello *world*');
    $text = $carve->renderText('# Hello *world*');
    $markdown = $carve->renderMarkdown('# Hello *world*');

    return new Response($html);
}
```

### Twig

[](#twig)

```
{# filter #}
{{ article.body|carve }}

{# function #}
{{ carve('# Inline /snippet/') }}

{# plain text and Markdown filters (escaped normally by Twig) #}
{{ article.body|carve_text }}
{{ article.body|carve_markdown }}
```

Only the HTML output from `carve` is marked safe, so Twig does not double-escape it. The `carve_text` and `carve_markdown` filters are not HTML and Twig escapes them normally. Safe mode only affects HTML rendering; profiles apply to all three output formats.

Configuration
-------------

[](#configuration)

```
# config/packages/carve.yaml
carve:
    safe_mode: true      # sanitize HTML (default: true)
    raw_html: strip      # strip | escape | allow (default: strip)
    profile: null        # null | full | article | comment | minimal (default: null)
    diagrams: []         # diagram presets to enable (default: none)
```

KeyTypeDefaultDescription`safe_mode`bool`true`Enable HTML sanitization. Keep this on for untrusted input.`raw_html`enum`strip`How raw HTML is handled when `safe_mode` is on: `strip`, `escape`, `allow`.`profile`enum|null`null`Restrict markup features using `full`, `article`, `comment`, or `minimal`.`diagrams`string\[\]`[]`Diagram fenced-block presets to enable (see below). Off by default.Setting `safe_mode: false` disables sanitization entirely. Only do this for fully trusted input. Safe mode only affects HTML output. Profiles restrict available constructs for HTML, plain-text, and Markdown output; `null` leaves all constructs available.

### Diagrams

[](#diagrams)

By default a fenced block like ```` plantuml` renders as a plain code block. Listing a preset under `diagrams` turns that fence into a hydration element for a client-side renderer:

```
# config/packages/carve.yaml
carve:
    diagrams: ['plantuml', 'mermaid']
```

Now ```` plantuml` renders as `...` and ```` mermaid`as `...`, ready for a browser library to pick up.

PresetFence word(s)Output`mermaid``mermaid````plantuml``plantuml`, `puml````d2``d2````graphviz``dot`, `graphviz````wavedrom``wavedrom````vega_lite``vega-lite````chart``chart````abc``abc```The bundle only emits the markup - it does **not** ship or load any renderer. You supply the client side:

- **Graphviz, D2** render fully offline (no server, no external call) with the WebAssembly helpers from [`@markup-carve/carve-grammars`](https://github.com/markup-carve/carve-grammars): `renderDiagrams` (or `renderGraphvizDiagrams` / `renderD2Diagrams`).
- **PlantUML** has no practical in-browser renderer; render it via a [Kroki](https://kroki.io)server with the same package's `renderKrokiDiagrams` helper. > ⚠️ **Privacy / GDPR:** the default Kroki server is the public `https://kroki.io`, so the PlantUML source is sent to a third party outside your domain. For sensitive content, or to stay offline, point the helper's `server` option at a self-hosted or localhost Kroki, and disclose the external call to end users where required.
- **Mermaid, WaveDrom, Vega-Lite, Chart.js, ABC** each need their own browser library loaded on the page (mermaid.js, wavedrom, vega-embed, chart.js, abcjs).

Unknown names in the whitelist are rejected by config validation; the accepted values are exactly the presets above.

Demo
----

[](#demo)

A full runnable demo app lives at [symfony-carve-demo](https://github.com/markup-carve/symfony-carve-demo): the Twig filter and function, the `CarveRenderer` service, a live editor, a safe-mode comparison, and a syntax gallery.

[![symfony-carve demo](https://raw.githubusercontent.com/markup-carve/symfony-carve-demo/main/docs/screenshots/twig-filter.png)](https://github.com/markup-carve/symfony-carve-demo)

License
-------

[](#license)

MIT

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance98

Actively maintained with recent releases

Popularity9

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity40

Maturing project, gaining track record

 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.

###  Release Activity

Cadence

Every ~10 days

Total

4

Last Release

15d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/39854?v=4)[Mark Scherer](/maintainers/dereuromark)[@dereuromark](https://github.com/dereuromark)

---

Top Contributors

[![dereuromark](https://avatars.githubusercontent.com/u/39854?v=4)](https://github.com/dereuromark "dereuromark (18 commits)")

---

Tags

carvedjotmarkdownmarkupparsersymfonysymfonybundletwightmlmarkupdjotcarve

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/markup-carve-symfony-carve/health.svg)

```
[![Health](https://phpackages.com/badges/markup-carve-symfony-carve/health.svg)](https://phpackages.com/packages/markup-carve-symfony-carve)
```

PHPackages © 2026

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