Skip to content

Commit d18d043

Browse files
committed
Initial commit.
0 parents  commit d18d043

29 files changed

+1953
-0
lines changed

.editorconfig

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
end_of_line = lf
6+
indent_size = 4
7+
indent_style = space
8+
insert_final_newline = true
9+
trim_trailing_whitespace = true
10+
11+
[*.md]
12+
trim_trailing_whitespace = false
13+
14+
[*.yml]
15+
indent_style = space
16+
indent_size = 2

.gitattributes

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
* text=auto
2+
3+
/tests export-ignore
4+
/.editorconfig export-ignore
5+
/.gitattributes export-ignore
6+
/.gitignore export-ignore
7+
/.travis.yml export-ignore
8+
/CHANGELOG.md export-ignore
9+
/phpunit.xml.dist export-ignore
10+
/README.md export-ignore

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
vendor/
2+
composer.lock
3+
phpunit.xml

.travis.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
language: php
2+
3+
sudo: false
4+
5+
php:
6+
- 7.1
7+
- 7.2
8+
9+
before_script:
10+
- travis_retry composer self-update
11+
12+
install:
13+
- travis_retry composer install --no-interaction --prefer-dist
14+
15+
script:
16+
- vendor/bin/phpunit

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Release Notes
2+
3+
## v1.0.0 (2018-05-29)
4+
5+
Initial release.

LICENSE.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) Marek Szymczuk
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.

README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Laravel Autolink
2+
3+
[![Build Status](https://travis-ci.org/osiemsiedem/laravel-autolink.svg?branch=master)](https://travis-ci.org/osiemsiedem/laravel-autolink)
4+
5+
A Laravel package for converting URLs in a given string of text into clickable links.
6+
7+
## Requirements
8+
9+
- PHP >= 7.1.3
10+
- Laravel >= 5.5
11+
12+
## Installation
13+
14+
```
15+
composer require osiemsiedem/laravel-autolink
16+
```
17+
18+
## Testing
19+
20+
```
21+
./vendor/bin/phpunit
22+
```
23+
24+
## Credits
25+
26+
This package is based on the [Rinku](https://github.com/vmg/rinku) library.
27+
28+
- [Marek Szymczuk](https://github.com/bonzai)
29+
- [All Contributors](../../contributors)
30+
31+
## License
32+
33+
Please see the [LICENSE.md](LICENSE.md) file.

composer.json

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"name": "osiemsiedem/laravel-autolink",
3+
"keywords": ["laravel", "autolink", "html", "email", "url", "www"],
4+
"license": "MIT",
5+
"authors": [
6+
{
7+
"name": "Marek Szymczuk",
8+
"email": "[email protected]"
9+
}
10+
],
11+
"require": {
12+
"php": "^7.1.3",
13+
"illuminate/support": "5.5.*|5.6.*",
14+
"symfony/polyfill-mbstring": "^1.8"
15+
},
16+
"require-dev": {
17+
"phpunit/phpunit": "^6.0|^7.0"
18+
},
19+
"autoload": {
20+
"psr-4" : {
21+
"OsiemSiedem\\Autolink\\" : "src/"
22+
},
23+
"files": [
24+
"src/helpers.php"
25+
]
26+
},
27+
"autoload-dev": {
28+
"psr-4": {
29+
"OsiemSiedem\\Tests\\Autolink\\": "tests/"
30+
}
31+
},
32+
"extra": {
33+
"laravel": {
34+
"providers": [
35+
"OsiemSiedem\\Autolink\\AutolinkServiceProvider"
36+
]
37+
}
38+
}
39+
}

phpunit.xml.dist

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit backupGlobals="false"
3+
backupStaticAttributes="false"
4+
bootstrap="vendor/autoload.php"
5+
colors="true"
6+
convertErrorsToExceptions="true"
7+
convertNoticesToExceptions="true"
8+
convertWarningsToExceptions="true"
9+
processIsolation="false"
10+
stopOnFailure="false"
11+
syntaxCheck="false">
12+
<testsuites>
13+
<testsuite name="Laravel Autolink Test Suite">
14+
<directory suffix="Test.php">./tests</directory>
15+
</testsuite>
16+
</testsuites>
17+
<filter>
18+
<whitelist processUncoveredFilesFromWhitelist="true">
19+
<directory suffix=".php">./src</directory>
20+
</whitelist>
21+
</filter>
22+
</phpunit>

src/Autolink.php

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace OsiemSiedem\Autolink;
6+
7+
use Illuminate\Support\HtmlString;
8+
use OsiemSiedem\Autolink\Contracts\Filter;
9+
use OsiemSiedem\Autolink\Contracts\Parser;
10+
11+
class Autolink
12+
{
13+
/**
14+
* @var array
15+
*/
16+
protected $filters = [];
17+
18+
/**
19+
* @var array
20+
*/
21+
protected $parsers = [];
22+
23+
/**
24+
* @var array
25+
*/
26+
protected $ignored = ['a', 'pre', 'code', 'kbd', 'script'];
27+
28+
/**
29+
* Add a new extension.
30+
*
31+
* @param \OsiemSiedem\Autolink\Contracts\Filter $filter
32+
* @return $this
33+
*/
34+
public function addFilter(Filter $filter): self
35+
{
36+
$this->filters[] = $filter;
37+
38+
return $this;
39+
}
40+
41+
/**
42+
* Add a new parser.
43+
*
44+
* @param \OsiemSiedem\Autolink\Contracts\Parser $parser
45+
* @return $this
46+
*/
47+
public function addParser(Parser $parser): self
48+
{
49+
foreach ($parser->getCharacters() as $character) {
50+
$this->parsers[$character] = $parser;
51+
}
52+
53+
return $this;
54+
}
55+
56+
/**
57+
* Set the ignored tags.
58+
*
59+
* @param array $ignore
60+
* @return $this
61+
*/
62+
public function ignore(array $ignored): self
63+
{
64+
$this->ignored = $ignored;
65+
66+
return $this;
67+
}
68+
69+
/**
70+
* Convert the URLs into clickable links.
71+
*
72+
* @param string $text
73+
* @param callable $callback
74+
* @return \Illuminate\Support\HtmlString
75+
*/
76+
public function convert(string $text, callable $callback = null): HtmlString
77+
{
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+
$parser = array_get($this->parsers, $character);
116+
117+
if (is_null($parser)) {
118+
continue;
119+
}
120+
121+
if ($link = $parser->parse($cursor)) {
122+
$links[] = $link;
123+
}
124+
}
125+
126+
for ($i = count($links) - 1; $i >= 0; $i--) {
127+
$start = $links[$i]->getStart();
128+
129+
$end = $links[$i]->getEnd();
130+
131+
foreach ($this->filters as $filter) {
132+
$links[$i] = $filter->filter($links[$i]);
133+
}
134+
135+
if ( ! is_null($callback)) {
136+
$links[$i] = $callback($links[$i]);
137+
}
138+
139+
$text = mb_substr($text, 0, $start)
140+
.$links[$i]->toHtml()
141+
.mb_substr($text, $end, mb_strlen($text) - $end);
142+
}
143+
144+
return new HtmlString($text);
145+
}
146+
}

0 commit comments

Comments
 (0)