Skip to content

Commit a04cdf9

Browse files
committed
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
1 parent 6263256 commit a04cdf9

File tree

3 files changed

+80
-19
lines changed

3 files changed

+80
-19
lines changed

readme.md

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
<p align="center">
22
<img src="https://raw.githubusercontent.com/themsaid/ibis/master/art/cover.png" alt="Ibis logo" width="480">
3-
3+
44
Artwork by <a href="https://twitter.com/ericlbarnes">Eric L. Barnes</a> and <a href="https://twitter.com/Caneco">Caneco</a> from <a href="https://laravel-news.com/ibis-book-maker">Laravel News</a> ❤️.
55
</p>
66

77
---
88

99
This PHP tool helps you write eBooks in markdown. Run `ibis build` and an eBook will be generated with:
10-
10+
1111
1. A cover photo.
1212
2. Clickable auto-generated table of contents.
1313
3. Code syntax highlighting.
@@ -45,7 +45,7 @@ You may configure your book by editing the `/ibis.php` configuration file.
4545

4646
## Writing Your eBook
4747

48-
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).
48+
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).
4949

5050
Inside the content directory, you can write multiple `.md` files. Ibis uses the headings to divide the book into parts and chapters:
5151

@@ -61,7 +61,7 @@ Inside the content directory, you can write multiple `.md` files. Ibis uses the
6161
### Starting with Ibis
6262
6363
<h3> tags define different titles inside a chapter.
64-
```
64+
```
6565

6666
## Using Fonts
6767

@@ -91,6 +91,30 @@ ibis sample dark
9191

9292
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.
9393

94+
95+
## Extending Ibis
96+
97+
### Build lifecycle hooks
98+
99+
You can customize your Ibis build process by defining lifecycle hook function(s) in your `ibis.php` config;
100+
101+
```php
102+
return [
103+
104+
'prehtml' => function($markdown) {
105+
// preprocesses markdown content before converting to HTML
106+
return $markdown;
107+
},
108+
109+
'prepdf' => function($html) {
110+
// preprocesses converted markdown HTML content before writing to PDF
111+
return $html;
112+
},
113+
114+
// .. rest of ibis.php config
115+
];
116+
```
117+
94118
## Credits
95119

96120
- [Mohamed Said](https://github.com/themsaid)

src/Commands/BuildCommand.php

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ class BuildCommand extends Command
3333
*/
3434
private $disk;
3535

36+
/**
37+
* User ibis.php config settings
38+
* @var array
39+
*/
40+
private $_config;
41+
3642
/**
3743
* Configure the command.
3844
*
@@ -62,7 +68,7 @@ public function execute(InputInterface $input, OutputInterface $output)
6268
$this->themeName = $input->getArgument('theme');
6369

6470
$currentPath = getcwd();
65-
$config = require $currentPath.'/ibis.php';
71+
$this->_config = require $currentPath.'/ibis.php';
6672

6773
$this->ensureExportDirectoryExists(
6874
$currentPath = getcwd()
@@ -72,7 +78,6 @@ public function execute(InputInterface $input, OutputInterface $output)
7278

7379
$this->buildPdf(
7480
$this->buildHtml($currentPath.'/content'),
75-
$config,
7681
$currentPath,
7782
$theme
7883
);
@@ -107,6 +112,10 @@ protected function buildHtml(string $path)
107112
{
108113
$this->output->writeln('<fg=yellow>==></> Parsing Markdown ...');
109114

115+
if (is_callable($this->_config['prehtml'] ?? null)) {
116+
$this->output->writeln('<fg=yellow>==></> Pre-processing Markdown ...');
117+
}
118+
110119
$environment = Environment::createCommonMarkEnvironment();
111120

112121
$environment->addBlockRenderer(FencedCode::class, new FencedCodeRenderer([
@@ -125,6 +134,12 @@ protected function buildHtml(string $path)
125134
$file->getPathname()
126135
);
127136

137+
138+
if (is_callable($this->_config['prehtml'] ?? null)) {
139+
$markdown = $this->_config['prehtml']($markdown);
140+
}
141+
142+
128143
return $this->prepareForPdf(
129144
$converter->convertToHtml($markdown),
130145
$i + 1
@@ -160,13 +175,12 @@ private function prepareForPdf(string $html, $file)
160175

161176
/**
162177
* @param string $html
163-
* @param array $config
164178
* @param string $currentPath
165179
* @param string $theme
166180
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
167181
* @throws \Mpdf\MpdfException
168182
*/
169-
protected function buildPdf(string $html, array $config, string $currentPath, string $theme)
183+
protected function buildPdf(string $html, string $currentPath, string $theme)
170184
{
171185
$defaultConfig = (new ConfigVariables())->getDefaults();
172186
$fontDirs = $defaultConfig['fontDir'];
@@ -176,13 +190,13 @@ protected function buildPdf(string $html, array $config, string $currentPath, st
176190

177191
$pdf = new Mpdf([
178192
'mode' => 'utf-8',
179-
'format' => $config['document']['format'] ?? [210, 297],
180-
'margin_left' => $config['document']['margin_left'] ?? 27,
181-
'margin_right' => $config['document']['margin_right'] ?? 27,
182-
'margin_bottom' => $config['document']['margin_bottom'] ?? 14,
183-
'margin_top' => $config['document']['margin_top'] ?? 14,
193+
'format' => $this->_config['document']['format'] ?? [210, 297],
194+
'margin_left' => $this->_config['document']['margin_left'] ?? 27,
195+
'margin_right' => $this->_config['document']['margin_right'] ?? 27,
196+
'margin_bottom' => $this->_config['document']['margin_bottom'] ?? 14,
197+
'margin_top' => $this->_config['document']['margin_top'] ?? 14,
184198
'fontDir' => array_merge($fontDirs, [getcwd().'/assets/fonts']),
185-
'fontdata' => $this->fonts($config, $fontData),
199+
'fontdata' => $this->fonts($fontData),
186200
]);
187201

188202
$pdf->SetTitle(Ibis::title());
@@ -207,8 +221,8 @@ protected function buildPdf(string $html, array $config, string $currentPath, st
207221
} else {
208222
$this->output->writeln('<fg=yellow>==></> Adding Book Cover ...');
209223

210-
$coverPosition = $config['cover']['position'] ?? 'position: absolute; left:0; right: 0; top: -.2; bottom: 0;';
211-
$coverDimensions = $config['cover']['dimensions'] ?? 'width: 210mm; height: 297mm; margin: 0;';
224+
$coverPosition = $this->_config['cover']['position'] ?? 'position: absolute; left:0; right: 0; top: -.2; bottom: 0;';
225+
$coverDimensions = $this->_config['cover']['dimensions'] ?? 'width: 210mm; height: 297mm; margin: 0;';
212226

213227
$pdf->WriteHTML(
214228
<<<HTML
@@ -223,6 +237,12 @@ protected function buildPdf(string $html, array $config, string $currentPath, st
223237

224238
$pdf->SetHTMLFooter('<div id="footer" style="text-align: center">{PAGENO}</div>');
225239

240+
241+
if (is_callable($this->_config['prepdf'] ?? null)) {
242+
$this->output->writeln('<fg=yellow>==></> Pre-processing PDF ...');
243+
$html = $this->_config['prepdf']($html);
244+
}
245+
226246
$this->output->writeln('<fg=yellow>==></> Building PDF ...');
227247

228248
$pdf->WriteHTML(
@@ -254,9 +274,9 @@ private function getTheme($currentPath, $themeName)
254274
* @param $fontData
255275
* @return array
256276
*/
257-
protected function fonts($config, $fontData)
277+
protected function fonts($fontData)
258278
{
259-
return $fontData + collect($config['fonts'])->mapWithKeys(function ($file, $name) {
279+
return $fontData + collect($this->_config['fonts'])->mapWithKeys(function ($file, $name) {
260280
return [
261281
$name => [
262282
'R' => $file

stubs/ibis.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
11
<?php
22

3+
4+
if (!function_exists('prehtml')) {
5+
function prehtml($markdown) {
6+
// preprocesses markdown content before converting to HTML
7+
return $markdown;
8+
}
9+
}
10+
11+
12+
if (!function_exists('prepdf')) {
13+
function prepdf($html) {
14+
// preprocesses converted markdown HTML content before writing to PDF
15+
return $html;
16+
}
17+
}
18+
19+
320
return [
421
/**
522
* The book title.
@@ -56,6 +73,6 @@
5673
/**
5774
* A notice printed at the final page of a generated sample.
5875
*/
59-
'sample_notice' => 'This is a sample from "Laravel Queues in Action" by Mohamed Said. <br>
76+
'sample_notice' => 'This is a sample from "Laravel Queues in Action" by Mohamed Said. <br>
6077
For more information, <a href="https://www.learn-laravel-queues.com/">Click here</a>.',
6178
];

0 commit comments

Comments
 (0)