From b2938b05005038778d85ecffd8899908c33e8109 Mon Sep 17 00:00:00 2001 From: Roberto Butti Date: Thu, 21 Dec 2023 17:52:15 +0100 Subject: [PATCH] Refactoring common code for PDF and EPUB commands --- src/Commands/BaseBuildCommand.php | 172 ++++++++++++++++++++++++++ src/Commands/BuildCommand.php | 158 ++++-------------------- src/Commands/EpubCommand.php | 192 ++++-------------------------- 3 files changed, 217 insertions(+), 305 deletions(-) create mode 100644 src/Commands/BaseBuildCommand.php diff --git a/src/Commands/BaseBuildCommand.php b/src/Commands/BaseBuildCommand.php new file mode 100644 index 0000000..9693c0a --- /dev/null +++ b/src/Commands/BaseBuildCommand.php @@ -0,0 +1,172 @@ +disk = new Filesystem(); + $this->output = $output; + + $this->currentPath = getcwd(); + + $this->contentDirectory = $input->getOption('content'); + if ($this->contentDirectory === "") { + $this->contentDirectory = getcwd() . DIRECTORY_SEPARATOR . "content"; + } + if (!$this->disk->isDirectory($this->contentDirectory)) { + $this->output->writeln('Error, check if ' . $this->contentDirectory . ' exists.'); + exit -1; + } + $this->output->writeln('Loading content from: ' . $this->contentDirectory . ''); + + $configIbisFile = $this->currentPath . '/ibis.php'; + if (!$this->disk->isFile($configIbisFile)) { + $this->output->writeln('Error, check if ' . $configIbisFile . ' exists.'); + exit -1; + } + + $this->config = require $configIbisFile; + + } + + + /** + * @param string $path + * @param array $config + * @return Collection + */ + protected function buildHtml(string $path, array $config): Collection + { + $this->output->writeln('==> Parsing Markdown ...'); + + + $environment = new Environment([]); + $environment->addExtension(new CommonMarkCoreExtension()); + $environment->addExtension(new GithubFlavoredMarkdownExtension()); + $environment->addExtension(new TableExtension()); + $environment->addExtension(new FrontMatterExtension()); + + $environment->addRenderer(FencedCode::class, new FencedCodeRenderer([ + 'html', 'php', 'js', 'bash', 'json' + ])); + $environment->addRenderer(IndentedCode::class, new IndentedCodeRenderer([ + 'html', 'php', 'js', 'bash', 'json' + ])); + + if (is_callable($config['configure_commonmark'])) { + call_user_func($config['configure_commonmark'], $environment); + } + + $converter = new MarkdownConverter($environment); + + return collect($this->disk->allFiles($path)) + ->map(function (SplFileInfo $file, $i) use ($converter) { + + $chapter = collect([]); + if ($file->getExtension() != 'md') { + $chapter["mdfile"] = $file->getFilename(); + $chapter["frontmatter"] = false; + $chapter["html"] = ""; + return $chapter; + } + + $markdown = $this->disk->get( + $file->getPathname() + ); + + + //$chapter = collect([]); + $convertedMarkdown = $converter->convert($markdown); + $chapter["mdfile"] = $file->getFilename(); + $chapter["frontmatter"] = false; + if ($convertedMarkdown instanceof RenderedContentWithFrontMatter) { + $chapter["frontmatter"] = $convertedMarkdown->getFrontMatter(); + } + $chapter["html"] = $this->prepareHtmlForEbook( + $convertedMarkdown->getContent(), + $i + 1 + ); + + + return $chapter; + }); + //->implode(' '); + } + + + /** + * @param string $html + * @param $file + * @return string|string[] + */ + protected function prepareHtmlForEbook(string $html, $file) + { + $commands = [ + '[break]' => '
' + ]; + + if ($file > 1) { + $html = str_replace('

', '[break]

', $html); + } + + $html = str_replace('

', '[break]

', $html); + $html = str_replace("
\n

{notice}", "

Notice:", $html); + $html = str_replace("

\n

{warning}", "

Warning:", $html); + $html = str_replace("

\n

{quote}", "

", $html); + + $html = str_replace(array_keys($commands), array_values($commands), $html); + + return $html; + } + + + + /** + * @param string $currentPath + */ + protected function ensureExportDirectoryExists(string $currentPath): void + { + $this->output->writeln('==> Preparing Export Directory ...'); + + if (!$this->disk->isDirectory($currentPath . '/export')) { + $this->disk->makeDirectory( + $currentPath . '/export', + 0755, + true + ); + } + } + +} diff --git a/src/Commands/BuildCommand.php b/src/Commands/BuildCommand.php index 28d2276..c71cf23 100644 --- a/src/Commands/BuildCommand.php +++ b/src/Commands/BuildCommand.php @@ -4,46 +4,32 @@ use Ibis\Ibis; use Mpdf\Mpdf; -use SplFileInfo; + use Mpdf\Config\FontVariables; use Mpdf\Config\ConfigVariables; -use League\CommonMark\Environment\Environment; -use Illuminate\Filesystem\Filesystem; + use Illuminate\Support\Arr; use Illuminate\Support\Collection; use Symfony\Component\Console\Command\Command; -use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension; -use League\CommonMark\Extension\CommonMark\Node\Block\FencedCode; -use League\CommonMark\Extension\CommonMark\Node\Block\IndentedCode; -use League\CommonMark\Extension\FrontMatter\FrontMatterExtension; -use League\CommonMark\Extension\FrontMatter\Output\RenderedContentWithFrontMatter; -use League\CommonMark\Extension\GithubFlavoredMarkdownExtension; + use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; -use Spatie\CommonMarkHighlighter\FencedCodeRenderer; -use League\CommonMark\Extension\Table\TableExtension; use Symfony\Component\Console\Output\OutputInterface; -use League\CommonMark\MarkdownConverter; -use Spatie\CommonMarkHighlighter\IndentedCodeRenderer; +use Symfony\Component\Console\Input\InputOption; -class BuildCommand extends Command +class BuildCommand extends BaseBuildCommand { /** * @var string|string[]|null */ public $themeName; - /** - * @var OutputInterface - */ - private $output; - /** - * @var Filesystem - */ - private $disk; + + + /** * Configure the command. @@ -55,6 +41,13 @@ protected function configure() $this ->setName('build') ->addArgument('theme', InputArgument::OPTIONAL, 'The name of the theme', 'light') + ->addOption( + 'content', + 'c', + InputOption::VALUE_OPTIONAL, + 'The path of the content directory', + '' + ) ->setDescription('Generate the book.'); } @@ -69,28 +62,18 @@ protected function configure() */ public function execute(InputInterface $input, OutputInterface $output): int { - $this->disk = new Filesystem(); - $this->output = $output; - $this->themeName = $input->getArgument('theme'); - $currentPath = getcwd(); - $configIbisFile = $currentPath . '/ibis.php'; - if (!$this->disk->isFile($configIbisFile)) { - $this->output->writeln('Error, check if ' . $configIbisFile . ' exists.'); - exit -1; - } + $this->preExecute($input, $output); + $this->themeName = $input->getArgument('theme'); - $config = require $configIbisFile; - $this->ensureExportDirectoryExists( - $currentPath = getcwd() - ); + $this->ensureExportDirectoryExists($this->currentPath); - $theme = $this->getTheme($currentPath, $this->themeName); + $theme = $this->getTheme($this->currentPath, $this->themeName); $this->buildPdf( - $this->buildHtml($currentPath . '/content', $config), - $config, - $currentPath, + $this->buildHtml($this->contentDirectory, $this->config), + $this->config, + $this->currentPath, $theme ); @@ -100,104 +83,10 @@ public function execute(InputInterface $input, OutputInterface $output): int return 0; } - /** - * @param string $currentPath - */ - protected function ensureExportDirectoryExists(string $currentPath): void - { - $this->output->writeln('==> Preparing Export Directory ...'); - - if (!$this->disk->isDirectory($currentPath . '/export')) { - $this->disk->makeDirectory( - $currentPath . '/export', - 0755, - true - ); - } - } - - /** - * @param string $path - * @param array $config - * @return Collection - */ - protected function buildHtml(string $path, array $config) - { - $this->output->writeln('==> Parsing Markdown ...'); - - - $environment = new Environment([]); - $environment->addExtension(new CommonMarkCoreExtension()); - $environment->addExtension(new GithubFlavoredMarkdownExtension()); - $environment->addExtension(new TableExtension()); - $environment->addExtension(new FrontMatterExtension()); - - $environment->addRenderer(FencedCode::class, new FencedCodeRenderer([ - 'html', 'php', 'js', 'bash', 'json' - ])); - $environment->addRenderer(IndentedCode::class, new IndentedCodeRenderer([ - 'html', 'php', 'js', 'bash', 'json' - ])); - - if (is_callable($config['configure_commonmark'])) { - call_user_func($config['configure_commonmark'], $environment); - } - - $converter = new MarkdownConverter($environment); - - return collect($this->disk->files($path)) - ->map(function (SplFileInfo $file, $i) use ($converter) { - if ($file->getExtension() != 'md') { - return ''; - } - - $markdown = $this->disk->get( - $file->getPathname() - ); - - - $chapter = collect([]); - $convertedMarkdown = $converter->convert($markdown); - $chapter["mdfile"] = $file->getFilename(); - $chapter["frontmatter"] = false; - if ($convertedMarkdown instanceof RenderedContentWithFrontMatter) { - $chapter["frontmatter"] = $convertedMarkdown->getFrontMatter(); - } - $chapter["html"] = $this->prepareForPdf( - $convertedMarkdown->getContent(), - $i + 1 - ); - - - return $chapter; - }); - //->implode(' '); - } - - /** - * @param string $html - * @param $file - * @return string|string[] - */ - private function prepareForPdf(string $html, $file) - { - $commands = [ - '[break]' => '

' - ]; - if ($file > 1) { - $html = str_replace('

', '[break]

', $html); - } - $html = str_replace('

', '[break]

', $html); - $html = str_replace("
\n

{notice}", "

Notice:", $html); - $html = str_replace("

\n

{warning}", "

Warning:", $html); - $html = str_replace("

\n

{quote}", "

", $html); - $html = str_replace(array_keys($commands), array_values($commands), $html); - return $html; - } /** * @param Collection $chapters @@ -278,8 +167,9 @@ protected function buildPdf(Collection $chapters, array $config, string $current $pdf->WriteHTML( $theme ); - + //dd($chapters); foreach ($chapters as $key => $chapter) { + //if ( is_string($chapter) ) { dd($key, $chapter);} $this->output->writeln('==> ❇️ ' . $chapter["mdfile"] . ' ...'); if (array_key_exists('header', $config)) { $pdf->SetHTMLHeader( diff --git a/src/Commands/EpubCommand.php b/src/Commands/EpubCommand.php index 7a05ad3..1e89478 100644 --- a/src/Commands/EpubCommand.php +++ b/src/Commands/EpubCommand.php @@ -3,47 +3,19 @@ namespace Ibis\Commands; use Ibis\Ibis; -use SplFileInfo; use Mpdf\Config\FontVariables; use Mpdf\Config\ConfigVariables; -use League\CommonMark\Environment\Environment; -use Illuminate\Filesystem\Filesystem; use Illuminate\Support\Arr; use Illuminate\Support\Collection; use Symfony\Component\Console\Command\Command; -use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension; -use League\CommonMark\Extension\CommonMark\Node\Block\FencedCode; -use League\CommonMark\Extension\CommonMark\Node\Block\IndentedCode; -use League\CommonMark\Extension\FrontMatter\FrontMatterExtension; -use League\CommonMark\Extension\FrontMatter\Output\RenderedContentWithFrontMatter; -use League\CommonMark\Extension\GithubFlavoredMarkdownExtension; -use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; -use Spatie\CommonMarkHighlighter\FencedCodeRenderer; -use League\CommonMark\Extension\Table\TableExtension; use Symfony\Component\Console\Output\OutputInterface; -use League\CommonMark\MarkdownConverter; use PHPePub\Core\EPub; -use Spatie\CommonMarkHighlighter\IndentedCodeRenderer; +use Symfony\Component\Console\Input\InputOption; -class EpubCommand extends Command +class EpubCommand extends BaseBuildCommand { - /** - * @var string|string[]|null - */ - public $themeName; - - /** - * @var OutputInterface - */ - private $output; - - /** - * @var Filesystem - */ - private $disk; - /** * Configure the command. * @@ -53,7 +25,13 @@ protected function configure() { $this ->setName('epub') - ->addArgument('theme', InputArgument::OPTIONAL, 'The name of the theme', 'light') + ->addOption( + 'content', + 'c', + InputOption::VALUE_OPTIONAL, + 'The path of the content directory', + '' + ) ->setDescription('Generate the book in Epub format.'); } @@ -74,29 +52,17 @@ public function execute(InputInterface $input, OutputInterface $output): int $this->output->writeln('✨ Stay tuned!! ✨'); $this->output->writeln('✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨'); //return 0; - $this->disk = new Filesystem(); - $this->output = $output; - $this->themeName = $input->getArgument('theme'); - $currentPath = getcwd(); - $configIbisFile = $currentPath . '/ibis.php'; - if (!$this->disk->isFile($configIbisFile)) { - $this->output->writeln('Error, check if ' . $configIbisFile . ' exists.'); - exit -1; - } + $this->preExecute($input, $output); + + - $config = require $configIbisFile; - $this->ensureExportDirectoryExists( - $currentPath = getcwd() - ); - $theme = $this->getTheme($currentPath, $this->themeName); $result = $this->buildEpub( - $this->buildHtml($currentPath . '/content', $config), - $config, - $currentPath, - $theme + $this->buildHtml($this->contentDirectory, $this->config), + $this->config, + $this->currentPath ); $this->output->writeln(''); @@ -111,105 +77,7 @@ public function execute(InputInterface $input, OutputInterface $output): int return 0; } - /** - * @param string $currentPath - */ - protected function ensureExportDirectoryExists(string $currentPath): void - { - $this->output->writeln('==> Preparing Export Directory ...'); - - if (!$this->disk->isDirectory($currentPath . '/export')) { - $this->disk->makeDirectory( - $currentPath . '/export', - 0755, - true - ); - } - } - - /** - * @param string $path - * @param array $config - * @return Collection - */ - protected function buildHtml(string $path, array $config) - { - - $this->output->writeln('==> Parsing Markdown ...'); - - - $environment = new Environment([]); - $environment->addExtension(new CommonMarkCoreExtension()); - $environment->addExtension(new GithubFlavoredMarkdownExtension()); - $environment->addExtension(new TableExtension()); - $environment->addExtension(new FrontMatterExtension()); - - $environment->addRenderer(FencedCode::class, new FencedCodeRenderer([ - 'html', 'php', 'js', 'bash', 'json' - ])); - $environment->addRenderer(IndentedCode::class, new IndentedCodeRenderer([ - 'html', 'php', 'js', 'bash', 'json' - ])); - - if (is_callable($config['configure_commonmark'])) { - call_user_func($config['configure_commonmark'], $environment); - } - - $converter = new MarkdownConverter($environment); - - return collect($this->disk->files($path)) - ->map(function (SplFileInfo $file, $i) use ($converter) { - if ($file->getExtension() != 'md') { - return ''; - } - - $markdown = $this->disk->get( - $file->getPathname() - ); - - - $chapter = collect([]); - $convertedMarkdown = $converter->convert($markdown); - $chapter["mdfile"] = $file->getFilename(); - $chapter["frontmatter"] = false; - if ($convertedMarkdown instanceof RenderedContentWithFrontMatter) { - $chapter["frontmatter"] = $convertedMarkdown->getFrontMatter(); - } - $chapter["html"] = $this->prepareForPdf( - $convertedMarkdown->getContent(), - $i + 1 - ); - - - return $chapter; - }); - //->implode(' '); - } - - /** - * @param string $html - * @param $file - * @return string|string[] - */ - private function prepareForPdf(string $html, $file) - { - $commands = [ - '[break]' => '

' - ]; - if ($file > 1) { - $html = str_replace('

', '[break]

', $html); - } - - $html = str_replace('

', '[break]

', $html); - $html = str_replace("
\n

{notice}", "

Notice:", $html); - $html = str_replace("

\n

{warning}", "

Warning:", $html); - $html = str_replace("

\n

{quote}", "

", $html); - - $html = str_replace(array_keys($commands), array_values($commands), $html); - - return $html; - } /** * @param Collection $chapters @@ -219,7 +87,7 @@ private function prepareForPdf(string $html, $file) * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException * @throws \Mpdf\MpdfException */ - protected function buildEpub(Collection $chapters, array $config, string $currentPath, string $theme) + protected function buildEpub(Collection $chapters, array $config, string $currentPath) { $defaultConfig = (new ConfigVariables())->getDefaults(); $fontDirs = $defaultConfig['fontDir']; @@ -254,13 +122,8 @@ protected function buildEpub(Collection $chapters, array $config, string $curren $book->setAuthor(Ibis::author(), Ibis::author()); $book->setIdentifier(Ibis::title() . "&stamp=" . time(), EPub::IDENTIFIER_URI); $book->setLanguage("en"); - //$cssData = "body {\n margin-left: .5em;\n margin-right: .5em;\n text-align: justify;\n}\n\np {\n font-family: serif;\n font-size: 10pt;\n text-align: justify;\n text-indent: 1em;\n margin-top: 0px;\n margin-bottom: 1ex;\n}\n\nh1, h2 {\n font-family: sans-serif;\n font-style: italic;\n text-align: center;\n background-color: #6b879c;\n color: yellow;\n width: 100%;\n}\n\nh1 {\n margin-bottom: 2px;\n}\n\nh2 {\n margin-top: -2px;\n margin-bottom: 2px;\n}\n"; - //$book->addCSSFile("styles.css", "css1", $cssData); - $cssData = file_get_contents("assets/style.css"); - //dd($cssData); - $book->addCSSFile("style.css", "css1", $cssData); + $book->addCSSFile("style.css", "css1", $this->getStyle($this->currentPath, "style")); $cssData = file_get_contents("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github.css"); - //dd($cssData); $book->addCSSFile("github.css", "css2", $cssData); //$book->addChapter("Table of Contents", "TOC.xhtml", null, false, EPub::EXTERNAL_REF_IGNORE); $cover = $content_start . "

" . Ibis::title() . "

\n"; @@ -296,7 +159,7 @@ protected function buildEpub(Collection $chapters, array $config, string $curren $book->finalize(); - $epubFilename = 'export/' . Ibis::outputFileName() . '-' . $this->themeName . '.epub'; + $epubFilename = 'export/' . Ibis::outputFileName() . '.epub'; $zipData = $book->saveBook($epubFilename); @@ -314,23 +177,10 @@ protected function buildEpub(Collection $chapters, array $config, string $curren * @return string * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException */ - private function getTheme($currentPath, $themeName) + private function getStyle($currentPath, $themeName) { - return $this->disk->get($currentPath . "/assets/theme-$themeName.html"); + return $this->disk->get($currentPath . "/assets/$themeName.css"); } - /** - * @param $fontData - * @return array - */ - protected function fonts($config, $fontData) - { - return $fontData + collect($config['fonts'])->mapWithKeys(function ($file, $name) { - return [ - $name => [ - 'R' => $file - ] - ]; - })->toArray(); - } + }