Completed
Push — master ( 0219e4...89d0da )
by Josh
19:23
created

Parser::parseAsciiEmoji()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 22
rs 9.2568
c 0
b 0
f 0
ccs 13
cts 13
cp 1
cc 5
nc 5
nop 1
crap 5
1
<?php
2
3
/**
4
* @package   s9e\TextFormatter
5
* @copyright Copyright (c) 2010-2018 The s9e Authors
6
* @license   http://www.opensource.org/licenses/mit-license.php The MIT License
7
*/
8
namespace s9e\TextFormatter\Plugins\Emoji;
9
10
use s9e\TextFormatter\Plugins\ParserBase;
11
12
class Parser extends ParserBase
13
{
14
	/**
15
	* @var string Regexp used to match shortnames
16
	*/
17
	protected $shortnameRegexp = '/:[-+_a-z0-9]+(?=:)/';
18
19
	/**
20
	* @var string Regexp used to match UTF-8 emoji
21
	*/
22
	protected $unicodeRegexp = '((?:[#*0-9]\\xEF\\xB8\\x8F(?:\\xE2\\x83\\xA3)?|\\xC2[\\xA9\\xAE]\\xEF\\xB8\\x8F|\\xE2(?:\\x80\\xBC\\xEF\\xB8\\x8F|\\x81\\x89\\xEF\\xB8\\x8F|\\x84[\\xA2\\xB9]\\xEF\\xB8\\x8F|\\x86[\\x94-\\x99\\xA9\\xAA]\\xEF\\xB8\\x8F|\\x8C(?:[\\x9A\\x9B](?:\\xEF\\xB8\\x8F)?|\\xA8\\xEF\\xB8\\x8F)|\\x8F(?:[\\x8F\\xAD-\\xAF\\xB1\\xB2\\xB8-\\xBA]\\xEF\\xB8\\x8F|[\\xA9-\\xAC\\xB0\\xB3](?:\\xEF\\xB8\\x8F)?)|\\x93\\x82\\xEF\\xB8\\x8F|\\x96[\\xAA\\xAB\\xB6]\\xEF\\xB8\\x8F|\\x97(?:[\\x80\\xBB\\xBC]\\xEF\\xB8\\x8F|[\\xBD\\xBE](?:\\xEF\\xB8\\x8F)?)|\\x98(?:[\\x80-\\x84\\x8E\\x91\\x98\\xA0\\xA2\\xA3\\xA6\\xAA\\xAE\\xAF\\xB8-\\xBA]\\xEF\\xB8\\x8F|[\\x94\\x95](?:\\xEF\\xB8\\x8F)?|\\x9D(?:\\xEF\\xB8\\x8F|\\xF0\\x9F\\x8F[\\xBB-\\xBF]))|\\x99(?:[\\x80\\x82\\xA0\\xA3\\xA5\\xA6\\xA8\\xBB]\\xEF\\xB8\\x8F|[\\x88-\\x93\\xBF](?:\\xEF\\xB8\\x8F)?)|\\x9A(?:[\\x92\\x94-\\x97\\x99\\x9B\\x9C\\xA0\\xB0\\xB1]\\xEF\\xB8\\x8F|[\\x93\\xA1\\xAA\\xAB\\xBD\\xBE](?:\\xEF\\xB8\\x8F)?)|\\x9B(?:[\\x84\\x85\\x8E\\x94\\xAA\\xB2\\xB3\\xB5\\xBA\\xBD](?:\\xEF\\xB8\\x8F)?|[\\x88\\x8F\\x91\\x93\\xA9\\xB0\\xB1\\xB4\\xB7\\xB8]\\xEF\\xB8\\x8F|\\xB9(?:\\xEF\\xB8\\x8F|\\xF0\\x9F\\x8F[\\xBB-\\xBF])(?:\\xE2\\x80\\x8D\\xE2\\x99[\\x80\\x82]\\xEF\\xB8\\x8F)?)|\\x9C(?:[\\x82\\x88\\x89\\x8F\\x92\\x94\\x96\\x9D\\xA1\\xB3\\xB4]\\xEF\\xB8\\x8F|[\\x85\\xA8](?:\\xEF\\xB8\\x8F)?|[\\x8A\\x8B](?:\\xEF\\xB8\\x8F|\\xF0\\x9F\\x8F[\\xBB-\\xBF])?|[\\x8C\\x8D](?:\\xEF\\xB8\\x8F|\\xF0\\x9F\\x8F[\\xBB-\\xBF]))|\\x9D(?:[\\x84\\x87\\xA3\\xA4]\\xEF\\xB8\\x8F|[\\x8C\\x8E\\x93-\\x95\\x97](?:\\xEF\\xB8\\x8F)?)|\\x9E(?:[\\x95-\\x97\\xB0\\xBF](?:\\xEF\\xB8\\x8F)?|\\xA1\\xEF\\xB8\\x8F)|\\xA4[\\xB4\\xB5]\\xEF\\xB8\\x8F|\\xAC(?:[\\x85-\\x87]\\xEF\\xB8\\x8F|[\\x9B\\x9C](?:\\xEF\\xB8\\x8F)?)|\\xAD[\\x90\\x95](?:\\xEF\\xB8\\x8F)?)|\\xE3(?:\\x80[\\xB0\\xBD]|\\x8A[\\x97\\x99])\\xEF\\xB8\\x8F|\\xF0\\x9F(?:\\x80\\x84(?:\\xEF\\xB8\\x8F)?|\\x83\\x8F(?:\\xEF\\xB8\\x8F)?|\\x85[\\xB0\\xB1\\xBE\\xBF]\\xEF\\xB8\\x8F|\\x86[\\x8E\\x91-\\x9A](?:\\xEF\\xB8\\x8F)?|\\x87[\\xA6-\\xBF](?:\\xEF\\xB8\\x8F|\\xF0\\x9F\\x87[\\xA6-\\xBF])?|\\x88(?:[\\x81\\x9A\\xAF\\xB2-\\xB6\\xB8-\\xBA](?:\\xEF\\xB8\\x8F)?|[\\x82\\xB7]\\xEF\\xB8\\x8F)|\\x89[\\x90\\x91](?:\\xEF\\xB8\\x8F)?|\\x8C(?:[\\x80-\\xA0\\xAD-\\xB5\\xB7-\\xBF](?:\\xEF\\xB8\\x8F)?|[\\xA1\\xA4-\\xAC\\xB6]\\xEF\\xB8\\x8F)|\\x8D(?:[\\x80-\\xBC\\xBE\\xBF](?:\\xEF\\xB8\\x8F)?|\\xBD\\xEF\\xB8\\x8F)|\\x8E(?:[\\x80-\\x84\\x86-\\x93\\xA0-\\xBF](?:\\xEF\\xB8\\x8F)?|[\\x96\\x97\\x99-\\x9B\\x9E\\x9F]\\xEF\\xB8\\x8F|\\x85(?:\\xEF\\xB8\\x8F|\\xF0\\x9F\\x8F[\\xBB-\\xBF])?)|\\x8F(?:[\\x80\\x81\\x85\\x86\\x88\\x89\\x8F-\\x93\\xA0-\\xB0\\xB8-\\xBF](?:\\xEF\\xB8\\x8F)?|[\\x82\\x87](?:\\xEF\\xB8\\x8F|\\xF0\\x9F\\x8F[\\xBB-\\xBF])?|[\\x83\\x84\\x8A](?:\\xE2\\x80\\x8D\\xE2\\x99[\\x80\\x82]\\xEF\\xB8\\x8F|\\xEF\\xB8\\x8F|\\xF0\\x9F\\x8F[\\xBB-\\xBF](?:\\xE2\\x80\\x8D\\xE2\\x99[\\x80\\x82]\\xEF\\xB8\\x8F)?)?|[\\x8B\\x8C](?:\\xEF\\xB8\\x8F|\\xF0\\x9F\\x8F[\\xBB-\\xBF])(?:\\xE2\\x80\\x8D\\xE2\\x99[\\x80\\x82]\\xEF\\xB8\\x8F)?|[\\x8D\\x8E\\x94-\\x9F\\xB5\\xB7]\\xEF\\xB8\\x8F|\\xB3\\xEF\\xB8\\x8F(?:\\xE2\\x80\\x8D\\xF0\\x9F\\x8C\\x88)?|\\xB4(?:\\xEF\\xB8\\x8F|\\xF3\\xA0\\x81\\xA7\\xF3\\xA0\\x81\\xA2\\xF3\\xA0\\x81(?:\\xA5\\xF3\\xA0\\x81\\xAE\\xF3\\xA0\\x81\\xA7|\\xB3\\xF3\\xA0\\x81\\xA3\\xF3\\xA0\\x81\\xB4|\\xB7\\xF3\\xA0\\x81\\xAC\\xF3\\xA0\\x81\\xB3)\\xF3\\xA0\\x81\\xBF)?)|\\x90(?:[\\x80-\\xBE](?:\\xEF\\xB8\\x8F)?|\\xBF\\xEF\\xB8\\x8F)|\\x91(?:[\\x80\\x84\\x85\\x91-\\xA5\\xAA-\\xAD\\xB9-\\xBB\\xBD-\\xBF](?:\\xEF\\xB8\\x8F)?|[\\x82\\x83\\x86-\\x90\\xA6\\xA7\\xB0\\xB2\\xB4-\\xB6\\xB8\\xBC](?:\\xEF\\xB8\\x8F|\\xF0\\x9F\\x8F[\\xBB-\\xBF])?|[\\xAE\\xB1\\xB3\\xB7](?:\\xE2\\x80\\x8D\\xE2\\x99[\\x80\\x82]\\xEF\\xB8\\x8F|\\xEF\\xB8\\x8F|\\xF0\\x9F\\x8F[\\xBB-\\xBF](?:\\xE2\\x80\\x8D\\xE2\\x99[\\x80\\x82]\\xEF\\xB8\\x8F)?)?|\\x81\\xEF\\xB8\\x8F(?:\\xE2\\x80\\x8D\\xF0\\x9F\\x97\\xA8\\xEF\\xB8\\x8F)?|\\xA8(?:\\xE2\\x80\\x8D(?:\\xE2(?:\\x9A[\\x95\\x96]\\xEF\\xB8\\x8F|\\x9C\\x88\\xEF\\xB8\\x8F|\\x9D\\xA4\\xEF\\xB8\\x8F\\xE2\\x80\\x8D\\xF0\\x9F(?:\\x92\\x8B\\xE2\\x80\\x8D\\xF0\\x9F)?\\x91\\xA8)|\\xF0\\x9F(?:\\x8C\\xBE|\\x8D\\xB3|\\x8E[\\x93\\xA4\\xA8]|\\x8F[\\xAB\\xAD]|\\x91(?:[\\xA8\\xA9]\\xE2\\x80\\x8D\\xF0\\x9F\\x91(?:\\xA6(?:\\xE2\\x80\\x8D\\xF0\\x9F\\x91\\xA6)?|\\xA7(?:\\xE2\\x80\\x8D\\xF0\\x9F\\x91[\\xA6\\xA7])?)|\\xA6(?:\\xE2\\x80\\x8D\\xF0\\x9F\\x91\\xA6)?|\\xA7(?:\\xE2\\x80\\x8D\\xF0\\x9F\\x91[\\xA6\\xA7])?)|\\x92[\\xBB\\xBC]|\\x94[\\xA7\\xAC]|\\x9A[\\x80\\x92]))|\\xEF\\xB8\\x8F|\\xF0\\x9F\\x8F[\\xBB-\\xBF](?:\\xE2\\x80\\x8D(?:\\xE2(?:\\x9A[\\x95\\x96]|\\x9C\\x88)\\xEF\\xB8\\x8F|\\xF0\\x9F(?:\\x8C\\xBE|\\x8D\\xB3|\\x8E[\\x93\\xA4\\xA8]|\\x8F[\\xAB\\xAD]|\\x92[\\xBB\\xBC]|\\x94[\\xA7\\xAC]|\\x9A[\\x80\\x92])))?)?|\\xA9(?:\\xE2\\x80\\x8D(?:\\xE2(?:\\x9A[\\x95\\x96]\\xEF\\xB8\\x8F|\\x9C\\x88\\xEF\\xB8\\x8F|\\x9D\\xA4\\xEF\\xB8\\x8F\\xE2\\x80\\x8D\\xF0\\x9F(?:\\x92\\x8B\\xE2\\x80\\x8D\\xF0\\x9F)?\\x91[\\xA8\\xA9])|\\xF0\\x9F(?:\\x8C\\xBE|\\x8D\\xB3|\\x8E[\\x93\\xA4\\xA8]|\\x8F[\\xAB\\xAD]|\\x91(?:\\xA6(?:\\xE2\\x80\\x8D\\xF0\\x9F\\x91\\xA6)?|\\xA7(?:\\xE2\\x80\\x8D\\xF0\\x9F\\x91[\\xA6\\xA7])?|\\xA9\\xE2\\x80\\x8D\\xF0\\x9F\\x91(?:\\xA6(?:\\xE2\\x80\\x8D\\xF0\\x9F\\x91\\xA6)?|\\xA7(?:\\xE2\\x80\\x8D\\xF0\\x9F\\x91[\\xA6\\xA7])?))|\\x92[\\xBB\\xBC]|\\x94[\\xA7\\xAC]|\\x9A[\\x80\\x92]))|\\xEF\\xB8\\x8F|\\xF0\\x9F\\x8F[\\xBB-\\xBF](?:\\xE2\\x80\\x8D(?:\\xE2(?:\\x9A[\\x95\\x96]|\\x9C\\x88)\\xEF\\xB8\\x8F|\\xF0\\x9F(?:\\x8C\\xBE|\\x8D\\xB3|\\x8E[\\x93\\xA4\\xA8]|\\x8F[\\xAB\\xAD]|\\x92[\\xBB\\xBC]|\\x94[\\xA7\\xAC]|\\x9A[\\x80\\x92])))?)?|\\xAF(?:(?:\\xE2\\x80\\x8D\\xE2\\x99[\\x80\\x82])?\\xEF\\xB8\\x8F)?)|\\x92(?:[\\x80\\x84\\x88-\\xA9\\xAB-\\xBF](?:\\xEF\\xB8\\x8F)?|[\\x81\\x82\\x86\\x87](?:\\xE2\\x80\\x8D\\xE2\\x99[\\x80\\x82]\\xEF\\xB8\\x8F|\\xEF\\xB8\\x8F|\\xF0\\x9F\\x8F[\\xBB-\\xBF](?:\\xE2\\x80\\x8D\\xE2\\x99[\\x80\\x82]\\xEF\\xB8\\x8F)?)?|[\\x83\\x85\\xAA](?:\\xEF\\xB8\\x8F|\\xF0\\x9F\\x8F[\\xBB-\\xBF])?)|\\x93(?:[\\x80-\\xBC\\xBF](?:\\xEF\\xB8\\x8F)?|\\xBD\\xEF\\xB8\\x8F)|\\x94[\\x80-\\xBD](?:\\xEF\\xB8\\x8F)?|\\x95(?:[\\x89\\x8A\\xAF\\xB0\\xB3\\xB6-\\xB9]\\xEF\\xB8\\x8F|[\\x8B-\\x8E\\x90-\\xA7](?:\\xEF\\xB8\\x8F)?|\\xB4(?:\\xEF\\xB8\\x8F|\\xF0\\x9F\\x8F[\\xBB-\\xBF])|\\xB5(?:\\xEF\\xB8\\x8F|\\xF0\\x9F\\x8F[\\xBB-\\xBF])(?:\\xE2\\x80\\x8D\\xE2\\x99[\\x80\\x82]\\xEF\\xB8\\x8F)?|\\xBA(?:\\xEF\\xB8\\x8F|\\xF0\\x9F\\x8F[\\xBB-\\xBF])?)|\\x96(?:[\\x87\\x8A-\\x8D\\xA5\\xA8\\xB1\\xB2\\xBC]\\xEF\\xB8\\x8F|[\\x95\\x96](?:\\xEF\\xB8\\x8F|\\xF0\\x9F\\x8F[\\xBB-\\xBF])?|\\x90(?:\\xEF\\xB8\\x8F|\\xF0\\x9F\\x8F[\\xBB-\\xBF])|\\xA4(?:\\xEF\\xB8\\x8F)?)|\\x97(?:[\\x82-\\x84\\x91-\\x93\\x9C-\\x9E\\xA1\\xA3\\xA8\\xAF\\xB3\\xBA]\\xEF\\xB8\\x8F|[\\xBB-\\xBF](?:\\xEF\\xB8\\x8F)?)|\\x98[\\x80-\\xBF](?:\\xEF\\xB8\\x8F)?|\\x99(?:[\\x80-\\x84\\x88-\\x8A](?:\\xEF\\xB8\\x8F)?|[\\x85-\\x87\\x8B\\x8D\\x8E](?:\\xE2\\x80\\x8D\\xE2\\x99[\\x80\\x82]\\xEF\\xB8\\x8F|\\xEF\\xB8\\x8F|\\xF0\\x9F\\x8F[\\xBB-\\xBF](?:\\xE2\\x80\\x8D\\xE2\\x99[\\x80\\x82]\\xEF\\xB8\\x8F)?)?|[\\x8C\\x8F](?:\\xEF\\xB8\\x8F|\\xF0\\x9F\\x8F[\\xBB-\\xBF])?)|\\x9A(?:[\\x80-\\xA2\\xA4-\\xB3\\xB7-\\xBF](?:\\xEF\\xB8\\x8F)?|[\\xA3\\xB4-\\xB6](?:\\xE2\\x80\\x8D\\xE2\\x99[\\x80\\x82]\\xEF\\xB8\\x8F|\\xEF\\xB8\\x8F|\\xF0\\x9F\\x8F[\\xBB-\\xBF](?:\\xE2\\x80\\x8D\\xE2\\x99[\\x80\\x82]\\xEF\\xB8\\x8F)?)?)|\\x9B(?:[\\x80\\x8C](?:\\xEF\\xB8\\x8F|\\xF0\\x9F\\x8F[\\xBB-\\xBF])?|[\\x81-\\x85\\x90-\\x92\\xAB\\xAC\\xB4-\\xB8](?:\\xEF\\xB8\\x8F)?|[\\x8B\\x8D-\\x8F\\xA0-\\xA5\\xA9\\xB0\\xB3]\\xEF\\xB8\\x8F)|\\xA4(?:[\\x90-\\x97\\x9D\\xA0-\\xA5\\xA7-\\xAF\\xBA](?:\\xEF\\xB8\\x8F)?|[\\x98-\\x9C\\x9E\\x9F\\xB0-\\xB6](?:\\xEF\\xB8\\x8F|\\xF0\\x9F\\x8F[\\xBB-\\xBF])?|[\\xA6\\xB7-\\xB9\\xBD\\xBE](?:\\xE2\\x80\\x8D\\xE2\\x99[\\x80\\x82]\\xEF\\xB8\\x8F|\\xEF\\xB8\\x8F|\\xF0\\x9F\\x8F[\\xBB-\\xBF](?:\\xE2\\x80\\x8D\\xE2\\x99[\\x80\\x82]\\xEF\\xB8\\x8F)?)?|\\xBC(?:(?:\\xE2\\x80\\x8D\\xE2\\x99[\\x80\\x82])?\\xEF\\xB8\\x8F)?)|\\xA5[\\x80-\\x85\\x87-\\x8C\\x90-\\xAB](?:\\xEF\\xB8\\x8F)?|\\xA6[\\x80-\\x97](?:\\xEF\\xB8\\x8F)?|\\xA7(?:[\\x80\\x90\\xA0-\\xA6](?:\\xEF\\xB8\\x8F)?|[\\x91-\\x95](?:\\xEF\\xB8\\x8F|\\xF0\\x9F\\x8F[\\xBB-\\xBF])?|[\\x96-\\x9D](?:\\xE2\\x80\\x8D\\xE2\\x99[\\x80\\x82]\\xEF\\xB8\\x8F|\\xEF\\xB8\\x8F|\\xF0\\x9F\\x8F[\\xBB-\\xBF](?:\\xE2\\x80\\x8D\\xE2\\x99[\\x80\\x82]\\xEF\\xB8\\x8F)?)?|[\\x9E\\x9F](?:(?:\\xE2\\x80\\x8D\\xE2\\x99[\\x80\\x82])?\\xEF\\xB8\\x8F)?)))(?!\\xEF\\xB8\\x8E))S';
23
24
	/**
25
	* {@inheritdoc}
26
	*/
27 26
	public function parse($text, array $matches)
28
	{
29 26
		$this->parseShortnames($text);
30 26
		$this->parseCustomAliases($text);
31 26
		$this->parseUnicode($text);
32 26
	}
33
34
	/**
35
	* Add an emoji tag for given sequence
36
	*
37
	* @param  integer $tagPos Position of the tag in the original text
38
	* @param  integer $tagLen Length of text consumed by the tag
39
	* @param  string  $hex    Full-qualified sequence of codepoints in hex
40
	* @return void
41
	*/
42 21
	protected function addTag($tagPos, $tagLen, $hex)
43
	{
44 21
		$tag = $this->parser->addSelfClosingTag($this->config['tagName'], $tagPos, $tagLen, 10);
45
46
		// Short sequence, only the relevant codepoints are kept
47 21
		$seq = str_replace(['-200d', '-fe0f'], '', $hex);
48 21
		$tag->setAttribute($this->config['attrName'], $seq);
49 21
	}
50
51
	/**
52
	* Get the sequence of Unicode codepoints that corresponds to given emoji
53
	*
54
	* @param  string $str UTF-8 emoji
55
	* @return string      Codepoint sequence, e.g. "0023-20e3"
56
	*/
57 20
	protected function getHexSequence($str)
58
	{
59 20
		$seq = [];
60 20
		$i   = 0;
61
		do
62
		{
63 20
			$cp = ord($str[$i]);
64 20
			if ($cp >= 0xF0)
65
			{
66 12
				$cp = ($cp << 18) + (ord($str[++$i]) << 12) + (ord($str[++$i]) << 6) + ord($str[++$i]) - 0x3C82080;
67
			}
68 11
			elseif ($cp >= 0xE0)
69
			{
70 11
				$cp = ($cp << 12) + (ord($str[++$i]) << 6) + ord($str[++$i]) - 0xE2080;
71
			}
72 4
			elseif ($cp >= 0xC0)
73
			{
74 3
				$cp = ($cp << 6) + ord($str[++$i]) - 0x3080;
75
			}
76 20
			$seq[] = sprintf('%04x', $cp);
77
		}
78 20
		while (++$i < strlen($str));
79
80 20
		return implode('-', $seq);
81
	}
82
83
	/**
84
	* Parse custom aliases in given text
85
	*
86
	* @param  string $text Original text
87
	* @return void
88
	*/
89 26
	protected function parseCustomAliases($text)
90
	{
91 26
		if (empty($this->config['customRegexp']))
92
		{
93 24
			return;
94
		}
95
96 2
		$matchPos = 0;
97 2
		if (isset($this->config['customQuickMatch']))
98
		{
99 2
			$matchPos = strpos($text, $this->config['customQuickMatch']);
100 2
			if ($matchPos === false)
101
			{
102 1
				return;
103
			}
104
		}
105
106 1
		preg_match_all($this->config['customRegexp'], $text, $matches, PREG_OFFSET_CAPTURE, $matchPos);
107 1
		foreach ($matches[0] as list($alias, $tagPos))
108
		{
109 1
			if (isset($this->parser->registeredVars['Emoji.aliases'][$alias]))
110
			{
111 1
				$hex = $this->getHexSequence($this->parser->registeredVars['Emoji.aliases'][$alias]);
112 1
				$this->addTag($tagPos, strlen($alias), $hex);
113
			}
114
		}
115 1
	}
116
117
	/**
118
	* Parse shortnames in given text
119
	*
120
	* @param  string $text Original text
121
	* @return void
122
	*/
123 26
	protected function parseShortnames($text)
124
	{
125 26
		$matchPos = strpos($text, ':');
126 26
		if ($matchPos === false)
127
		{
128 16
			return;
129
		}
130 10
		preg_match_all($this->shortnameRegexp, $text, $matches, PREG_OFFSET_CAPTURE, $matchPos);
131 10
		foreach ($matches[0] as list($alias, $tagPos))
132
		{
133 9
			$alias .= ':';
134 9
			$tagLen = strlen($alias);
135 9
			if (isset($this->parser->registeredVars['Emoji.aliases'][$alias]))
136
			{
137 6
				$hex = $this->getHexSequence($this->parser->registeredVars['Emoji.aliases'][$alias]);
138 6
				$this->addTag($tagPos, $tagLen, $hex);
139
			}
140 4
			elseif (preg_match('/^:[0-3][0-9a-f]{3,4}(?:-[0-9a-f]{4,5})*:$/', $alias))
141
			{
142 9
				$this->addTag($tagPos, $tagLen, substr($alias, 1, -1));
143
			}
144
		}
145 10
	}
146
147
	/**
148
	* Parse Unicode emoji in given text
149
	*
150
	* @param  string $text Original text
151
	* @return void
152
	*/
153 26
	protected function parseUnicode($text)
154
	{
155 26
		if (strpos($text, "\xE2") === false && strpos($text, "\xEF") === false && strpos($text, "\xF0") === false)
156
		{
157 9
			return;
158
		}
159 17
		preg_match_all($this->unicodeRegexp, $text, $matches, PREG_OFFSET_CAPTURE);
160 17
		foreach ($matches[0] as list($emoji, $tagPos))
161
		{
162 14
			$this->addTag($tagPos, strlen($emoji), $this->getHexSequence($emoji));
163
		}
164
	}
165
}