Reusable league/commonmark extensions in a monorepo, installable as either the umbrella package alto/commonmark or as standalone per-extension packages.
composer require alto/commonmarkalto/commonmark declares replace on all standalone packages, so dependency resolution stays compatible whether you install one or all.
Read the complete guide at altophp.com/commonmark. It covers installation, extension selection, configuration, examples, and the security boundaries of file-reading extensions.
| Extension | Description | GitHub | Packagist |
|---|---|---|---|
| CodeBlockTitle | Titled fenced code blocks rendered as <figure> |
GitHub | Packagist |
| ContentSlicer | Wraps heading sections in semantic <section> elements |
GitHub | Packagist |
| HeadingLevel | Shift or remap heading levels across the document | GitHub | Packagist |
| Import | Import file contents into code blocks with line ranges | GitHub | Packagist |
| Include | Inline-include Markdown fragments for doc composition | GitHub | Packagist |
| LinkRewriter | Rewrite links & images via base URI, map, or regex | GitHub | Packagist |
| Source | Embed source files with line numbers and highlighting | GitHub | Packagist |
| TableOfContents | Auto-generated TOC from headings via @toc |
GitHub | Packagist |
| Tabs | Accessible ARIA tabbed UI from a simple @tabs directive |
GitHub | Packagist |
The detail that signals craft — adds a title="..." to any fenced code block and wraps it in a semantic <figure>/<figcaption>. One small thing that makes a doc site feel finished.
```php title="hello.php"
echo "Hello";
```<figure class="code-block has-title" data-title="hello.php">
<figcaption class="code-title">hello.php</figcaption>
<pre><code class="language-php">echo "Hello";
</code></pre>
</figure>Documentation · GitHub · Packagist
The rarest one in the set. Most processors stop at rendering headings as tags — this one restructures the entire document into a properly nested <section> tree, giving CSS selectors, JavaScript, and accessibility tooling something real to work with. No custom syntax needed.
## Subtopic 1
More content.
## Subtopic 2
Final content.<section><h2>Subtopic 1</h2><p>More content.</p></section>
<section><h2>Subtopic 2</h2><p>Final content.</p></section>Documentation · GitHub · Packagist
The one you don't need until you really do — then it's irreplaceable. Shifts, remaps, or transforms heading levels when embedding content from one context into another without heading hierarchy collisions.
# Title
## Section<!-- with down: 1 -->
<h2>Title</h2>
<h3>Section</h3>Documentation · GitHub · Packagist
Solves copy-paste drift between your docs and your source code. Pulls external file content directly into a code block — with line-range selection, language hinting, and depth-limited circular-import protection.
@import "src/Auth.php" {lines: 1-30, lang: php}<pre><code class="language-php">// src/Auth.php lines 1–30
</code></pre>Documentation · GitHub · Packagist
The backbone of large documentation sets. Pulls in and fully parses markdown fragments inline — making one-file-per-section composition possible without a build system.
@include "parts/intro.md"<h2>Introduction</h2>
<p>This is the introduction section.</p>Documentation · GitHub · Packagist
Indispensable plumbing for any hosted documentation setup. Decouples your markdown from your deployment URL with a composable chain of rewrite rules — base URI, exact maps, regex, and custom callbacks — applied in sequence.
[Guide](/getting-started)
<!-- with base_uri: https://docs.example.com -->
<a href="https://docs.example.com/getting-started">Guide</a>
<img src="https://docs.example.com/assets/logo.svg" alt="Logo">Documentation · GitHub · Packagist
The flagship of the set. Embeds a real file — not a copy — directly into your documentation, with syntax detection, line-range selection, line numbers, and per-line highlighting. Your docs stay in sync with your code by definition.
@source "src/Service.php" {lines: 9-11, numbers: true, highlight: "9,11"}<div class="source-block">
<div class="source-path">src/Service.php</div>
<pre><code class="language-php"><span class="line highlighted"><span class="line-number">9</span> public function add(int $a, int $b): int</span>
<span class="line"><span class="line-number">10</span> {</span>
<span class="line highlighted"><span class="line-number">11</span> return $a + $b;</span></code></pre>
</div>Documentation · GitHub · Packagist
A must-have for any document longer than a page. Drop @toc where you want the contents list — headings are collected, IDs assigned, and a navigable list rendered in one pass.
@toc {min: 2}
## Introduction
## Setup<div class="table-of-contents" id="toc">
<ul>
<li><a href="#introduction">Introduction</a></li>
<li><a href="#setup">Setup</a></li>
</ul>
</div>Documentation · GitHub · Packagist
One directive, fully accessible tabbed UI, zero JavaScript to write. Wraps content in proper ARIA tablist/tab/tabpanel roles with a self-contained switching script.
@tabs
@tab "PHP"
```php
echo 'Hello';
```
@tab "JS"
```js
console.log('Hello');
```
@endtabs<div class="tab-group" data-tabs-id="tabs-1">
<div class="tab-list" role="tablist">
<button class="tab active" role="tab" aria-selected="true" aria-controls="tabs-1-panel-0">PHP</button>
<button class="tab" role="tab" aria-selected="false" aria-controls="tabs-1-panel-1">JS</button>
</div>
<div class="tab-panels">
<div class="tab-panel" id="tabs-1-panel-0" role="tabpanel">…</div>
<div class="tab-panel" id="tabs-1-panel-1" role="tabpanel">…</div>
</div>
</div>Documentation · GitHub · Packagist
Contributions of all kinds are welcome. Visit the project on GitHub to report a bug, suggest a feature, or open a pull request.
Before submitting code, run:
# Runs PHP CS Fixer, PHPStan, and PHPUnit
composer qaChanges to public behavior should include tests and documentation.
ALTO CommonMark is open source and independently maintained by Simon André. If it is useful to your work, you can support its continued development through GitHub Sponsors.
Sharing the package or starring it on GitHub also helps.
ALTO CommonMark is released by ALTO PHP under the MIT License.