Parsel provides one expressive PHP API for document parsing, backed by interchangeable drivers. Version 1.0 includes local LiteParse and AnyDoc drivers and public contracts for custom or future hosted providers.
use Shipfastlabs\Parsel;
$markdown = Parsel::file('report.pdf')->markdown(); // LiteParse by default
$markdown = Parsel::driver('anydoc')
->file('report.docx')
->markdown();Parsel requires PHP 8.4 or greater.
composer require shipfastlabs/parselInstall only the parser you use. With no --driver, the installer installs LiteParse:
vendor/bin/parsel-install
vendor/bin/parsel-install --driver=anydoc
vendor/bin/parsel-install --driver=allLiteParse supports npm, pnpm, bun, pip, and cargo. AnyDoc supports npm, pnpm, and bun and requires Node.js 20 or newer.
vendor/bin/parsel-install --driver=liteparse --manager=cargo
vendor/bin/parsel-install --driver=anydoc --manager=npm
vendor/bin/parsel-install --driver=liteparse --with-system-dependenciesvendor/bin/parsel-install-lit remains as a compatibility alias.
| Capability | LiteParse | AnyDoc |
|---|---|---|
| Markdown | Yes | Yes |
| Plain text | Yes | No |
| Structured pages and coordinates | Yes | No |
| Lazy pages | Yes | No |
| Screenshots | Yes | No |
| OCR | Yes | No |
Calling an unavailable operation throws UnsupportedCapabilityException before the provider is executed. Parsel does not derive fake structured data or plain text from AnyDoc Markdown.
LiteParse remains the default driver, so existing basic calls continue to work:
$text = Parsel::file('invoice.pdf')->text();
$document = Parsel::file('invoice.pdf')->parse();
$array = Parsel::file('invoice.pdf')->toArray();Select AnyDoc explicitly or change the process-wide default:
Parsel::driver('anydoc')->file('book.epub')->markdown();
Parsel::defaultDriver('anydoc');
Parsel::file('book.epub')->markdown();For dependency injection and long-running applications, use an instance:
use Shipfastlabs\Parsel\ParselManager;
$parsel = new ParselManager;
$markdown = $parsel->driver('anydoc')->file('report.docx')->markdown();Both drivers accept paths and raw bytes. Byte sources require an extension so signature-less formats such as CSV can be identified reliably.
$markdown = Parsel::file('/path/to/report.pdf')->markdown();
$markdown = Parsel::bytes($uploadedBytes, 'pdf')->markdown();
$markdown = Parsel::driver('anydoc')
->bytes($csvBytes, 'csv')
->withProviderOptions(['format' => 'csv'])
->markdown();Timeout is portable across drivers:
Parsel::file('report.pdf')->withTimeout(120)->markdown();save() selects the corresponding capability from the extension. Both drivers support .md and .markdown; LiteParse additionally supports .txt and .json.
Parsel::driver('anydoc')->file('report.docx')->save('report.md');
Parsel::file('report.pdf')->save('report.json');Provider-specific behavior belongs in withProviderOptions(). It accepts a typed fluent object or a strict associative array.
use Shipfastlabs\Parsel\Options\LiteParseOptions;
$options = LiteParseOptions::make()
->pageRange(1, 5)
->page(10)
->withOcr(language: 'eng', workers: 8)
->withDpi(300)
->preserveSmallText();
$document = Parsel::file('invoice.pdf')
->withProviderOptions($options)
->parse();LiteParse options include page selection, maximum pages, OCR settings, DPI, small-text preservation, passwords, Markdown images and links, headers and footers, and a binary override.
use Shipfastlabs\Parsel\Enums\ImageMode;
$markdown = Parsel::file('report.pdf')
->withProviderOptions(
LiteParseOptions::make()
->withoutOcr()
->withImages(ImageMode::Embed, '/path/to/images')
->withoutLinks()
->keepHeadersAndFooters()
)
->markdown();AnyDoc supports explicit input format and binary overrides:
use Shipfastlabs\Parsel\Options\AnyDocOptions;
$markdown = Parsel::driver('anydoc')
->file('data.csv')
->withProviderOptions(
AnyDocOptions::make()->format('csv')
)
->markdown();Array keys are validated, so typos fail early. For a newly released upstream CLI flag, use the explicit escape hatch:
$options = LiteParseOptions::make()->option('new-upstream-flag', 42);
$options = AnyDocOptions::make()->option('new-upstream-flag');$document = Parsel::file('document.pdf')->parse();
echo $document->text;
echo $document->pageCount();
foreach ($document->pages as $page) {
foreach ($page->items as $item) {
echo "{$item->text} @ ({$item->x}, {$item->y})\n";
}
}Stream large documents without decoding the complete page array:
foreach (Parsel::file('large.pdf')->lazyPages() as $page) {
echo $page->text;
}Screenshots require an existing destination directory:
$files = Parsel::file('document.pdf')
->withProviderOptions(LiteParseOptions::make()->pageRange(1, 5)->withDpi(200))
->screenshots('/path/to/screenshots');Each local driver resolves its executable in this order:
- The typed or array provider option
binary. PARSEL_LITEPARSE_BINARYorPARSEL_ANYDOC_BINARY.litoranydoconPATH.
PARSEL_LIT_BINARY remains a fallback for LiteParse during the 1.0 migration.
Implement the minimal Driver contract for Markdown, then opt into additional capability contracts only when the provider supports them.
use Shipfastlabs\Parsel;
use Shipfastlabs\Parsel\Contracts\Driver;
use Shipfastlabs\Parsel\ParseRequest;
use Shipfastlabs\Parsel\ParselManager;
Parsel::extend('company-api', function (ParselManager $manager): Driver {
return new CompanyApiDriver;
});
$markdown = Parsel::driver('company-api')->file('report.pdf')->markdown();Drivers are resolved lazily and cached by the manager. Implement TextDriver, StructuredDocumentDriver, LazyPageDriver, or ScreenshotDriver to add those operations. A remote driver may use any HTTP client and does not need to depend on Parsel's CLI process infrastructure.
Parsel::fake() swaps the shared local process runner and matches canned responses against command substrings:
$fake = Parsel::fake([
'--format json' => file_get_contents(__DIR__.'/fixtures/lit-output.json'),
'anydoc' => '# Converted document',
]);
$document = Parsel::file('invoice.pdf')->parse();
$markdown = Parsel::driver('anydoc')->file('report.docx')->markdown();
expect($fake->ranCount())->toBe(2);See UPGRADE.md when moving from Parsel 0.x.
composer test
vendor/bin/pest --group=integrationParsel is maintained by Shipfastlabs and released under the MIT license.
