Skip to content

Commit

Permalink
6 allow prefixing image sources (#7)
Browse files Browse the repository at this point in the history
It's possible to prefix image sources. Thanks @juripetersen
  • Loading branch information
juripetersen authored May 28, 2021
1 parent 45dc00f commit 242481f
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 14 deletions.
13 changes: 13 additions & 0 deletions config/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,17 @@
],
],

/*
|--------------------------------------------------------------------------
| Images
|--------------------------------------------------------------------------
|
| If fetching images from an external repository, you may wish to prefix
| your image paths with a prefix to automatically convert a relative url
| to an absolute url.
|
*/
'images' => [
// 'prefix' => 'https://your-prefix.com/',
],
];
14 changes: 5 additions & 9 deletions src/Markdown/AddCustomHtmlClasses.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ class AddCustomHtmlClasses
{
public string $content;
public string $style;
public array $styleset;
public array $styleSet;

public function __construct(string $content, string $style)
{
$this->content = $content;
$this->style = $style;
$this->styleset = $this->getStyleSet();
$this->styleSet = $this->getStyleSet();
}

/**
Expand All @@ -21,7 +21,7 @@ public function __construct(string $content, string $style)
*/
public function handle(): string
{
foreach ($this->styleset as $tag => $class) {
foreach ($this->styleSet as $tag => $class) {
$this->content = str_replace($this->tagFilter($tag), $this->replaceTag($tag, $class), $this->content);
}

Expand All @@ -44,14 +44,10 @@ private function replaceTag(string $tag, string $class): string
return "<{$tag} class=\"{$class}\"";
}

private function getStyleset(): array
private function getStyleSet(): array
{
$configPath = 'markdown.styles.'.$this->style;

if (!config()->has($configPath)) {
return [];
}

return config($configPath);
return config($configPath, []);
}
}
7 changes: 6 additions & 1 deletion src/Markdown/CommonMarkRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,16 @@ public function parse(string $content): string
{
$content = $this->parser->convertToHtml($content);

return (new AddCustomHtmlClasses($content, $this->style))->handle();
return (new PrefixImageSources(
(new AddCustomHtmlClasses($content, $this->style))->handle()
)
)->handle();
}

public function style(string $style): self
{
$this->style = $style;

return $this;
}
}
94 changes: 94 additions & 0 deletions src/Markdown/PrefixImageSources.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php

namespace VV\Markdown\Markdown;

use Illuminate\Support\Arr;
use Illuminate\Support\Str;

class PrefixImageSources
{
public string $content;

public function __construct(string $content)
{
$this->content = $content;
}

/**
* Find all image sources in the html content and replace all absolute paths with a configurable url that is prefixed to it.
*/
public function handle()
{
if ($this->getPrefixUrl()) {
$this->findImageSources($this->findImages($this->content));
}

return $this->content;
}

/**
* Iterate over the html and find all images.
*/
private function findImages(string $htmlContent): array
{
preg_match_all('/<img[^>]+>/i', $htmlContent, $result);

return Arr::flatten($result);
}

/**
* Iterate over all sources and prefix them with the configurable url.
*/
private function findImageSources(array $htmlImages): void
{
foreach ($htmlImages as $image) {
preg_match('/src=(?:"[^"]*")/i', $image, $source);

$source = $source[0] ?? null;

if ($source && !$this->isAbsolutePath($source)) {
$this->content = str_replace($source, $this->insertPrefix($source), $this->content);
}
}
}

/**
* Add prefix to image source.
*/
private function insertPrefix(string $source): string
{
$source = str_replace('src="', '', $source);

if (Str::startsWith($source, '/')) {
$source = Str::substr($source, 1);
}

$prefix = $this->getPrefixUrl();

return 'src="'.$prefix.$source;
}

/**
* Load Prefix URL from config.
*/
private function getPrefixUrl(): ?string
{
$prefix = config('markdown.images.prefix', null);

if ($prefix) {
$prefix = Str::finish($prefix, '/');
}

return $prefix;
}

/**
* Check if source is a absolute path or a complete url.
*/
private function isAbsolutePath(string $source): bool
{
return Str::contains($source, 'https://')
|| Str::contains($source, 'http://')
|| Str::contains($source, 'ftp://');
}
}
40 changes: 36 additions & 4 deletions tests/Unit/CommonMarkTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace VV\Markdown\Tests\Unit;

use VV\Markdown\Facades\Markdown;
use VV\Markdown\Markdown\PrefixImageSources;
use VV\Markdown\Tests\TestCase;

class CommonMarkTest extends TestCase
Expand Down Expand Up @@ -42,8 +43,9 @@ public function it_can_add_a_html_class_to_a_paragraph()
public function it_can_parse_tables()
{
$toParse = 'th | th(center) | th(right)
---|:----------:|----------:
td | td | td';
---|:----------:|----------:
td | td | td';

$result = '<table>';

$this->assertStringcontainsString($result, Markdown::parse($toParse));
Expand All @@ -55,8 +57,9 @@ public function it_can_add_a_css_class_to_a_table()
config()->set('markdown.styles.default.table', 'mb-2');

$toParse = 'th | th(center) | th(right)
---|:----------:|----------:
td | td | td';
---|:----------:|----------:
td | td | td';

$result = '<table class="mb-2">';

$this->assertStringcontainsString($result, Markdown::parse($toParse));
Expand All @@ -79,4 +82,33 @@ public function it_can_parse_lists()

$this->assertStringcontainsString($result, Markdown::parse($toParse));
}

/** @test */
public function it_prefixes_relative_image_sources()
{
config()->set('markdown.images.prefix', 'https://git.visuellverstehen.de/visuel/wiki/-/raw/main');
$result = '<img src="/uploads/7a9a2cea1fe762a59ae72cb1fd78e7bd/screenshot_5.png" alt="screenshot_5" />';

$prefixed = (new PrefixImageSources($result))->handle();
$this->assertStringContainsString('src="https://git.visuellverstehen.de/visuel/wiki/-/raw/main/uploads/7a9a2cea1fe762a59ae72cb1fd78e7bd/screenshot_5.png"', $prefixed);
}

/** @test */
public function it_does_not_prefix_if_config_empty()
{
$result = '<img src="/uploads/7a9a2cea1fe762a59ae72cb1fd78e7bd/screenshot_5.png" alt="screenshot_5" />';

$prefixed = (new PrefixImageSources($result))->handle();
$this->assertEquals($result, $prefixed);
}

/** @test */
public function it_does_not_prefix_complete_urls()
{
config()->set('markdown.images.prefix', 'https://git.visuellverstehen.de/visuel/wiki/-/raw/main');
$result = '<img src="https://www.visuellverstehen.de/fileadmin/_processed_/b/3/csm_frs-webapp-ui-ux-design-entwicklung-webbasierte-anwendung-digital-header-visuellverstehen-flensburg-werbeagentur-kommunikationsagentur-internetagentur_7b5cbde98a.jpg" alt="screenshot_5" />';

$prefixed = (new PrefixImageSources($result))->handle();
$this->assertStringNotContainsString('https://git.visuellverstehen.de/visuel/wiki/-/raw/main', $prefixed);
}
}

0 comments on commit 242481f

Please sign in to comment.