daux.io/libs/Format/HTML/Generator.php

221 regels
7.6 KiB
PHP

<?php namespace Todaymade\Daux\Format\HTML;
use Symfony\Component\Console\Input\InputInterface;
2015-07-14 22:06:01 +02:00
use Symfony\Component\Console\Output\OutputInterface;
2019-12-07 11:22:40 +01:00
use Todaymade\Daux\Config as GlobalConfig;
2015-07-23 17:44:24 +02:00
use Todaymade\Daux\Console\RunAction;
use Todaymade\Daux\Daux;
use Todaymade\Daux\DauxHelper;
use Todaymade\Daux\Format\Base\LiveGenerator;
2016-07-29 23:46:57 +02:00
use Todaymade\Daux\Format\HTML\ContentTypes\Markdown\ContentType;
2015-07-23 17:44:24 +02:00
use Todaymade\Daux\GeneratorHelper;
use Todaymade\Daux\Tree\ComputedRaw;
use Todaymade\Daux\Tree\Directory;
use Todaymade\Daux\Tree\Entry;
use Todaymade\Daux\Tree\Raw;
class Generator implements \Todaymade\Daux\Format\Base\Generator, LiveGenerator
{
use RunAction, HTMLUtils;
2015-07-14 22:06:01 +02:00
/** @var Daux */
protected $daux;
/** @var Template */
protected $templateRenderer;
2016-03-13 21:51:58 +01:00
protected $indexed_pages = [];
/**
* @param Daux $daux
*/
public function __construct(Daux $daux)
{
$config = $daux->getConfig();
2017-12-11 21:14:18 +01:00
$this->daux = $daux;
$this->templateRenderer = new Template($config);
$config->templateRenderer = $this->templateRenderer;
}
/**
* @return array
*/
public function getContentTypes()
{
return [
'markdown' => new ContentType($this->daux->getConfig()),
];
}
public function generateAll(InputInterface $input, OutputInterface $output, $width)
{
$destination = $input->getOption('destination');
$config = $this->daux->getConfig();
if (is_null($destination)) {
$destination = $config->getLocalBase() . DIRECTORY_SEPARATOR . 'static';
}
2015-07-14 22:06:01 +02:00
$this->runAction(
2016-07-27 21:32:51 +02:00
'Copying Static assets ...',
2015-07-14 22:06:01 +02:00
$width,
function() use ($destination, $config) {
$this->ensureEmptyDestination($destination);
$this->copyThemes($destination, $config->getThemesPath());
2015-07-14 22:06:01 +02:00
}
);
2016-07-27 21:32:51 +02:00
$output->writeLn('Generating ...');
$this->generateRecursive($this->daux->tree, $destination, $config, $output, $width, $config->getHTML()->hasSearch());
2016-03-13 21:51:58 +01:00
GeneratorHelper::copyRecursive(
$config->getLocalBase() . DIRECTORY_SEPARATOR . 'daux_libraries' . DIRECTORY_SEPARATOR,
$destination . DIRECTORY_SEPARATOR . 'daux_libraries'
);
if ($config->getHTML()->hasSearch()) {
2016-03-13 21:51:58 +01:00
file_put_contents(
$destination . DIRECTORY_SEPARATOR . 'daux_search_index.json',
2016-03-13 21:51:58 +01:00
json_encode(['pages' => $this->indexed_pages])
);
if (json_last_error()) {
echo "Could not write search index: \n" . json_last_error_msg() . "\n";
}
}
}
/**
* Remove HTML tags, including invisible text such as style and
* script code, and embedded objects. Add line breaks around
* block-level tags to prevent word joining after tag removal.
* Also collapse whitespace to single space and trim result.
* modified from: http://nadeausoftware.com/articles/2007/09/php_tip_how_strip_html_tags_web_page
2016-07-29 23:46:57 +02:00
*
* @param string $text
* @return string
*/
private function sanitize($text)
{
$text = preg_replace(
2016-07-27 21:32:51 +02:00
[
// Remove invisible content
'@<head[^>]*?>.*?</head>@siu',
'@<style[^>]*?>.*?</style>@siu',
'@<script[^>]*?.*?</script>@siu',
'@<object[^>]*?.*?</object>@siu',
'@<embed[^>]*?.*?</embed>@siu',
'@<applet[^>]*?.*?</applet>@siu',
'@<noframes[^>]*?.*?</noframes>@siu',
'@<noscript[^>]*?.*?</noscript>@siu',
'@<noembed[^>]*?.*?</noembed>@siu',
// Add line breaks before and after blocks
'@</?((address)|(blockquote)|(center)|(del))@iu',
'@</?((div)|(h[1-9])|(ins)|(isindex)|(p)|(pre))@iu',
'@</?((dir)|(dl)|(dt)|(dd)|(li)|(menu)|(ol)|(ul))@iu',
'@</?((table)|(th)|(td)|(caption))@iu',
'@</?((form)|(button)|(fieldset)|(legend)|(input))@iu',
'@</?((label)|(select)|(optgroup)|(option)|(textarea))@iu',
'@</?((frameset)|(frame)|(iframe))@iu',
2016-07-27 21:32:51 +02:00
],
[
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
"\n\$0", "\n\$0", "\n\$0", "\n\$0", "\n\$0", "\n\$0",
"\n\$0", "\n\$0",
2016-07-27 21:32:51 +02:00
],
2016-03-13 21:51:58 +01:00
$text
);
2016-07-27 21:32:51 +02:00
$text = trim(preg_replace('/\s+/', ' ', strip_tags($text)));
// Sometimes strings are detected as invalid UTF-8 and json_encode can't treat them
// iconv can fix those strings
2017-11-08 21:51:01 +01:00
$text = iconv('UTF-8', 'UTF-8//IGNORE', $text);
return $text;
}
2015-07-17 23:38:06 +02:00
/**
* Recursively generate the documentation
*
2015-07-18 01:10:40 +02:00
* @param Directory $tree
2015-07-17 23:38:06 +02:00
* @param string $output_dir
2019-12-07 11:22:40 +01:00
* @param GlobalConfig $config
2015-07-17 23:38:06 +02:00
* @param OutputInterface $output
2016-07-27 21:32:51 +02:00
* @param int $width
* @param bool $index_pages
2015-07-17 23:38:06 +02:00
* @param string $base_url
* @throws \Exception
*/
2019-12-07 11:22:40 +01:00
private function generateRecursive(Directory $tree, $output_dir, GlobalConfig $config, $output, $width, $index_pages, $base_url = '')
{
DauxHelper::rebaseConfiguration($config, $base_url);
if ($base_url !== '' && !$config->hasEntryPage()) {
$config->setEntryPage($tree->getFirstPage());
}
foreach ($tree->getEntries() as $key => $node) {
if ($node instanceof Directory) {
2015-07-20 15:59:52 +02:00
$new_output_dir = $output_dir . DIRECTORY_SEPARATOR . $key;
2015-07-17 23:38:06 +02:00
mkdir($new_output_dir);
$this->generateRecursive($node, $new_output_dir, $config, $output, $width, $index_pages, '../' . $base_url);
// Rebase configuration again as $config is a shared object
DauxHelper::rebaseConfiguration($config, $base_url);
} else {
2015-07-14 22:06:01 +02:00
$this->runAction(
2016-07-27 21:32:51 +02:00
'- ' . $node->getUrl(),
2015-07-14 22:06:01 +02:00
$width,
function() use ($node, $output_dir, $key, $config, $index_pages) {
if ($node instanceof Raw) {
2015-07-20 15:59:52 +02:00
copy($node->getPath(), $output_dir . DIRECTORY_SEPARATOR . $key);
2016-07-27 21:32:51 +02:00
return;
}
$this->daux->tree->setActiveNode($node);
$generated = $this->generateOne($node, $config);
2015-07-20 15:59:52 +02:00
file_put_contents($output_dir . DIRECTORY_SEPARATOR . $key, $generated->getContent());
2016-03-13 21:51:58 +01:00
if ($index_pages) {
2016-07-27 21:32:51 +02:00
$this->indexed_pages[] = [
'title' => $node->getTitle(),
'text' => $this->sanitize($generated->getPureContent()),
2016-07-27 21:32:51 +02:00
'tags' => '',
'url' => $node->getUrl(),
2016-03-13 21:51:58 +01:00
];
}
2015-07-14 22:06:01 +02:00
}
);
}
}
}
/**
* @param Entry $node
2019-12-07 11:22:40 +01:00
* @param GlobalConfig $config
* @return \Todaymade\Daux\Format\Base\Page
*/
2019-12-07 11:22:40 +01:00
public function generateOne(Entry $node, GlobalConfig $config)
{
if ($node instanceof Raw) {
return new RawPage($node->getPath());
}
if ($node instanceof ComputedRaw) {
return new ComputedRawPage($node);
}
$config->setRequest($node->getUrl());
2016-07-27 21:32:51 +02:00
$contentPage = ContentPage::fromFile($node, $config, $this->daux->getContentTypeHandler()->getType($node));
2017-12-11 21:14:18 +01:00
$contentPage->templateRenderer = $this->templateRenderer;
return $contentPage;
}
}