Skip to content

Commit

Permalink
feat: convert relative image urls to absolute
Browse files Browse the repository at this point in the history
  • Loading branch information
saade committed Jan 6, 2025
1 parent 8dc889e commit e1981e7
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 44 deletions.
27 changes: 15 additions & 12 deletions app/Models/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,31 +67,34 @@ public function stars(): MorphMany
return $this->morphMany(Star::class, 'starrable');
}

public function getDocs(string $version = null): ?string
public function getDocUrl(string $version = null): ?string
{
if (filled($this->content)) {
return $this->content;
if (filled($this->docs_url)) {
return $this->docs_url;
}

$docs_url = $this->docs_url;

if (filled($this->docs_urls)) {
if ($version !== null) {
$docs_url = $this->docs_urls[$version];
} else {
$docs_url = $this->docs_urls[key($this->docs_urls)];
}
return $this->docs_urls[$version ?? key($this->docs_urls)] ?? null;
}

return null;
}

public function getDocs(string $version = null): ?string
{
if (filled($this->content)) {
return $this->content;
}

if (blank($docs_url)) {
if (blank($url = $this->getDocUrl($version))) {
return null;
}

try {
return cache()->remember(
"plugin:{$this->slug}:docs:{$version}",
now()->addHour(),
fn (): string => file_get_contents($docs_url),
fn (): string => file_get_contents($url),
);
} catch (\Throwable) {
return null;
Expand Down
112 changes: 82 additions & 30 deletions app/Support/Markdown.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,24 @@

namespace App\Support;

use Illuminate\Contracts\Support\Htmlable;
use Illuminate\Support\HtmlString;
use League\CommonMark\Environment\Environment;
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
use League\CommonMark\Extension\HeadingPermalink\HeadingPermalinkExtension;
use League\CommonMark\Extension\Table\TableExtension;
use League\CommonMark\Extension\TableOfContents\TableOfContentsExtension;
use League\CommonMark\MarkdownConverter;
use Stringable;
use Torchlight\Commonmark\V2\TorchlightExtension;

class Markdown
class Markdown implements Htmlable, Stringable
{
public static function parse(string $text): HtmlString
{
$text = self::convertSpecialBlockQuotes($text);
protected Environment $environment;

$environment = new Environment([
public function __construct(protected string $content)
{
$this->environment = new Environment([
'allow_unsafe_links' => false,
'heading_permalink' => [
'html_class' => 'heading-anchor',
Expand All @@ -37,35 +39,85 @@ public static function parse(string $text): HtmlString
],
]);

$environment->addExtension(new CommonMarkCoreExtension);
$environment->addExtension(new TableExtension);
$environment->addExtension(new HeadingPermalinkExtension);
$environment->addExtension(new TorchlightExtension);
$environment->addExtension(new TableOfContentsExtension);
$this->environment->addExtension(new CommonMarkCoreExtension);
$this->environment->addExtension(new TableExtension);
$this->environment->addExtension(new HeadingPermalinkExtension);
$this->environment->addExtension(new TorchlightExtension);
$this->environment->addExtension(new TableOfContentsExtension);
}

public static function parse(string $text): static
{
$static = app(static::class, ['content' => $text]);

$static->convert();
$static->removeH1Tags();
$static->convertSpecialBlockQuotes();

return $static;
}

protected function convert(): static
{
$this->content = (new MarkdownConverter($this->environment))
->convert($this->content)
->getContent();

return $this;
}

protected function removeH1Tags(): static
{
$this->content = preg_replace(
pattern: '/\<h1(.*)\>(.*)\<\/h1\>/',
replacement: '',
subject: $this->content
);

$converter = new MarkdownConverter($environment);
return $this;
}

return new HtmlString($converter->convert($text)->getContent());
protected function convertSpecialBlockQuotes(): static
{
$this->content = preg_replace(
pattern: [
'/> \[\!NOTE\]\s*\n> /',
'/> \[\!TIP\]\s*\n> /',
'/> \[\!IMPORTANT\]\s*\n> /',
'/> \[\!WARNING\]\s*\n> /',
'/> \[\!CAUTION\]\s*\n> /',
],
replacement: [
'> 📝 **Note:** ',
'> 💡 **Tip:** ',
'> ❗ **Important:** ',
'> ⚠️ **Warning:** ',
'> ⚠️ **Caution:** ',
],
subject: $this->content
);

return $this;
}

public function absoluteImageUrls(string $baseUrl): static
{
$this->content = preg_replace(
pattern: '/src=["\'](?!https?:\/\/)([^"\']+)["\'][^>]/i',
replacement: 'src="' . $baseUrl . '$1" ',
subject: $this->content
);

return $this;
}

public function __toString(): string
{
return str($this->content)->sanitizeHtml();
}

protected static function convertSpecialBlockQuotes(string $text): string
public function toHtml()
{
$searchPatterns = [
'/> \[\!NOTE\]\s*\n> /',
'/> \[\!TIP\]\s*\n> /',
'/> \[\!IMPORTANT\]\s*\n> /',
'/> \[\!WARNING\]\s*\n> /',
'/> \[\!CAUTION\]\s*\n> /',
];
$replacePatterns = [
'> 📝 **Note:** ',
'> 💡 **Tip:** ',
'> ❗ **Important:** ',
'> ⚠️ **Warning:** ',
'> ⚠️ **Caution:** ',
];

// Perform the replacement
return preg_replace($searchPatterns, $replacePatterns, $text);
return new HtmlString($this->content);
}
}
2 changes: 1 addition & 1 deletion resources/views/articles/view-article.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ class="select-none rounded-full bg-stone-200/50 px-5 py-2.5 text-sm"
<div
class="prose selection:bg-stone-500/30 prose-a:break-words prose-blockquote:not-italic prose-code:break-words prose-code:rounded prose-code:bg-merino prose-code:px-1.5 prose-code:py-0.5 prose-code:font-normal prose-code:before:hidden prose-code:after:hidden [&_p]:before:hidden [&_p]:after:hidden"
>
{!! preg_replace('/\<h1(.*)\>(.*)\<\/h1\>/', '', str(\App\Support\Markdown::parse($article->content))->sanitizeHtml()) !!}
{!! \App\Support\Markdown::parse($article->content) !!}
</div>
</div>
</div>
Expand Down
8 changes: 7 additions & 1 deletion resources/views/plugins/view-plugin.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,13 @@ class="block w-32 rounded-lg border border-gray-300 bg-gray-50 p-2 text-sm text-
<div
class="prose selection:bg-stone-500/30 prose-a:break-words prose-blockquote:not-italic prose-code:break-words prose-code:rounded prose-code:bg-merino prose-code:px-1.5 prose-code:py-0.5 prose-code:font-normal prose-code:before:hidden prose-code:after:hidden [&_p]:before:hidden [&_p]:after:hidden"
>
{!! preg_replace('/\<h1(.*)\>(.*)\<\/h1\>/', '', str(\App\Support\Markdown::parse($docs))->sanitizeHtml()) !!}
{!!
\App\Support\Markdown::parse($docs)->absoluteImageUrls(
baseUrl: str($plugin->getDocUrl(request()->query('v')))
->lower()
->before('readme.md'),
)
!!}
</div>
</div>
@endif
Expand Down

0 comments on commit e1981e7

Please sign in to comment.