Fix single page generation, make internal links work correctly

This commit is contained in:
Stéphane Goetz 2018-09-21 23:43:06 +02:00
parent 851bad3ada
commit 4e0e81cb29
7 changed files with 157 additions and 79 deletions

View File

@ -16,7 +16,7 @@ use Todaymade\Daux\Tree\Raw;
class Generator implements \Todaymade\Daux\Format\Base\Generator, LiveGenerator
{
use RunAction;
use RunAction, HTMLUtils;
/** @var Daux */
protected $daux;
@ -45,30 +45,6 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator, LiveGenerator
];
}
protected function ensureEmptyDestination($destination)
{
if (is_dir($destination)) {
GeneratorHelper::rmdir($destination);
} else {
mkdir($destination);
}
}
/**
* Copy all files from $local to $destination
*
* @param string $destination
* @param string $local_base
*/
protected function copyThemes($destination, $local_base)
{
mkdir($destination . DIRECTORY_SEPARATOR . 'themes');
GeneratorHelper::copyRecursive(
$local_base,
$destination . DIRECTORY_SEPARATOR . 'themes'
);
}
public function generateAll(InputInterface $input, OutputInterface $output, $width)
{
$destination = $input->getOption('destination');

View File

@ -0,0 +1,29 @@
<?php namespace Todaymade\Daux\Format\HTML;
use Todaymade\Daux\GeneratorHelper;
trait HTMLUtils {
public function ensureEmptyDestination($destination)
{
if (is_dir($destination)) {
GeneratorHelper::rmdir($destination);
} else {
mkdir($destination);
}
}
/**
* Copy all files from $local to $destination
*
* @param string $destination
* @param string $local_base
*/
public function copyThemes($destination, $local_base)
{
mkdir($destination . DIRECTORY_SEPARATOR . 'themes');
GeneratorHelper::copyRecursive(
$local_base,
$destination . DIRECTORY_SEPARATOR . 'themes'
);
}
}

View File

@ -22,15 +22,9 @@ class Book
return '<style>' . file_get_contents('themes/daux_singlepage/css/main.min.css') . '</style>';
}
protected function getSectionId(Content $node)
protected function getPageUrl($page)
{
foreach ($this->pages as $id => $page) {
if ($page['page'] == $node) {
return $id;
}
}
throw new RuntimeException('Could not find the content page');
return "file_" . str_replace('/', '_', $page->getUrl());
}
protected function buildNavigation(Directory $tree)
@ -44,7 +38,7 @@ class Book
$nav[] = [
'title' => $node->getTitle(),
'href' => '#section_' . $this->getSectionId($node),
'href' => "#" . $this->getPageUrl($node),
];
} elseif ($node instanceof Directory) {
if (!$node->hasContent()) {
@ -55,7 +49,7 @@ class Book
$nav[] = [
'title' => $node->getTitle(),
'href' => '#section_' . $this->getSectionId($page_index),
'href' => "#" . $this->getPageUrl($page_index),
'children' => $this->buildNavigation($node),
];
}
@ -104,8 +98,8 @@ class Book
protected function generatePages()
{
$content = '';
foreach ($this->pages as $section => $page) {
$content .= '<a id="section_' . $section . '"></a>';
foreach ($this->pages as $page) {
$content .= '<a id="' . $this->getPageUrl($page['page']) . '"></a>';
$content .= '<h1>' . $page['page']->getTitle() . '</h1>';
$content .= '<section class="s-content">' . $page['content'] . '</section>';
$content .= '<div class="PageBreak">&nbsp;</div>';

View File

@ -0,0 +1,13 @@
<?php namespace Todaymade\Daux\Format\HTMLFile\ContentTypes\Markdown;
use League\CommonMark\Environment;
use Todaymade\Daux\Config;
class CommonMarkConverter extends \Todaymade\Daux\Format\HTML\ContentTypes\Markdown\CommonMarkConverter
{
protected function getLinkRenderer(Environment $environment)
{
var_dump(LinkRenderer::class);
return new LinkRenderer($environment->getConfig('daux'));
}
}

View File

@ -0,0 +1,12 @@
<?php namespace Todaymade\Daux\Format\HTMLFile\ContentTypes\Markdown;
use Todaymade\Daux\Config;
class ContentType extends \Todaymade\Daux\ContentTypes\Markdown\ContentType
{
public function __construct(Config $config)
{
$this->config = $config;
$this->converter = new CommonMarkConverter(['daux' => $config]);
}
}

View File

@ -0,0 +1,74 @@
<?php namespace Todaymade\Daux\Format\HTMLFile\ContentTypes\Markdown;
use League\CommonMark\ElementRendererInterface;
use League\CommonMark\HtmlElement;
use League\CommonMark\Inline\Element\AbstractInline;
use League\CommonMark\Inline\Element\Link;
use Todaymade\Daux\Config;
use Todaymade\Daux\DauxHelper;
use Todaymade\Daux\Exception\LinkNotFoundException;
use Todaymade\Daux\Tree\Entry;
class LinkRenderer extends \Todaymade\Daux\ContentTypes\Markdown\LinkRenderer
{
/**
* @param AbstractInline|Link $inline
* @param ElementRendererInterface $htmlRenderer
* @return HtmlElement
* @throws LinkNotFoundException
*/
public function render(AbstractInline $inline, ElementRendererInterface $htmlRenderer)
{
// This can't be in the method type as
// the method is an abstract and should
// have the same interface
if (!$inline instanceof Link) {
throw new \RuntimeException(
'Wrong type passed to ' . __CLASS__ . '::' . __METHOD__ .
" the expected type was 'League\\CommonMark\\Inline\\Element\\Link' but '" .
get_class($inline) . "' was provided"
);
}
$element = parent::render($inline, $htmlRenderer);
$url = $inline->getUrl();
// empty urls and anchors should
// not go through the url resolver
if (!$this->isValidUrl($url)) {
return $element;
}
// Absolute urls, shouldn't either
if ($this->isExternalUrl($url)) {
$element->setAttribute('class', 'Link--external');
return $element;
}
// if there's a hash component in the url, we can directly use it as all pages are in the same file
$urlAndHash = explode('#', $url);
if (isset($urlAndHash[1])) {
$element->setAttribute('href', '#' . $urlAndHash[1]);
return $element;
}
try {
$file = $this->resolveInternalFile($url);
$url = $file->getUrl();
} catch (LinkNotFoundException $e) {
if ($this->daux->isStatic()) {
throw $e;
}
$element->setAttribute('class', 'Link--broken');
}
$url = str_replace('/', '_', $url);
$element->setAttribute('href', "#file_$url");
return $element;
}
}

View File

@ -5,11 +5,12 @@ use Symfony\Component\Console\Output\OutputInterface;
use Todaymade\Daux\Console\RunAction;
use Todaymade\Daux\Daux;
use Todaymade\Daux\Format\HTML\Template;
use Todaymade\Daux\Format\HTML\ContentTypes\Markdown\ContentType;
use Todaymade\Daux\Format\HTML\HTMLUtils;
use Todaymade\Daux\Format\HTMLFile\ContentTypes\Markdown\ContentType;
class Generator implements \Todaymade\Daux\Format\Base\Generator
{
use RunAction;
use RunAction, HTMLUtils;
/** @var Daux */
protected $daux;
@ -36,52 +37,31 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator
];
}
protected function initPDF()
{
// create new PDF document
$pdf = new Book(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
$params = $this->daux->getParams();
// set document information
$pdf->SetCreator(PDF_CREATOR);
// set default header data
$pdf->SetHeaderData('', 0, $params['title'], $params['tagline']);
// set header and footer fonts
$pdf->setHeaderFont([PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN]);
$pdf->setFooterFont([PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA]);
// set default monospaced font
$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
// set margins
$pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
$pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
$pdf->SetFooterMargin(PDF_MARGIN_FOOTER);
// set auto page breaks
$pdf->SetAutoPageBreak(true, PDF_MARGIN_BOTTOM);
// set image scale factor
$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
// set font
$pdf->SetFont('helvetica', '', 10);
return $pdf;
}
/**
* {@inheritdoc}
*/
public function generateAll(InputInterface $input, OutputInterface $output, $width)
{
$params = $this->daux->getParams();
$destination = $input->getOption('destination');
$data = ['author' => $params['author'], 'title' => $params['title'], 'subject' => $params['tagline']];
$params = $this->daux->getParams();
if (is_null($destination)) {
$destination = $this->daux->local_base . DIRECTORY_SEPARATOR . 'static';
}
$this->runAction(
'Cleaning destination folder ...',
$width,
function() use ($destination, $params) {
$this->ensureEmptyDestination($destination);
}
);
$data = [
'author' => $params['author'],
'title' => $params['title'],
'subject' => $params['tagline']
];
$book = new Book($this->daux->tree, $data);