From a04cdf99b0f77fa03df181b4a5a2fce51823f42b Mon Sep 17 00:00:00 2001 From: bmcminn Date: Wed, 11 Nov 2020 02:26:56 -0600 Subject: [PATCH] feat(BuildCommand.php): add lifecycle hooks for prehtml and prepdf Adds optional user defined functions to ibis.php that allows users to modify content Fixes #13 --- readme.md | 32 ++++++++++++++++++++--- src/Commands/BuildCommand.php | 48 +++++++++++++++++++++++++---------- stubs/ibis.php | 19 +++++++++++++- 3 files changed, 80 insertions(+), 19 deletions(-) diff --git a/readme.md b/readme.md index 97a2864..4f1673c 100644 --- a/readme.md +++ b/readme.md @@ -1,13 +1,13 @@

Ibis logo - + Artwork by Eric L. Barnes and Caneco from Laravel News ❤️.

--- This PHP tool helps you write eBooks in markdown. Run `ibis build` and an eBook will be generated with: - + 1. A cover photo. 2. Clickable auto-generated table of contents. 3. Code syntax highlighting. @@ -45,7 +45,7 @@ You may configure your book by editing the `/ibis.php` configuration file. ## Writing Your eBook -The `init` command will create sample .md files inside the content folder. You can explore those files to see how you can write your book. This sample content is taken from [Laravel Queues in Action](https://learn-laravel-queues.com). +The `init` command will create sample .md files inside the content folder. You can explore those files to see how you can write your book. This sample content is taken from [Laravel Queues in Action](https://learn-laravel-queues.com). Inside the content directory, you can write multiple `.md` files. Ibis uses the headings to divide the book into parts and chapters: @@ -61,7 +61,7 @@ Inside the content directory, you can write multiple `.md` files. Ibis uses the ### Starting with Ibis

tags define different titles inside a chapter. -``` +``` ## Using Fonts @@ -91,6 +91,30 @@ ibis sample dark This command will use the generated files from the `ibis build` command to generate samples from your PDF eBook. You can configure which pages to include in the sample by updating the `/ibis.php` file. + +## Extending Ibis + +### Build lifecycle hooks + +You can customize your Ibis build process by defining lifecycle hook function(s) in your `ibis.php` config; + +```php +return [ + + 'prehtml' => function($markdown) { + // preprocesses markdown content before converting to HTML + return $markdown; + }, + + 'prepdf' => function($html) { + // preprocesses converted markdown HTML content before writing to PDF + return $html; + }, + + // .. rest of ibis.php config +]; +``` + ## Credits - [Mohamed Said](https://github.com/themsaid) diff --git a/src/Commands/BuildCommand.php b/src/Commands/BuildCommand.php index 25a602c..0078366 100644 --- a/src/Commands/BuildCommand.php +++ b/src/Commands/BuildCommand.php @@ -33,6 +33,12 @@ class BuildCommand extends Command */ private $disk; + /** + * User ibis.php config settings + * @var array + */ + private $_config; + /** * Configure the command. * @@ -62,7 +68,7 @@ public function execute(InputInterface $input, OutputInterface $output) $this->themeName = $input->getArgument('theme'); $currentPath = getcwd(); - $config = require $currentPath.'/ibis.php'; + $this->_config = require $currentPath.'/ibis.php'; $this->ensureExportDirectoryExists( $currentPath = getcwd() @@ -72,7 +78,6 @@ public function execute(InputInterface $input, OutputInterface $output) $this->buildPdf( $this->buildHtml($currentPath.'/content'), - $config, $currentPath, $theme ); @@ -107,6 +112,10 @@ protected function buildHtml(string $path) { $this->output->writeln('==> Parsing Markdown ...'); + if (is_callable($this->_config['prehtml'] ?? null)) { + $this->output->writeln('==> Pre-processing Markdown ...'); + } + $environment = Environment::createCommonMarkEnvironment(); $environment->addBlockRenderer(FencedCode::class, new FencedCodeRenderer([ @@ -125,6 +134,12 @@ protected function buildHtml(string $path) $file->getPathname() ); + + if (is_callable($this->_config['prehtml'] ?? null)) { + $markdown = $this->_config['prehtml']($markdown); + } + + return $this->prepareForPdf( $converter->convertToHtml($markdown), $i + 1 @@ -160,13 +175,12 @@ private function prepareForPdf(string $html, $file) /** * @param string $html - * @param array $config * @param string $currentPath * @param string $theme * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException * @throws \Mpdf\MpdfException */ - protected function buildPdf(string $html, array $config, string $currentPath, string $theme) + protected function buildPdf(string $html, string $currentPath, string $theme) { $defaultConfig = (new ConfigVariables())->getDefaults(); $fontDirs = $defaultConfig['fontDir']; @@ -176,13 +190,13 @@ protected function buildPdf(string $html, array $config, string $currentPath, st $pdf = new Mpdf([ 'mode' => 'utf-8', - 'format' => $config['document']['format'] ?? [210, 297], - 'margin_left' => $config['document']['margin_left'] ?? 27, - 'margin_right' => $config['document']['margin_right'] ?? 27, - 'margin_bottom' => $config['document']['margin_bottom'] ?? 14, - 'margin_top' => $config['document']['margin_top'] ?? 14, + 'format' => $this->_config['document']['format'] ?? [210, 297], + 'margin_left' => $this->_config['document']['margin_left'] ?? 27, + 'margin_right' => $this->_config['document']['margin_right'] ?? 27, + 'margin_bottom' => $this->_config['document']['margin_bottom'] ?? 14, + 'margin_top' => $this->_config['document']['margin_top'] ?? 14, 'fontDir' => array_merge($fontDirs, [getcwd().'/assets/fonts']), - 'fontdata' => $this->fonts($config, $fontData), + 'fontdata' => $this->fonts($fontData), ]); $pdf->SetTitle(Ibis::title()); @@ -207,8 +221,8 @@ protected function buildPdf(string $html, array $config, string $currentPath, st } else { $this->output->writeln('==> Adding Book Cover ...'); - $coverPosition = $config['cover']['position'] ?? 'position: absolute; left:0; right: 0; top: -.2; bottom: 0;'; - $coverDimensions = $config['cover']['dimensions'] ?? 'width: 210mm; height: 297mm; margin: 0;'; + $coverPosition = $this->_config['cover']['position'] ?? 'position: absolute; left:0; right: 0; top: -.2; bottom: 0;'; + $coverDimensions = $this->_config['cover']['dimensions'] ?? 'width: 210mm; height: 297mm; margin: 0;'; $pdf->WriteHTML( <<SetHTMLFooter(''); + + if (is_callable($this->_config['prepdf'] ?? null)) { + $this->output->writeln('==> Pre-processing PDF ...'); + $html = $this->_config['prepdf']($html); + } + $this->output->writeln('==> Building PDF ...'); $pdf->WriteHTML( @@ -254,9 +274,9 @@ private function getTheme($currentPath, $themeName) * @param $fontData * @return array */ - protected function fonts($config, $fontData) + protected function fonts($fontData) { - return $fontData + collect($config['fonts'])->mapWithKeys(function ($file, $name) { + return $fontData + collect($this->_config['fonts'])->mapWithKeys(function ($file, $name) { return [ $name => [ 'R' => $file diff --git a/stubs/ibis.php b/stubs/ibis.php index c5474cc..2abb286 100644 --- a/stubs/ibis.php +++ b/stubs/ibis.php @@ -1,5 +1,22 @@ 'This is a sample from "Laravel Queues in Action" by Mohamed Said.
+ 'sample_notice' => 'This is a sample from "Laravel Queues in Action" by Mohamed Said.
For more information, Click here.', ];