Skip to content

Commit

Permalink
Added inline color parsing.
Browse files Browse the repository at this point in the history
  • Loading branch information
johnnyhuy committed Mar 15, 2019
1 parent 24d4fc7 commit 42352d0
Show file tree
Hide file tree
Showing 11 changed files with 228 additions and 42 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,25 +121,35 @@ I've composed a wiki page to describe features of this extension.
Hello I should be in red text :D
:color

:color red this is inline! :color

# 3 Character hex
:color #AAA
Hello!
:color

:color #AAA this is inline! :color

# 6 Character hex
:color #DADADA
Hello!
:color

:color #DADADA this is inline! :color

# RGB
:color 255,255,255
Hello!
:color

:color 255,255,255 this is inline! :color

# RGBA
:color 255,255,255,50
Hello!
:color

:color 255,255,255,50 this is inline! :color
```

[More info](https://github.com/johnnyhuy/laravel-useful-commonmark-extension/wiki/Color)
Expand Down
7 changes: 7 additions & 0 deletions src/Inline/Element/Color.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace JohnnyHuy\Laravel\Inline\Element;

use League\CommonMark\Inline\Element\AbstractStringContainer;

class Color extends AbstractStringContainer {}
60 changes: 60 additions & 0 deletions src/Inline/Parser/ColorParser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

declare(strict_types=1);

namespace JohnnyHuy\Laravel\Inline\Parser;

use JohnnyHuy\Laravel\Inline\Element\Color;
use League\CommonMark\InlineParserContext;
use League\CommonMark\Inline\Parser\AbstractInlineParser;

class ColorParser extends AbstractInlineParser
{
/**
* @param InlineParserContext $inlineContext
* @return bool
*/
public function parse(InlineParserContext $inlineContext)
{
$cursor = $inlineContext->getCursor();
$savedState = $cursor->saveState();

$cursor->advance();

$regex = '/(?:color|colour)(?:\s(?:(\#?[A-z]+|\d{1,3}\,\s?\d{1,3}\,\s?\d{1,3}(\,\s?\d{1,3})?)))\s(.*(?!:color))\s(?:\:color)/';
$validate = $cursor->match($regex);

if (!$validate) {
$cursor->restoreState($savedState);
return false;
}

$matches = [];
preg_match($regex, $validate, $matches);
[, $color, $alpha, $content] = $matches;

if (preg_match('/[\,]+/', $color, $_)) {
if (empty($alpha)) {
$color = "rgb({$color})";
} else {
$color = "rgba({$color})";
}
} else if (preg_match('/[\#]+/', $color, $_)) {
$color = "#{$color}";
}

$data['color'] = $color;

$inlineContext->getContainer()->appendChild(new Color($content, $data));

return true;
}

/**
* @return string[]
*/
public function getCharacters()
{
return [':'];
}
}
14 changes: 7 additions & 7 deletions src/Inline/Renderer/CodepenRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

namespace JohnnyHuy\Laravel\Inline\Renderer;

use League\CommonMark\HtmlElement;
use League\CommonMark\Util\Configuration;
use ErrorException;
use JohnnyHuy\Laravel\Inline\Element\Codepen;
use League\CommonMark\ElementRendererInterface;
use League\CommonMark\HtmlElement;
use League\CommonMark\Inline\Element\AbstractInline;
use League\CommonMark\Util\ConfigurationAwareInterface;
use League\CommonMark\Inline\Element\AbstractWebResource;
use League\CommonMark\Inline\Renderer\InlineRendererInterface;
use League\CommonMark\Util\Configuration;

class CodepenRenderer implements InlineRendererInterface
{
Expand All @@ -20,10 +20,10 @@ class CodepenRenderer implements InlineRendererInterface

/**
* @param AbstractInline|AbstractWebResource $inline
* @param \League\CommonMark\ElementRendererInterface $htmlRenderer
* @param ElementRendererInterface $htmlRenderer
*
* @return \League\CommonMark\HtmlElement|string
* @throws \ErrorException
* @return HtmlElement|string
* @throws ErrorException
*/
public function render(AbstractInline $inline, ElementRendererInterface $htmlRenderer)
{
Expand All @@ -39,7 +39,7 @@ public function render(AbstractInline $inline, ElementRendererInterface $htmlRen
//seems that the used codepen url is invalid
//or codepen is currently not available
if (is_null($apiResponse)) {
throw new \ErrorException('Codepen request returned null: ' . $apiUrl);
throw new ErrorException('Codepen request returned null: ' . $apiUrl);
}

//parse the oembed response
Expand Down
45 changes: 45 additions & 0 deletions src/Inline/Renderer/ColorRenderer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

namespace JohnnyHuy\Laravel\Inline\Renderer;

use InvalidArgumentException;
use JohnnyHuy\Laravel\Inline\Element\Color;
use JohnnyHuy\Laravel\Inline\Element\YouTube;
use League\CommonMark\ElementRendererInterface;
use League\CommonMark\HtmlElement;
use League\CommonMark\Inline\Element\AbstractInline;
use League\CommonMark\Inline\Element\AbstractWebResource;
use League\CommonMark\Inline\Renderer\InlineRendererInterface;
use League\CommonMark\Util\Configuration;
use League\CommonMark\Util\ConfigurationAwareInterface;

class ColorRenderer implements InlineRendererInterface, ConfigurationAwareInterface
{
/**
* @var Configuration
*/
protected $config;

/**
* @param AbstractInline|AbstractWebResource $inline
* @param ElementRendererInterface $htmlRenderer
*
* @return HtmlElement|string
*/
public function render(AbstractInline $inline, ElementRendererInterface $htmlRenderer)
{
if (!($inline instanceof Color)) {
throw new InvalidArgumentException('Incompatible inline type: ' . get_class($inline));
}

return new HtmlElement('span', ['style' => "color: {$inline->getData('color')}"], $inline->getContent());
}

/**
* @param Configuration $configuration
*/
public function setConfiguration(Configuration $configuration)
{
$this->config = $configuration;
}
}
12 changes: 4 additions & 8 deletions src/Inline/Renderer/GistRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@

namespace JohnnyHuy\Laravel\Inline\Renderer;

use League\CommonMark\HtmlElement;
use League\CommonMark\Util\Configuration;
use JohnnyHuy\Laravel\Inline\Element\Gist;
use League\CommonMark\ElementRendererInterface;
use League\CommonMark\HtmlElement;
use League\CommonMark\Inline\Element\AbstractInline;
use League\CommonMark\Util\ConfigurationAwareInterface;
use League\CommonMark\Inline\Element\AbstractWebResource;
use League\CommonMark\Inline\Renderer\InlineRendererInterface;
use League\CommonMark\Util\Configuration;

class GistRenderer implements InlineRendererInterface
{
Expand All @@ -20,23 +19,20 @@ class GistRenderer implements InlineRendererInterface

/**
* @param AbstractInline|AbstractWebResource $inline
* @param \League\CommonMark\ElementRendererInterface $htmlRenderer
* @param ElementRendererInterface $htmlRenderer
*
* @return \League\CommonMark\HtmlElement|string
* @return HtmlElement|string
*/
public function render(AbstractInline $inline, ElementRendererInterface $htmlRenderer)
{
if (!($inline instanceof Gist)) {
throw new \InvalidArgumentException('Incompatible inline type: ' . get_class($inline));
}

//generates the same script element, which you can see
//in the "embed gist" input field
$script = new HtmlElement('script', [
'src' => $inline->getUrl().'.js'
]);

//add a div wrapper around the script element
return new HtmlElement('div', ['class' => 'gist-container'], $script);
}

Expand Down
26 changes: 13 additions & 13 deletions src/Inline/Renderer/SoundCloudRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

namespace JohnnyHuy\Laravel\Inline\Renderer;

use League\CommonMark\HtmlElement;
use League\CommonMark\Util\Configuration;
use League\CommonMark\ElementRendererInterface;
use ErrorException;
use JohnnyHuy\Laravel\Inline\Element\SoundCloud;
use League\CommonMark\ElementRendererInterface;
use League\CommonMark\HtmlElement;
use League\CommonMark\Inline\Element\AbstractInline;
use League\CommonMark\Util\ConfigurationAwareInterface;
use League\CommonMark\Inline\Element\AbstractWebResource;
use League\CommonMark\Inline\Renderer\InlineRendererInterface;
use League\CommonMark\Util\Configuration;

class SoundCloudRenderer implements InlineRendererInterface
{
Expand All @@ -20,10 +20,10 @@ class SoundCloudRenderer implements InlineRendererInterface

/**
* @param AbstractInline|AbstractWebResource $inline
* @param \League\CommonMark\ElementRendererInterface $htmlRenderer
* @param ElementRendererInterface $htmlRenderer
*
* @return \League\CommonMark\HtmlElement|string
* @throws \ErrorException
* @return HtmlElement|string
* @throws ErrorException
*/
public function render(AbstractInline $inline, ElementRendererInterface $htmlRenderer)
{
Expand All @@ -35,16 +35,16 @@ public function render(AbstractInline $inline, ElementRendererInterface $htmlRen
$url = "https://soundcloud.com/oembed?&format=json&url={$inline->getUrl()}&maxheight=166";
$soundCloud = $this->getContent($url);

//seems that the used soundcloud url is invalid
//or soundcloud is currently not available
if (is_null($soundCloud)) {
throw new \ErrorException('SoundCloud request returned null: ' . $url);
// Seems that the used SoundCloud url is invalid
// or SoundCloud is currently not available
if ($soundCloud === null) {
throw new ErrorException('SoundCloud request returned null: ' . $url);
}

//parse the oembed response
// Parse the embed response
$soundCloud = json_decode($soundCloud);

//use the oembed html snippet as response
// Use the embed html snippet as response
return $soundCloud->html;
}

Expand Down
14 changes: 7 additions & 7 deletions src/Inline/Renderer/YouTubeRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

namespace JohnnyHuy\Laravel\Inline\Renderer;

use League\CommonMark\HtmlElement;
use League\CommonMark\Util\Configuration;
use JohnnyHuy\Laravel\Inline\Element\YouTube;
use League\CommonMark\ElementRendererInterface;
use League\CommonMark\HtmlElement;
use League\CommonMark\Inline\Element\AbstractInline;
use League\CommonMark\Util\ConfigurationAwareInterface;
use League\CommonMark\Inline\Element\AbstractWebResource;
use League\CommonMark\Inline\Renderer\InlineRendererInterface;
use League\CommonMark\Util\Configuration;
use League\CommonMark\Util\ConfigurationAwareInterface;

class YouTubeRenderer implements InlineRendererInterface, ConfigurationAwareInterface
{
Expand All @@ -20,17 +20,17 @@ class YouTubeRenderer implements InlineRendererInterface, ConfigurationAwareInte

/**
* @param AbstractInline|AbstractWebResource $inline
* @param \League\CommonMark\ElementRendererInterface $htmlRenderer
* @param ElementRendererInterface $htmlRenderer
*
* @return \League\CommonMark\HtmlElement|string
* @return HtmlElement|string
*/
public function render(AbstractInline $inline, ElementRendererInterface $htmlRenderer)
{
if (!($inline instanceof YouTube)) {
throw new \InvalidArgumentException('Incompatible inline type: ' . get_class($inline));
}

//create a new iframe with the given youtube url
// Create a new iframe with the given youtube url
$iframe = new HtmlElement('iframe', [
'width' => 640,
'height' => 390,
Expand All @@ -39,7 +39,7 @@ public function render(AbstractInline $inline, ElementRendererInterface $htmlRen
'frameborder' => 0,
]);

//return the iframe with a span as wrapper element
// Return the iframe with a span as wrapper element
return new HtmlElement('span', ['class' => 'youtube-video'], $iframe);
}

Expand Down
Loading

0 comments on commit 42352d0

Please sign in to comment.