Add custom image renderer to fix relative links to images #78
This commit is contained in:
parent
7acf4e5b55
commit
727c5c015e
@ -29,8 +29,7 @@ class CommonMarkConverter extends \League\CommonMark\CommonMarkConverter
|
|||||||
$config['daux']['processor_instance']->extendCommonMarkEnvironment($environment);
|
$config['daux']['processor_instance']->extendCommonMarkEnvironment($environment);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->docParser = new DocParser($environment);
|
parent::__construct($config, $environment);
|
||||||
$this->htmlRenderer = new HtmlRenderer($environment);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getLinkRenderer(Environment $environment)
|
protected function getLinkRenderer(Environment $environment)
|
||||||
|
@ -30,53 +30,6 @@ class LinkRenderer implements InlineRendererInterface, ConfigurationAwareInterfa
|
|||||||
$this->parent = new \League\CommonMark\Inline\Renderer\LinkRenderer();
|
$this->parent = new \League\CommonMark\Inline\Renderer\LinkRenderer();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $url
|
|
||||||
* @return Entry
|
|
||||||
* @throws LinkNotFoundException
|
|
||||||
*/
|
|
||||||
protected function resolveInternalFile($url)
|
|
||||||
{
|
|
||||||
$triedAbsolute = false;
|
|
||||||
|
|
||||||
// Legacy absolute paths could start with
|
|
||||||
// "!" In this case we will try to find
|
|
||||||
// the file starting at the root
|
|
||||||
if ($url[0] == '!' || $url[0] == '/') {
|
|
||||||
$url = ltrim($url, '!/');
|
|
||||||
|
|
||||||
if ($file = DauxHelper::getFile($this->daux['tree'], $url)) {
|
|
||||||
return $file;
|
|
||||||
}
|
|
||||||
|
|
||||||
$triedAbsolute = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Seems it's not an absolute path or not found,
|
|
||||||
// so we'll continue with the current folder
|
|
||||||
if ($file = DauxHelper::getFile($this->daux->getCurrentPage()->getParent(), $url)) {
|
|
||||||
return $file;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we didn't already try it, we'll
|
|
||||||
// do a pass starting at the root
|
|
||||||
if (!$triedAbsolute && $file = DauxHelper::getFile($this->daux['tree'], $url)) {
|
|
||||||
return $file;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new LinkNotFoundException("Could not locate file '$url'");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function isValidUrl($url)
|
|
||||||
{
|
|
||||||
return !empty($url) && $url[0] != '#';
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function isExternalUrl($url)
|
|
||||||
{
|
|
||||||
return preg_match('#^(?:[a-z]+:)?//|^mailto:#', $url);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param AbstractInline|Link $inline
|
* @param AbstractInline|Link $inline
|
||||||
* @param ElementRendererInterface $htmlRenderer
|
* @param ElementRendererInterface $htmlRenderer
|
||||||
@ -102,12 +55,12 @@ class LinkRenderer implements InlineRendererInterface, ConfigurationAwareInterfa
|
|||||||
|
|
||||||
// empty urls and anchors should
|
// empty urls and anchors should
|
||||||
// not go through the url resolver
|
// not go through the url resolver
|
||||||
if (!$this->isValidUrl($url)) {
|
if (!DauxHelper::isValidUrl($url)) {
|
||||||
return $element;
|
return $element;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Absolute urls, shouldn't either
|
// Absolute urls, shouldn't either
|
||||||
if ($this->isExternalUrl($url)) {
|
if (DauxHelper::isExternalUrl($url)) {
|
||||||
$element->setAttribute('class', 'Link--external');
|
$element->setAttribute('class', 'Link--external');
|
||||||
|
|
||||||
return $element;
|
return $element;
|
||||||
@ -121,16 +74,13 @@ class LinkRenderer implements InlineRendererInterface, ConfigurationAwareInterfa
|
|||||||
$foundWithHash = false;
|
$foundWithHash = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$file = $this->resolveInternalFile($url);
|
$file = DauxHelper::resolveInternalFile($this->daux, $url);
|
||||||
$url = DauxHelper::getRelativePath($this->daux->getCurrentPage()->getUrl(), $file->getUrl());
|
$url = DauxHelper::getRelativePath($this->daux->getCurrentPage()->getUrl(), $file->getUrl());
|
||||||
} catch (LinkNotFoundException $e) {
|
} catch (LinkNotFoundException $e) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// For some reason, the filename could contain a # and thus the link needs to resolve to that.
|
// For some reason, the filename could contain a # and thus the link needs to resolve to that.
|
||||||
try {
|
try {
|
||||||
if (strlen($urlAndHash[1] ?? "") > 0) {
|
if (strlen($urlAndHash[1] ?? "") > 0) {
|
||||||
$file = $this->resolveInternalFile($url . '#' . $urlAndHash[1]);
|
$file = DauxHelper::resolveInternalFile($this->daux, $url . '#' . $urlAndHash[1]);
|
||||||
$url = DauxHelper::getRelativePath($this->daux->getCurrentPage()->getUrl(), $file->getUrl());
|
$url = DauxHelper::getRelativePath($this->daux->getCurrentPage()->getUrl(), $file->getUrl());
|
||||||
$foundWithHash = true;
|
$foundWithHash = true;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<?php namespace Todaymade\Daux;
|
<?php namespace Todaymade\Daux;
|
||||||
|
|
||||||
|
use Todaymade\Daux\Exception\LinkNotFoundException;
|
||||||
use Todaymade\Daux\Tree\Builder;
|
use Todaymade\Daux\Tree\Builder;
|
||||||
use Todaymade\Daux\Tree\Directory;
|
use Todaymade\Daux\Tree\Directory;
|
||||||
|
|
||||||
@ -526,4 +527,52 @@ class DauxHelper
|
|||||||
public static function is($path, $type) {
|
public static function is($path, $type) {
|
||||||
return ($type == 'dir') ? is_dir($path) : file_exists($path);
|
return ($type == 'dir') ? is_dir($path) : file_exists($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Config $config
|
||||||
|
* @param string $url
|
||||||
|
* @return Entry
|
||||||
|
* @throws LinkNotFoundException
|
||||||
|
*/
|
||||||
|
public static function resolveInternalFile($config, $url)
|
||||||
|
{
|
||||||
|
$triedAbsolute = false;
|
||||||
|
|
||||||
|
// Legacy absolute paths could start with
|
||||||
|
// "!" In this case we will try to find
|
||||||
|
// the file starting at the root
|
||||||
|
if ($url[0] == '!' || $url[0] == '/') {
|
||||||
|
$url = ltrim($url, '!/');
|
||||||
|
|
||||||
|
if ($file = DauxHelper::getFile($config['tree'], $url)) {
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
|
||||||
|
$triedAbsolute = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seems it's not an absolute path or not found,
|
||||||
|
// so we'll continue with the current folder
|
||||||
|
if ($file = DauxHelper::getFile($config->getCurrentPage()->getParent(), $url)) {
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we didn't already try it, we'll
|
||||||
|
// do a pass starting at the root
|
||||||
|
if (!$triedAbsolute && $file = DauxHelper::getFile($config['tree'], $url)) {
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new LinkNotFoundException("Could not locate file '$url'");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function isValidUrl($url)
|
||||||
|
{
|
||||||
|
return !empty($url) && $url[0] != '#';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function isExternalUrl($url)
|
||||||
|
{
|
||||||
|
return preg_match('#^(?:[a-z]+:)?//|^mailto:#', $url);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ use League\CommonMark\ElementRendererInterface;
|
|||||||
use League\CommonMark\HtmlElement;
|
use League\CommonMark\HtmlElement;
|
||||||
use League\CommonMark\Inline\Element\AbstractInline;
|
use League\CommonMark\Inline\Element\AbstractInline;
|
||||||
use League\CommonMark\Inline\Element\Link;
|
use League\CommonMark\Inline\Element\Link;
|
||||||
|
use Todaymade\Daux\DauxHelper;
|
||||||
|
|
||||||
class LinkRenderer extends \Todaymade\Daux\ContentTypes\Markdown\LinkRenderer
|
class LinkRenderer extends \Todaymade\Daux\ContentTypes\Markdown\LinkRenderer
|
||||||
{
|
{
|
||||||
@ -38,7 +39,7 @@ class LinkRenderer extends \Todaymade\Daux\ContentTypes\Markdown\LinkRenderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Internal links
|
//Internal links
|
||||||
$file = $this->resolveInternalFile($url);
|
$file = DauxHelper::resolveInternalFile($this->daux, $url);
|
||||||
|
|
||||||
$link_props = [
|
$link_props = [
|
||||||
'ri:content-title' => trim(trim($this->daux['confluence']['prefix']) . ' ' . $file->getTitle()),
|
'ri:content-title' => trim(trim($this->daux['confluence']['prefix']) . ' ' . $file->getTitle()),
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
use League\CommonMark\Environment;
|
use League\CommonMark\Environment;
|
||||||
use League\CommonMark\Block\Element as BlockElement;
|
use League\CommonMark\Block\Element as BlockElement;
|
||||||
|
use League\CommonMark\Inline\Element as InlineElement;
|
||||||
use League\CommonMark\Event\DocumentParsedEvent;
|
use League\CommonMark\Event\DocumentParsedEvent;
|
||||||
use Todaymade\Daux\Config;
|
use Todaymade\Daux\Config;
|
||||||
use Todaymade\Daux\ContentTypes\Markdown\TableOfContents;
|
use Todaymade\Daux\ContentTypes\Markdown\TableOfContents;
|
||||||
@ -17,5 +18,7 @@ class CommonMarkConverter extends \Todaymade\Daux\ContentTypes\Markdown\CommonMa
|
|||||||
$processor = new TOC\Processor($config);
|
$processor = new TOC\Processor($config);
|
||||||
$environment->addEventListener(DocumentParsedEvent::class, [$processor, 'onDocumentParsed']);
|
$environment->addEventListener(DocumentParsedEvent::class, [$processor, 'onDocumentParsed']);
|
||||||
$environment->addBlockRenderer(TableOfContents::class, new TOC\Renderer($config));
|
$environment->addBlockRenderer(TableOfContents::class, new TOC\Renderer($config));
|
||||||
|
|
||||||
|
$environment->addInlineRenderer(InlineElement\Image::class, new ImageRenderer($config));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
87
libs/Format/HTML/ContentTypes/Markdown/ImageRenderer.php
Normal file
87
libs/Format/HTML/ContentTypes/Markdown/ImageRenderer.php
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
<?php namespace Todaymade\Daux\Format\HTML\ContentTypes\Markdown;
|
||||||
|
|
||||||
|
use League\CommonMark\ElementRendererInterface;
|
||||||
|
use League\CommonMark\HtmlElement;
|
||||||
|
use League\CommonMark\Inline\Element\AbstractInline;
|
||||||
|
use League\CommonMark\Inline\Element\Image;
|
||||||
|
use League\CommonMark\Inline\Renderer\InlineRendererInterface;
|
||||||
|
use League\CommonMark\Util\ConfigurationAwareInterface;
|
||||||
|
use League\CommonMark\Util\ConfigurationInterface;
|
||||||
|
use Todaymade\Daux\Config;
|
||||||
|
use Todaymade\Daux\DauxHelper;
|
||||||
|
|
||||||
|
class ImageRenderer implements InlineRendererInterface, ConfigurationAwareInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var Config
|
||||||
|
*/
|
||||||
|
protected $daux;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ConfigurationInterface
|
||||||
|
*/
|
||||||
|
protected $config;
|
||||||
|
|
||||||
|
public function __construct($daux)
|
||||||
|
{
|
||||||
|
$this->daux = $daux;
|
||||||
|
$this->parent = new \League\CommonMark\Inline\Renderer\ImageRenderer();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Relative URLs can be done using either the folder with
|
||||||
|
* number prefix or the final name (with prefix stripped).
|
||||||
|
* This ensures that we always use the final name when generating.
|
||||||
|
*/
|
||||||
|
protected function getCleanUrl(Image $element)
|
||||||
|
{
|
||||||
|
$url = $element->getUrl();
|
||||||
|
|
||||||
|
// empty urls and anchors should
|
||||||
|
// not go through the url resolver
|
||||||
|
if (!DauxHelper::isValidUrl($url)) {
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Absolute urls, shouldn't either
|
||||||
|
if (DauxHelper::isExternalUrl($url)) {
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$file = DauxHelper::resolveInternalFile($this->daux, $url);
|
||||||
|
return DauxHelper::getRelativePath($this->daux->getCurrentPage()->getUrl(), $file->getUrl());
|
||||||
|
} catch (LinkNotFoundException $e) {
|
||||||
|
if ($this->daux->isStatic()) {
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
$element->setAttribute('class', 'Link--broken');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Image $inline
|
||||||
|
* @param ElementRendererInterface $htmlRenderer
|
||||||
|
*
|
||||||
|
* @return HtmlElement
|
||||||
|
*/
|
||||||
|
public function render(AbstractInline $inline, ElementRendererInterface $htmlRenderer)
|
||||||
|
{
|
||||||
|
$original = $inline->getUrl();
|
||||||
|
$inline->setUrl($this->getCleanUrl($inline));
|
||||||
|
|
||||||
|
return $this->parent->render($inline, $htmlRenderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ConfigurationInterface $configuration
|
||||||
|
*/
|
||||||
|
public function setConfiguration(ConfigurationInterface $configuration)
|
||||||
|
{
|
||||||
|
$this->config = $configuration;
|
||||||
|
$this->parent->setConfiguration($configuration);
|
||||||
|
}
|
||||||
|
}
|
@ -56,7 +56,7 @@ class LinkRenderer extends \Todaymade\Daux\ContentTypes\Markdown\LinkRenderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$file = $this->resolveInternalFile($url);
|
$file = DauxHelper::resolveInternalFile($this->daux, $url);
|
||||||
$url = $file->getUrl();
|
$url = $file->getUrl();
|
||||||
} catch (LinkNotFoundException $e) {
|
} catch (LinkNotFoundException $e) {
|
||||||
if ($this->daux->isStatic()) {
|
if ($this->daux->isStatic()) {
|
||||||
|
Loading…
Reference in New Issue
Block a user