Completed
Push — master ( fbfcb5...11633f )
by Josh
17:15
created

Parser::trimUrl()   B

Complexity

Conditions 4
Paths 2

Size

Total Lines 22
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 22
rs 8.9197
c 1
b 0
f 0
ccs 9
cts 9
cp 1
cc 4
eloc 8
nc 2
nop 1
crap 4
1
<?php
2
3
/**
4
* @package   s9e\TextFormatter
5
* @copyright Copyright (c) 2010-2016 The s9e Authors
6
* @license   http://www.opensource.org/licenses/mit-license.php The MIT License
7
*/
8
namespace s9e\TextFormatter\Plugins\Autolink;
9
10
use s9e\TextFormatter\Plugins\ParserBase;
11
12
class Parser extends ParserBase
13
{
14
	/**
15
	* {@inheritdoc}
16
	*/
17 31
	public function parse($text, array $matches)
18
	{
19 31
		foreach ($matches as $m)
20
		{
21
			// Linkify the trimmed URL
22 31
			$this->linkifyUrl($m[0][1], $this->trimUrl($m[0][0]));
23 31
		}
24 31
	}
25
26
	/**
27
	* Linkify given URL at given position
28
	*
29
	* @param  integer $tagPos URL's position in the text
30
	* @param  string  $url    URL
31
	* @return void
32
	*/
33 31
	protected function linkifyUrl($tagPos, $url)
34
	{
35
		// Ensure that the anchor (scheme/www) is still there
36 31
		if (!preg_match('/^[^:]+:|^www\\./i', $url))
37 31
		{
38 2
			return;
39
		}
40
41
		// Create a zero-width end tag right after the URL
42 29
		$endTag = $this->parser->addEndTag($this->config['tagName'], $tagPos + strlen($url), 0);
43
44
		// If the URL starts with "www." we prepend "http://"
45 29
		if ($url[3] === '.')
46 29
		{
47 3
			$url = 'http://' . $url;
48 3
		}
49
50
		// Create a zero-width start tag right before the URL
51 29
		$startTag = $this->parser->addStartTag($this->config['tagName'], $tagPos, 0);
52 29
		$startTag->setAttribute($this->config['attrName'], $url);
53
54
		// Give this tag a slightly lower priority than default to allow specialized plugins
55
		// to use the URL instead
56 29
		$startTag->setSortPriority(1);
57
58
		// Pair the tags together
59 29
		$startTag->pairWith($endTag);
60 29
	}
61
62
	/**
63
	* Remove trailing punctuation from given URL
64
	*
65
	* Removes trailing punctuation and right angle brackets. We preserve right parentheses
66
	* if there's a balanced number of parentheses in the URL, e.g.
67
	*   http://en.wikipedia.org/wiki/Mars_(disambiguation)
68
	*
69
	* @param  string $url Original URL
70
	* @return string      Trimmed URL
71
	*/
72 31
	protected function trimUrl($url)
73
	{
74 31
		while (1)
75
		{
76
			// We remove most ASCII non-letters and Unicode punctuation from the end of the string.
77
			// Exceptions:
78
			//  - dashes (some YouTube URLs end with a dash due to the video ID)
79
			//  - equal signs (because of "foo?bar="),
80
			//  - trailing slashes,
81
			//  - closing parentheses are balanced separately.
82 31
			$url = preg_replace('#(?![-=/)])[\\s!-.:-@[-`{-~\\pP]+$#Du', '', $url);
83
84 31
			if (substr($url, -1) === ')' && substr_count($url, '(') < substr_count($url, ')'))
85 31
			{
86 2
				$url = substr($url, 0, -1);
87 2
				continue;
88
			}
89 31
			break;
90
		}
91
92 31
		return $url;
93
	}
94
}