Skip to content

Commit cc4a5c6

Browse files
committed
Split code into parser and renderer.
1 parent f5e25e6 commit cc4a5c6

29 files changed

+600
-374
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Release Notes
22

3+
## v2.0.0 (2018-06-17)
4+
5+
- Split code into parser and renderer.
6+
37
## v1.3.0 (2018-06-15)
48

59
- Added support for multiple parsers with the same character.

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,16 @@ A Laravel package for converting URLs in a given string of text into clickable l
1515
composer require osiemsiedem/laravel-autolink
1616
```
1717

18+
## Usage
19+
20+
```php
21+
use OsiemSiedem\Autolink\Facades\Autolink;
22+
23+
echo Autolink::convert('Check this out - www.example.com. This will be ignored - <a href="http://example.com">My awesome website</a>.');
24+
25+
// Check this out - <a href="http://www.example.com">example.com</a>. This will be ignored - <a href="http://example.com">My awesome website</a>.
26+
```
27+
1828
## Testing
1929

2030
```

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
"require": {
1212
"php": "^7.1.3",
1313
"illuminate/support": "5.5.*|5.6.*",
14-
"symfony/polyfill-mbstring": "^1.0"
14+
"symfony/polyfill-mbstring": "^1.0",
15+
"spatie/laravel-html": "^2.19"
1516
},
1617
"require-dev": {
1718
"phpunit/phpunit": "^6.0|^7.0",

config/autolink.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
return [
66
/*
77
|--------------------------------------------------------------------------
8-
| Ignored Elements
8+
| Ignored Tags
99
|--------------------------------------------------------------------------
1010
|
1111
*/
12-
'ignored' => [
12+
'ignored_tags' => [
1313
'a',
1414
'code',
1515
'kbd',

src/Autolink.php

Lines changed: 27 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -5,146 +5,67 @@
55
namespace OsiemSiedem\Autolink;
66

77
use Illuminate\Support\HtmlString;
8-
use OsiemSiedem\Autolink\Contracts\Filter;
9-
use OsiemSiedem\Autolink\Contracts\Parser;
108

119
class Autolink
1210
{
1311
/**
14-
* @var array
12+
* @var \OsiemSiedem\Autolink\Parser
1513
*/
16-
protected $filters = [];
14+
protected $parser;
1715

1816
/**
19-
* @var array
17+
* @var \OsiemSiedem\Autolink\HtmlRenderer
2018
*/
21-
protected $parsers = [];
19+
protected $renderer;
2220

2321
/**
24-
* @var array
25-
*/
26-
protected $ignored = ['a', 'pre', 'code', 'kbd', 'script'];
27-
28-
/**
29-
* Add a new extension.
22+
* Create a new instance.
3023
*
31-
* @param \OsiemSiedem\Autolink\Contracts\Filter $filter
32-
* @return $this
24+
* @param \OsiemSiedem\Autolink\Parser $parser
25+
* @param \OsiemSiedem\Autolink\HtmlRenderer $renderer
26+
* @return void
3327
*/
34-
public function addFilter(Filter $filter): self
28+
public function __construct(Parser $parser, HtmlRenderer $renderer)
3529
{
36-
$this->filters[] = $filter;
37-
38-
return $this;
30+
$this->parser = $parser;
31+
$this->renderer = $renderer;
3932
}
4033

4134
/**
42-
* Add a new parser.
35+
* Convert the URLs into clickable links.
4336
*
44-
* @param \OsiemSiedem\Autolink\Contracts\Parser $parser
45-
* @return $this
37+
* @param string $text
38+
* @param callable|null $callback
39+
* @return \Illuminate\Support\HtmlString
4640
*/
47-
public function addParser(Parser $parser): self
41+
public function convert(string $text, callable $callback = null): HtmlString
4842
{
49-
foreach ($parser->getCharacters() as $character) {
50-
$this->parsers[$character][] = $parser;
51-
}
43+
$elements = $this->parse($text);
5244

53-
return $this;
45+
return $this->render($text, $elements, $callback);
5446
}
5547

5648
/**
57-
* Set the ignored tags.
49+
* Parse the text.
5850
*
59-
* @param array $ignored
60-
* @return $this
51+
* @param string $text
52+
* @return array
6153
*/
62-
public function ignore(array $ignored): self
54+
public function parse(string $text): array
6355
{
64-
$this->ignored = $ignored;
65-
66-
return $this;
56+
return $this->parser->parse($text);
6757
}
6858

6959
/**
70-
* Convert the URLs into clickable links.
60+
* Render the elements.
7161
*
7262
* @param string $text
63+
* @param array $elements
7364
* @param callable|null $callback
7465
* @return \Illuminate\Support\HtmlString
7566
*/
76-
public function convert(string $text, callable $callback = null): HtmlString
67+
public function render(string $text, array $elements, callable $callback = null): HtmlString
7768
{
78-
$cursor = new Cursor($text);
79-
80-
$links = [];
81-
82-
foreach ($cursor as $character) {
83-
if ($character === '<') {
84-
foreach ($this->ignored as $ignored) {
85-
if ($cursor->match("#^<{$ignored}[\s>]#i")) {
86-
$cursor->next(strlen($ignored) + 1);
87-
88-
while ($cursor->valid()) {
89-
while ($cursor->valid() && $cursor->getCharacter() !== '<') {
90-
$cursor->next();
91-
}
92-
93-
if ($cursor->getPosition() === $cursor->getLength()) {
94-
break 2;
95-
}
96-
97-
if ($cursor->match("#^</{$ignored}[\s>]#i")) {
98-
break 2;
99-
}
100-
101-
$cursor->next();
102-
}
103-
104-
break;
105-
}
106-
}
107-
108-
while ($cursor->valid() && $cursor->getCharacter() !== '>') {
109-
$cursor->next();
110-
}
111-
112-
continue;
113-
}
114-
115-
$parsers = array_get($this->parsers, $character);
116-
117-
if (is_null($parsers)) {
118-
continue;
119-
}
120-
121-
foreach ($parsers as $parser) {
122-
if ($link = $parser->parse($cursor)) {
123-
$links[] = $link;
124-
125-
break;
126-
}
127-
}
128-
}
129-
130-
for ($i = count($links) - 1; $i >= 0; $i--) {
131-
$start = $links[$i]->getStart();
132-
133-
$end = $links[$i]->getEnd();
134-
135-
foreach ($this->filters as $filter) {
136-
$links[$i] = $filter->filter($links[$i]);
137-
}
138-
139-
if ( ! is_null($callback)) {
140-
$links[$i] = $callback($links[$i]);
141-
}
142-
143-
$text = mb_substr($text, 0, $start)
144-
.$links[$i]->toHtml()
145-
.mb_substr($text, $end, mb_strlen($text) - $end);
146-
}
147-
148-
return new HtmlString($text);
69+
return $this->renderer->render($text, $elements, $callback);
14970
}
15071
}

src/AutolinkServiceProvider.php

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,22 +38,32 @@ public function boot()
3838
*/
3939
public function register()
4040
{
41-
$this->app->singleton('osiemsiedem.autolink', function ($app) {
41+
$this->app->singleton('osiemsiedem.autolink.parser', function ($app) {
4242
$config = $app['config']->get('autolink');
4343

44-
$autolink = new Autolink;
44+
$parser = new Parser;
4545

46-
$autolink->ignore($config['ignored']);
46+
$parser->setIgnoredTags($config['ignored_tags']);
4747

48-
foreach ($config['filters'] as $filter) {
49-
$autolink->addFilter(new $filter);
48+
foreach ($config['parsers'] as $elementParser) {
49+
$parser->addElementParser(new $elementParser);
5050
}
5151

52-
foreach ($config['parsers'] as $parser) {
53-
$autolink->addParser(new $parser);
52+
return $parser;
53+
});
54+
55+
$this->app->singleton('osiemsiedem.autolink.renderer', function ($app) {
56+
$renderer = new HtmlRenderer;
57+
58+
foreach ($app['config']->get('autolink.filters') as $filter) {
59+
$renderer->addFilter(new $filter);
5460
}
5561

56-
return $autolink;
62+
return $renderer;
63+
});
64+
65+
$this->app->singleton('osiemsiedem.autolink', function ($app) {
66+
return new Autolink($app['osiemsiedem.autolink.parser'], $app['osiemsiedem.autolink.renderer']);
5767
});
5868
}
5969

@@ -64,6 +74,10 @@ public function register()
6474
*/
6575
public function provides()
6676
{
67-
return ['osiemsiedem.autolink'];
77+
return [
78+
'osiemsiedem.autolink.parser',
79+
'osiemsiedem.autolink.renderer',
80+
'osiemsiedem.autolink',
81+
];
6882
}
6983
}

src/Contracts/Element.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace OsiemSiedem\Autolink\Contracts;
6+
7+
interface Element
8+
{
9+
//
10+
}

src/Contracts/Filter.php

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,13 @@
44

55
namespace OsiemSiedem\Autolink\Contracts;
66

7-
use OsiemSiedem\Autolink\Link;
8-
97
interface Filter
108
{
119
/**
12-
* Filter the link.
10+
* Filter the element.
1311
*
14-
* @param \OsiemSiedem\Autolink\Link $link
15-
* @return \OsiemSiedem\Autolink\Link
12+
* @param \OsiemSiedem\Autolink\Contracts\Element $element
13+
* @return \OsiemSiedem\Autolink\Contracts\Element
1614
*/
17-
public function filter(Link $link): Link;
15+
public function filter(Element $element): Element;
1816
}

src/Contracts/Parser.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
namespace OsiemSiedem\Autolink\Contracts;
66

7-
use OsiemSiedem\Autolink\Link;
87
use OsiemSiedem\Autolink\Cursor;
98

109
interface Parser
@@ -20,7 +19,7 @@ public function getCharacters(): array;
2019
* Parse the text.
2120
*
2221
* @param \OsiemSiedem\Autolink\Cursor $cursor
23-
* @return \OsiemSiedem\Autolink\Link|null
22+
* @return \OsiemSiedem\Autolink\Contracts\Element|null
2423
*/
25-
public function parse(Cursor $cursor): ?Link;
24+
public function parse(Cursor $cursor): ?Element;
2625
}

0 commit comments

Comments
 (0)