{"id":24916840,"url":"https://github.com/smnandre/pandoc","last_synced_at":"2026-02-24T02:04:01.468Z","repository":{"id":275379168,"uuid":"907650398","full_name":"smnandre/pandoc","owner":"smnandre","description":"Pandoc PHP - Advanced Document Converter","archived":false,"fork":false,"pushed_at":"2025-02-03T01:06:52.000Z","size":41,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-14T19:07:29.702Z","etag":null,"topics":["converter","convertion","document","docx","html","latex","markdown","pandoc","pandoc-php","pdf","php-cli","php-library","rst","symfony-console"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/smnandre.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["smnandre"]}},"created_at":"2024-12-24T04:36:35.000Z","updated_at":"2025-02-03T01:06:55.000Z","dependencies_parsed_at":"2025-02-02T05:17:16.148Z","dependency_job_id":"c41366e7-7542-4461-8f30-701447087de6","html_url":"https://github.com/smnandre/pandoc","commit_stats":null,"previous_names":["smnandre/pandoc"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smnandre%2Fpandoc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smnandre%2Fpandoc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smnandre%2Fpandoc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smnandre%2Fpandoc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/smnandre","download_url":"https://codeload.github.com/smnandre/pandoc/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248943456,"owners_count":21186958,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["converter","convertion","document","docx","html","latex","markdown","pandoc","pandoc-php","pdf","php-cli","php-library","rst","symfony-console"],"created_at":"2025-02-02T08:18:40.026Z","updated_at":"2026-02-24T02:04:01.463Z","avatar_url":"https://github.com/smnandre.png","language":"PHP","funding_links":["https://github.com/sponsors/smnandre"],"categories":[],"sub_categories":[],"readme":"\u003ch1\u003e\u003cpicture\u003e\n\u003csource media=\"(prefers-color-scheme: light)\" srcset=\"./pandoc.svg\" /\u003e\n\u003cimg src=\"./pandoc.dark.svg\" alt=\"PANDOC PHP - Document Converter\" width=\"100%\" /\u003e\n\u003c/picture\u003e\u003c/h1\u003e\n\u003cdiv align=\"center\"\u003e\n\n\u0026nbsp; ![PHP Version](https://img.shields.io/badge/PHP-8.3+-2e7d32?logoColor=6AB76E\u0026labelColor=010)\n\u0026nbsp; ![CI](https://img.shields.io/github/actions/workflow/status/smnandre/pandoc/CI.yaml?branch=main\u0026label=Tests\u0026logoColor=white\u0026logoSize=auto\u0026labelColor=010\u0026color=388e3c)\n\u0026nbsp; ![Release](https://img.shields.io/github/v/release/smnandre/pandoc?label=Stable\u0026logoColor=white\u0026logoSize=auto\u0026labelColor=010\u0026color=43a047)\n\u0026nbsp; [![GitHub Sponsors](https://img.shields.io/github/sponsors/smnandre?logo=github-sponsors\u0026logoColor=66bb6a\u0026logoSize=auto\u0026label=%20Sponsor\u0026labelColor=010\u0026color=a5d6a7)](https://github.com/sponsors/smnandre)\n\u0026nbsp; ![License](https://img.shields.io/github/license/smnandre/pandoc?label=License\u0026logoColor=white\u0026logoSize=auto\u0026labelColor=010\u0026color=2e7d32)\n\nPHP [Pandoc](https://pandoc.org/) Document Converter. Typed, tested \u0026 mockable.\n\n\u003c/div\u003e\n\n---\n\n## Why Pandoc PHP\n\nReplace shell commands with type-safe objects and structured error handling.\n\n```php\n$html = Pandoc::convert('# Hello', 'html');     // Static facade for quick tasks\n\n$html = new Converter()                         // ConverterInterface \n    -\u003efile('document.txt')\n    -\u003eto('html')\n    -\u003egetContent();                             // Traceable, testable, mockable\n    \nPandoc::file('reporting.md')                    // Options, variables,  metadata      \n    -\u003eoption('toc', true)\n    -\u003emetadata('author', 'John Doe')\n    -\u003evariable('title', 'My Document')\n```\n\n- **60+ formats** - **Markdown**, **HTML**, PDF, DOCX, LaTeX, **RST**, EPUB, RTF, and more\n- **Dual API Design** - Static `Pandoc` facade for quick tasks, `ConverterInterface` for dependency injection\n- **Smart Format Detection** - Auto-detects input/output formats from file extensions and content patterns\n- **Unit Testing** - `MockConverter` for tests without Pandoc installation, real Pandoc for integration\n- **Production Ready** - PHPStan level 10, full test coverage, rich error handling\n\n---\n\n## Installation\n\n### Requirements\n\n- PHP 8.3 or higher\n- Pandoc (see below)\n\n### Pandoc PHP\n\nInstall via Composer.\n\n```bash\ncomposer require smnandre/pandoc\n```\n\n### Pandoc Binary\n\nInstall Pandoc first using your system package manager.\n\n```bash\n# Ubuntu/Debian\nsudo apt-get install pandoc\n\n# macOS  \nbrew install pandoc\n```\n\n---\n\n## Usage\n\n### Input\n\nSpecify source content using string input, file paths, or explicit format overrides when automatic detection fails.\n\n```php\n// String content with automatic format detection\n$converter = Pandoc::content('# Hello World');\n\n// File input with extension-based format detection\n$converter = Pandoc::file('document.md');\n\n// Override automatic format detection when needed\n$converter = Pandoc::content($data)-\u003efrom('markdown');\n\n// Check format compatibility\nif (Pandoc::supports('markdown', 'pdf')) {\n    // Proceed with conversion\n}\n```\n\n### Output\n\nControl conversion targets through format specification, file destinations, or directory outputs.\n\n```php\n// Get content as string\n$htmlContent = Pandoc::file('doc.md')-\u003eto('html')-\u003econvert()-\u003egetContent();\n\n// Save to specific file path\nPandoc::file('doc.md')-\u003eto('pdf')-\u003eoutput('reports/final-report.pdf')-\u003econvert();\n\n// Save to directory (filename inferred from input)\nPandoc::file('doc.md')-\u003eto('pdf')-\u003eoutput('reports/')-\u003econvert();\n\n// Save to file (format inferred from extension)\nPandoc::file('doc.md')-\u003eoutput('documentation.html')-\u003econvert();\n```\n\n### Options\n\nConfigure Pandoc behavior using individual options, batch option arrays, template variables, or document metadata.\n\n```php\n// Individual option configuration\n$converter-\u003eoption('toc', true)-\u003eoption('standalone', true);\n\n// Batch option setting\n$converter-\u003eoptions(['toc' =\u003e true, 'number-sections' =\u003e true]);\n\n// Template variables and metadata\n$converter-\u003evariable('title', 'Report')-\u003evariable('grade', 'A+');\n\n// Document metadata for publishing workflows\n$converter-\u003emetadata('author', 'The Team')-\u003emetadata('date', '2025-01-01');\n```\n\n### Configuration\n\nFramework integration and custom binary paths for non-standard installations.\n\n```php\n// Custom binary path configuration\n$binary = PandocBinary::fromPath('/opt/pandoc/bin/pandoc');\nPandoc::setDefaultBinary($binary);\n\n// Check supported formats\nPandoc::getInputFormats();  // Get all supported input formats\nPandoc::getOutputFormats(); // Get all supported output formats\nPandoc::supports('markdown', 'html'); // Check if conversion is supported\n```\n\n### Test\n\nUnit testing with `MockConverter` records method calls without requiring Pandoc installation. Integration testing\nverifies actual Pandoc functionality.\n\n```php\n// Unit testing with MockConverter\nclass DocumentServiceTest extends TestCase\n{\n    public function testGenerateReport(): void\n    {\n        $mock = new MockConverter();\n        $service = new DocumentService($mock);\n        $service-\u003ecreateReport('# Test');\n        \n        // Verify calls without external dependencies\n        $calls = $mock-\u003egetCalls();\n\n        $this-\u003eassertCount(1, $calls);\n        $this-\u003eassertEquals('# Test', $calls[0]['inputContent']);\n        $this-\u003eassertEquals('html', $calls[0]['outputFormat']);\n        $this-\u003eassertTrue($calls[0]['options']['standalone']);\n    }\n}\n\n// Integration testing with real Pandoc\nclass PandocIntegrationTest extends TestCase\n{\n    public function testConversion(): void\n    {\n        if (!Pandoc::isInstalled()) {\n            $this-\u003emarkTestSkipped('Pandoc not installed');\n        }\n        \n        $html = Pandoc::content('# Test')-\u003eto('html')-\u003econvert()-\u003egetContent();\n        $this-\u003eassertStringContainsString('\u003ch1\u003eTest\u003c/h1\u003e', $html);\n    }\n}\n```\n\n---\n\n## Examples\n\nConvert **multiple Markdown files** to **HTML**\n\n```php\n$posts = glob('content/*.md');\nforeach ($posts as $post) {\n    Pandoc::convertFile($post, 'public/'.basename($post, '.md').'.html');\n}\n```\n\nGenerate **academic paper** with **citations and formatting**\n\n```php\n$result = Pandoc::file('manuscript.md')\n    -\u003eto('pdf')\n    -\u003eoption('toc', true)\n    -\u003eoption('bibliography', 'references.bib')\n    -\u003evariable('title', 'Research Paper')\n    -\u003evariable('author', 'The Team')\n    -\u003econvert();\n```\n\nHandle **document conversion** in web applications with **error handling**\n\n```php\nclass DocumentController {\n    public function convert(Request $request): Response {\n        $result = $this-\u003econverter-\u003econtent($request-\u003egetContent())-\u003eto('html')-\u003econvert();\n        \n        if (!$result-\u003eisSuccess()) {\n            throw new BadRequestHttpException($result-\u003egetError());\n        }\n        \n        return new Response($result-\u003egetContent());\n    }\n}\n```\n\n---\n\n## Troubleshooting\n\n### Pandoc not found\n\nThis error occurs when the library cannot find the pandoc executable in your system PATH.\n\n```php\n// Solution: Specify custom binary path\nuse Pandoc\\PandocBinary;\n\n$binary = PandocBinary::fromPath('/opt/pandoc/bin/pandoc');\nPandoc::setDefaultBinary($binary);\n```\n\n### Format detection\n\nAutomatic format detection fails when file extensions are missing or content format is ambiguous.\n\n```php\n// Solution: Explicitly specify input and output formats\n$result = Pandoc::content($unknownContent)\n    -\u003efrom('markdown')  // Override input format detection\n    -\u003eto('html')        // Ensure output format is clear\n    -\u003econvert();\n```\n\n### Conversion errors\n\nPandoc conversion failures provide detailed error messages through the result object.\n\n```php\n$result = Pandoc::file('input.md')-\u003eto('pdf')-\u003econvert();\n\nif (!$result-\u003eisSuccess()) {\n    // Access detailed error information from Pandoc\n    $errorMessage = $result-\u003egetError();\n    echo \"Conversion failed: \" . $errorMessage;\n}\n```\n\n---\n\n## Contributing\n\nContributions are welcome! Please start by creating an issue to discuss your changes.\n\n---\n\n## Credits\n\nBuilt on [Pandoc](https://pandoc.org/) by John MacFarlane.\n\nCreated and maintained by [Simon André](https://github.com/smnandre).\n\n\u003e [!TIP]\n\u003e This library is developed and maintained by a single developer in their free time.\n\u003e\n\u003e To ensure continued maintenance and improvements, consider [sponsoring development](https://github.com/sponsors/smnandre).\n\n---\n\n## License\n\nMIT License - see [LICENSE](LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmnandre%2Fpandoc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsmnandre%2Fpandoc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmnandre%2Fpandoc/lists"}