doctrine/rst-parser
PHP library for parsing reStructuredText documents, used to generate documentation for the Doctrine project website. It converts RST markup into a structured document tree.
Install the library directly; there is no Laravel package or service provider:
composer require doctrine/rst-parser
Start with the smallest possible document:
use Doctrine\RST\Parser;
$parser = new Parser();
$document = $parser->parse(<<<'RST'
Project Docs
============
Install with:
.. code-block:: bash
composer require doctrine/rst-parser
See :doc:`installation` for details.
RST);
return response($document->render());
For real files, keep the filename context so relative references, includes, and links resolve correctly:
$document = $parser->parseFile(base_path('docs/index.rst'));
If your installed version’s parseFile() signature differs, call parse($contents, $filename) and pass the source path explicitly.
Look first at:
src/Parser.php — entry pointsrc/Configuration.php and src/Environment.php — renderer and parser behaviorsrc/HTML/ — HTML renderer behaviortests/ — fixture examples of supported RST syntaxFirst use case: build an internal documentation viewer or a docs:build Artisan command. Start with one .rst file rendered to HTML, then add caching, navigation, and custom directives only after the basic pipeline works.
Wrap rendering in a small application service. This keeps Parser out of controllers and gives you one place for configuration, caching, and error handling.
namespace App\Services;
use Doctrine\RST\Parser;
class RstRenderer
{
public function renderFile(string $path): string
{
$parser = new Parser();
return $parser->parseFile($path)->render();
}
public function renderString(string $rst): string
{
return (new Parser())->parse($rst)->render();
}
}
Bind it as a singleton if you do not mutate parser/environment state per request:
$this->app->singleton(RstRenderer::class);
Cache rendered HTML, not the parser. Parsing is deterministic for a given source and configuration, so cache the output:
$key = 'docs:'.hash('sha256', $rst).':'.config('docs.renderer_version');
$html = Cache::remember($key, now()->addHour(), fn () => $renderer->renderString($rst));
Include referenced files, includes, and configuration in the cache key if your documents depend on them.
Use a build command for multi-file docs. Batch parse files, render to static HTML, and write to public/docs or storage:
foreach (File::allFiles(resource_path('docs')) as $file) {
$html = (new Parser())->parseFile($file->getPathname())->render();
File::put(
public_path('docs/'.str_replace('.rst', '.html', $file->getRelativePathname())),
$html
);
}
Use a fresh parser per document unless you have verified that environment state does not leak references, directives, or metadata between documents.
Use the directive/role system instead of string replacement. When you need project-specific blocks such as callouts, tabs, or API references, implement custom directives and register them through the parser environment. Keep directive output structured where possible; if a directive emits raw HTML, treat it as trusted code.
Post-process with DOMDocument, not regex. If you need to rewrite links, add CSS classes, or inject anchors, load the rendered HTML into DOMDocument and manipulate nodes. Regex against generated HTML becomes brittle quickly.
Test with RST fixtures. Keep small .rst fixtures and assert against rendered output:
$html = (new Parser())->parse("Title\n=====\n")->render();
$this->assertStringContainsString('<h1>Title</h1>', $html);
This is especially useful when upgrading the package, since the public API is intentionally small and output details matter.
parseFile() or pass the filename to parse() rather than rendering isolated strings.src/Directives, src/Nodes, and src/HTML before considering a fork. Many presentation changes can be handled by wrapping or post-processing the rendered HTML.How can I help you explore Laravel packages today?