Merge pull request #4363 from Icinga/enhance-markdown-formatting

Enhance markdown formatting
This commit is contained in:
Johannes Meyer 2021-04-30 11:24:54 +02:00 committed by GitHub
commit c8497c8e6f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 105 additions and 4 deletions

View File

@ -3,20 +3,36 @@
namespace Icinga\Web\Helper;
use Icinga\Web\Helper\Markdown\LinkTransformer;
use Parsedown;
class Markdown
{
public static function line($content)
public static function line($content, $config = null)
{
require_once 'Parsedown/Parsedown.php';
return HtmlPurifier::process(Parsedown::instance()->line($content));
if ($config === null) {
$config = function (\HTMLPurifier_Config $config) {
$config->set('HTML.Parent', 'span'); // Only allow inline elements
LinkTransformer::attachTo($config);
};
}
return HtmlPurifier::process(Parsedown::instance()->line($content), $config);
}
public static function text($content)
public static function text($content, $config = null)
{
require_once 'Parsedown/Parsedown.php';
return HtmlPurifier::process(Parsedown::instance()->text($content));
if ($config === null) {
$config = function (\HTMLPurifier_Config $config) {
LinkTransformer::attachTo($config);
};
}
return HtmlPurifier::process(Parsedown::instance()->text($content), $config);
}
}

View File

@ -0,0 +1,85 @@
<?php
/* Icinga Web 2 | (c) 2021 Icinga GmbH | GPLv2+ */
namespace Icinga\Web\Helper\Markdown;
use HTMLPurifier_AttrTransform;
use HTMLPurifier_Config;
use ipl\Stdlib\Str;
use ipl\Web\Url;
class LinkTransformer extends HTMLPurifier_AttrTransform
{
/**
* Link targets with such a file extension are not loaded by an iFrame
*
* @var string[]
*/
public static $NON_IFRAME_FILES = [
'html',
'htm',
'php',
'svg',
'aspx',
'cshtml',
'vbhtml'
];
/**
* Link targets that are considered to have a thumbnail
*
* @var string[]
*/
public static $IMAGE_FILES = [
'jpg',
'jpeg',
'png',
'bmp',
'gif',
'heif',
'heic',
'webp'
];
public function transform($attr, $config, $context)
{
if (! isset($attr['href'])) {
return $attr;
}
$url = Url::fromPath($attr['href']);
list($_, $ext) = Str::symmetricSplit($url->getPath(), '.', 2);
$hasThumbnail = $ext !== null && in_array($ext, static::$IMAGE_FILES, true);
$useIframe = $ext !== null && ! in_array($ext, static::$NON_IFRAME_FILES, true);
if ($hasThumbnail) {
// I would have liked to not only base this off of the extension, but also by
// whether there is an actual img tag inside the anchor. Seems not possible :(
$attr['class'] = 'with-thumbnail';
}
if ((! isset($attr['target']) || ! in_array($attr['target'], ['_blank', '_self']))
&& ($useIframe || $url->isExternal())
) {
$attr['href'] = Url::fromPath('iframe', ['url' => $url])->getAbsoluteUrl();
}
return $attr;
}
public static function attachTo(HTMLPurifier_Config $config)
{
$module = $config->getHTMLDefinition(true)
->getAnonymousModule();
if (isset($module->info['a'])) {
$a = $module->info['a'];
} else {
$a = $module->addBlankElement('a');
}
$a->attr_transform_post[] = new self();
}
}