Skip to content

Commit

Permalink
Refactoring common code for PDF and EPUB commands
Browse files Browse the repository at this point in the history
  • Loading branch information
roberto-butti committed Dec 21, 2023
1 parent e1266ab commit b2938b0
Show file tree
Hide file tree
Showing 3 changed files with 217 additions and 305 deletions.
172 changes: 172 additions & 0 deletions src/Commands/BaseBuildCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
<?php

namespace Ibis\Commands;

use SplFileInfo;

use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Collection;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use League\CommonMark\Environment\Environment;
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
use League\CommonMark\Extension\FrontMatter\FrontMatterExtension;
use League\CommonMark\Extension\GithubFlavoredMarkdownExtension;
use League\CommonMark\Extension\Table\TableExtension;

use League\CommonMark\Extension\CommonMark\Node\Block\FencedCode;
use League\CommonMark\Extension\CommonMark\Node\Block\IndentedCode;
use League\CommonMark\MarkdownConverter;
use Spatie\CommonMarkHighlighter\IndentedCodeRenderer;
use Spatie\CommonMarkHighlighter\FencedCodeRenderer;

class BaseBuildCommand extends Command
{
protected OutputInterface $output;

protected Filesystem $disk;

protected string $contentDirectory;

protected string $currentPath;

protected array $config;


protected function preExecute(InputInterface $input, OutputInterface $output)
{
$this->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>Error, check if ' . $this->contentDirectory . ' exists.</error>');
exit -1;
}
$this->output->writeln('<info>Loading content from: ' . $this->contentDirectory . '</info>');

$configIbisFile = $this->currentPath . '/ibis.php';
if (!$this->disk->isFile($configIbisFile)) {
$this->output->writeln('<error>Error, check if ' . $configIbisFile . ' exists.</error>');
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('<fg=yellow>==></> 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]' => '<div style="page-break-after: always;"></div>'
];

if ($file > 1) {
$html = str_replace('<h1>', '[break]<h1>', $html);
}

$html = str_replace('<h2>', '[break]<h2>', $html);
$html = str_replace("<blockquote>\n<p>{notice}", "<blockquote class='notice'><p><strong>Notice:</strong>", $html);
$html = str_replace("<blockquote>\n<p>{warning}", "<blockquote class='warning'><p><strong>Warning:</strong>", $html);
$html = str_replace("<blockquote>\n<p>{quote}", "<blockquote class='quote'><p>", $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('<fg=yellow>==></> Preparing Export Directory ...');

if (!$this->disk->isDirectory($currentPath . '/export')) {
$this->disk->makeDirectory(
$currentPath . '/export',
0755,
true
);
}
}

}
158 changes: 24 additions & 134 deletions src/Commands/BuildCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.');
}

Expand All @@ -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>Error, check if ' . $configIbisFile . ' exists.</error>');
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
);

Expand All @@ -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('<fg=yellow>==></> 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('<fg=yellow>==></> 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]' => '<div style="page-break-after: always;"></div>'
];

if ($file > 1) {
$html = str_replace('<h1>', '[break]<h1>', $html);
}

$html = str_replace('<h2>', '[break]<h2>', $html);
$html = str_replace("<blockquote>\n<p>{notice}", "<blockquote class='notice'><p><strong>Notice:</strong>", $html);
$html = str_replace("<blockquote>\n<p>{warning}", "<blockquote class='warning'><p><strong>Warning:</strong>", $html);
$html = str_replace("<blockquote>\n<p>{quote}", "<blockquote class='quote'><p>", $html);

$html = str_replace(array_keys($commands), array_values($commands), $html);

return $html;
}

/**
* @param Collection $chapters
Expand Down Expand Up @@ -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('<fg=yellow>==></> ❇️ ' . $chapter["mdfile"] . ' ...');
if (array_key_exists('header', $config)) {
$pdf->SetHTMLHeader(
Expand Down
Loading

0 comments on commit b2938b0

Please sign in to comment.