alto / markdown
Parse, query, lint, build, render, and edit Markdown with minimal diffs.
Package info
pkg:composer/alto/markdown
Fund package maintenance!
Requires
- php: >=8.4
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.94
- phpstan/phpstan: ^2.1
- phpstan/phpstan-strict-rules: ^2.0
- phpunit/phpunit: ^12.5
Suggests
- ext-dom: Required for HtmlPolicy::curated() HTML sanitization
README
ALTO Markdown parses Markdown into a document model you can lint, format, edit, and convert to HTML, preserving everything you don't touch.
The core has no runtime Composer dependencies. It supports CommonMark, GitHub Flavored Markdown, and GitHub-oriented documents. Trusted extensions can add custom blocks, leaf inlines, native HTML decorators, render-only document projections, lint rules, formatter passes, and document metrics. ALTO includes configurable leaf delimiter pairs, smart punctuation, highlights, description lists, footnotes, configurable mentions, nested Markdown tabs, constrained source attributes, escaped code imports, recursive Markdown includes, semantic heading sections, source excerpt displays, and a bounded resource resolver for trusted custom extensions and rich embeds. Front matter stays opaque until the application explicitly passes a decoder.
The full guide set lives under docs/.
| Need | Start with |
|---|---|
| Convert a string to HTML | Markdown::github()->toHtml($source) |
| Convert inline Markdown without a wrapper | Markdown::github()->toInlineHtml($source) |
| Inspect or reuse a document | Markdown::github()->fromString($source) |
| Edit and save a file | Markdown::github()->open($path) |
| Generate Markdown | Markdown::github()->builder() |
| Add trusted syntax or analysis | Markdown::github()->with($extension) |
Installation
Install ALTO Markdown with Composer:
composer require alto/markdown
ALTO Markdown requires PHP 8.4 or later. ext-dom is optional and used only by the curated HTML
sanitizer.
Quick Start
use Alto\Markdown\Markdown; $markdown = "# Installation\n\nRun `composer install`.\n"; $html = Markdown::github()->toHtml($markdown);
The result is:
<h1>Installation</h1> <p>Run <code>composer install</code>.</p>
Direct conversion is the shortest and fastest path when HTML is the only result you need. Output is safe by default: raw HTML is escaped and unsafe URL schemes are filtered.
Use toInlineHtml() for a title, label, comment, or other fragment where block
syntax and a paragraph wrapper are unwanted:
$label = Markdown::github()->toInlineHtml('Install **Alto**');
See Installation, HTML, Profiles, and Security to choose the right language and HTML policy.
Open a document when you need more
A document keeps the parsed structure and the original source bytes. Query and edit it without rewriting unrelated content:
use Alto\Markdown\Markdown; $document = Markdown::github()->fromString( "# Guide\n\nRead the [documentation](https://example.com).\n\n" ."## Install\n\nOld instructions.\n", ); $title = $document->title()?->text(); $linkCount = $document->links()->count(); $document->section('Install')->replaceBody("Run Composer.\n"); $markdown = $document->toMarkdown(); $html = $document->toHtml();
Use open() for a file. It adds atomic saving, unified diffs, formatting, and
safe lint fixes:
use Alto\Markdown\Lint\LintConfig; use Alto\Markdown\Markdown; use Alto\Markdown\Operation\SaveOptions; $file = Markdown::github()->open('README.md'); $config = LintConfig::recommended(); $report = $file->lint($config); $file->fix($config); $file->format(); if ($file->hasChanges()) { echo $file->diff()->toUnifiedString(); $file->save(new SaveOptions(compareBeforeWrite: true)); }
Source ranges use original byte offsets. toMarkdown() preserves unchanged
bytes, line endings, and a UTF-8 BOM. Alto rejects an edit when it cannot apply
it safely under the documented V1 contract.
The documentation covers this in more depth: Queries and Statistics to inspect structure and metrics; Editing to change sections and rearrange top-level blocks with minimal diffs; and Linting, Fixing, and Formatting to enforce content and style policies.
Extend
Trusted extensions add custom blocks, leaf inlines, native and link-aware HTML decoration, document render projections, lint, formatting, metrics, heading-level projection, permalinks, and generated tables of contents through compiled contracts. Read Extensions and Compatibility for the extension contracts and migration notes from historical Alto CommonMark extensions.
Documentation
- Documentation index: browse the complete guide set.
- API reference and Exceptions: the public surface and recovery contracts.
Contributing
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 qa
Changes to public behavior should include tests and documentation. Run
composer coverage separately to enforce the 99% line-coverage floor.
Support
ALTO Markdown is open source. You can support its continued development through GitHub Sponsors.
Sharing this package with others or starring it on GitHub is also much appreciated.
License
ALTO Markdown is released by ALTO PHP under the MIT License.