mirror of
https://github.com/YunoHost/doc.git
synced 2024-09-03 20:06:26 +02:00
186 lines
5.3 KiB
PHP
186 lines
5.3 KiB
PHP
|
<?php
|
||
|
namespace Grav\Plugin;
|
||
|
|
||
|
use DiDom\Document;
|
||
|
use DiDom\Element;
|
||
|
use Grav\Common\Plugin;
|
||
|
use RocketTheme\Toolbox\Event\Event;
|
||
|
|
||
|
/**
|
||
|
* Class ImageCaptionsPlugin
|
||
|
* @package Grav\Plugin
|
||
|
*/
|
||
|
class ImageCaptionsPlugin extends Plugin
|
||
|
{
|
||
|
/**
|
||
|
* @return array
|
||
|
*/
|
||
|
public static function getSubscribedEvents()
|
||
|
{
|
||
|
return [
|
||
|
'onPluginsInitialized' => ['onPluginsInitialized', 0]
|
||
|
];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Initialize the plugin
|
||
|
*/
|
||
|
public function onPluginsInitialized()
|
||
|
{
|
||
|
// Don't proceed if we are in the admin plugin
|
||
|
if ($this->isAdmin()) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
include __DIR__.'/vendor/autoload.php';
|
||
|
|
||
|
if ($this->grav['config']->get('plugins.image-captions.entire_page')) {
|
||
|
$this->enable([
|
||
|
'onOutputGenerated' => ['onOutputGenerated', 0],
|
||
|
'onTwigSiteVariables' => ['onTwigSiteVariables', 0]
|
||
|
]);
|
||
|
} else {
|
||
|
$this->enable([
|
||
|
'onPageContentProcessed' => ['onPageContentProcessed', 0],
|
||
|
'onTwigSiteVariables' => ['onTwigSiteVariables', 0]
|
||
|
]);
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Process on entire Grav output
|
||
|
*/
|
||
|
public function onOutputGenerated()
|
||
|
{
|
||
|
$page = $this->grav['page'];
|
||
|
$this->updateConfig($page);
|
||
|
|
||
|
if ($this->config->get('plugins.image-captions.enabled') === false) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
$this->grav->output = $this->processFigures($this->grav->output);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Process on page content
|
||
|
*
|
||
|
* @param Event $event
|
||
|
*/
|
||
|
public function onPageContentProcessed(Event $event)
|
||
|
{
|
||
|
$page = $event['page'];
|
||
|
$this->updateConfig($page);
|
||
|
|
||
|
if ($this->config->get('plugins.image-captions.enabled') === false) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
$content = $page->getRawContent();
|
||
|
$content = $this->processFigures($content);
|
||
|
$page->setRawContent($content);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Load the CSS if configured
|
||
|
*/
|
||
|
public function onTwigSiteVariables()
|
||
|
{
|
||
|
|
||
|
if ($this->config->get('plugins.image-captions.built_in_css')) {
|
||
|
$this->grav['assets']->add('plugin://image-captions/css/image-captions.css');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Process content and replace any items in scope with the figure/figcaption structure
|
||
|
*
|
||
|
* @param $content
|
||
|
* @return string
|
||
|
*/
|
||
|
protected function processFigures($content)
|
||
|
{
|
||
|
// Check for empty content
|
||
|
if (strlen($content) === 0) {
|
||
|
return '';
|
||
|
}
|
||
|
|
||
|
$document = new Document($content);
|
||
|
|
||
|
$scope = trim($this->grav['config']->get('plugins.image-captions.scope'));
|
||
|
$figure_class = $this->grav['config']->get('plugins.image-captions.figure_class');
|
||
|
$figcaption_class = $this->grav['config']->get('plugins.image-captions.figcaption_class');
|
||
|
$source = $this->grav['config']->get('plugins.image-captions.source');
|
||
|
|
||
|
if (count($images = $document->find($scope)) > 0) {
|
||
|
foreach ($images as $image) {
|
||
|
if ($source == 'alt') {
|
||
|
$caption = $image->getAttribute('alt');
|
||
|
} else {
|
||
|
$caption = $image->getAttribute('title');
|
||
|
}
|
||
|
|
||
|
if ($caption) {
|
||
|
$figure_classes = [$figure_class];
|
||
|
|
||
|
// If there are any `caption-*` classes on the image, add them to the figure
|
||
|
$image_classes = explode(' ', $image->getAttribute('class'));
|
||
|
foreach ($image_classes as $class) {
|
||
|
if (preg_match('/^(caption-|figure-).*/', $class)) {
|
||
|
$figure_classes[] = $class;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$figcaption = new Element('figcaption',$caption, ['class' => $figcaption_class]);
|
||
|
$items = [$image, $figcaption];
|
||
|
$figure = new Element('figure', '', ['class' => implode(' ', $figure_classes)]);
|
||
|
$figure->appendChild($items);
|
||
|
$image->replace($figure);
|
||
|
}
|
||
|
}
|
||
|
return $this->cleanupTags($document->html());
|
||
|
}
|
||
|
|
||
|
return $content;
|
||
|
}
|
||
|
|
||
|
private function updateConfig($page)
|
||
|
{
|
||
|
$config = $this->mergeConfig($page)->toArray();
|
||
|
$this->config->set('plugins.image-captions', $config);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Removes html and body tags at the begining and end of the html source
|
||
|
*
|
||
|
* @param $html
|
||
|
* @return string
|
||
|
*/
|
||
|
private function cleanupTags($html)
|
||
|
{
|
||
|
// remove html/body tags
|
||
|
$html = preg_replace('#<html><body>#', '', $html);
|
||
|
$html = preg_replace('#</body></html>#', '', $html);
|
||
|
|
||
|
// remove whitespace
|
||
|
$html = trim($html);
|
||
|
|
||
|
// remove p tags
|
||
|
preg_match_all('#<p>(?:\s*)((<a*.>)?.*)(?:\s*)(<figure((?:.|\n)*?)*(?:\s*)<\/figure>)(?:\s*)(<\/a>)?(?:\s*)<\/p>#m', $html, $matches);
|
||
|
|
||
|
if (is_array($matches) && !empty($matches)) {
|
||
|
$num_matches = count($matches[0]);
|
||
|
for ($i = 0; $i < $num_matches; $i++) {
|
||
|
$original = $matches[0][$i];
|
||
|
$new = $matches[1][$i] . $matches[3][$i] . $matches[5][$i];
|
||
|
|
||
|
$html = str_replace($original, $new, $html);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $html;
|
||
|
}
|
||
|
}
|