Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100755 335 lines (229 sloc) 6.788 kb
ce55782 @iamcal git-svn-id: https://svn.iamcal.com/public/php/lib_autolink/trunk@1803 ac...
authored
1 <?php
2 #
3 # A PHP auto-linking library
4 #
38233a9 @iamcal updated link to github (not sure the previous link ever actually existed...
authored
5 # https://github.com/iamcal/lib_autolink
ce55782 @iamcal git-svn-id: https://svn.iamcal.com/public/php/lib_autolink/trunk@1803 ac...
authored
6 #
7 # By Cal Henderson <cal@iamcal.com>
453938b @iamcal Updated for MIT license
authored
8 # This code is licensed under the MIT license
ce55782 @iamcal git-svn-id: https://svn.iamcal.com/public/php/lib_autolink/trunk@1803 ac...
authored
9 #
10
11 ####################################################################
12
13b7dcd @iamcal it's time we added some global options and stopped passing do much as ar...
authored
13 #
14 # These are global options. You can set them before calling the autolinking
15 # functions to change the output.
16 #
17
18 $GLOBALS['autolink_options'] = array(
19
20 # Should http:// be visibly stripped from the front
21 # of URLs?
22 'strip_protocols' => true,
23
24 );
25
26 ####################################################################
27
bd0a691 @nickmoline make it optional
nickmoline authored
28 function autolink($text, $limit=30, $tagfill='', $auto_title = true){
ce55782 @iamcal git-svn-id: https://svn.iamcal.com/public/php/lib_autolink/trunk@1803 ac...
authored
29
2c60e03 @iamcal switch to using regular expressions for the prefix matching, so that we ...
authored
30 $text = autolink_do($text, '![a-z][a-z-]+://!i', $limit, $tagfill, $auto_title);
31 $text = autolink_do($text, '!(mailto|skype):!i', $limit, $tagfill, $auto_title);
32 $text = autolink_do($text, '!www\\.!i', $limit, $tagfill, $auto_title, 'http://');
ce55782 @iamcal git-svn-id: https://svn.iamcal.com/public/php/lib_autolink/trunk@1803 ac...
authored
33 return $text;
34 }
35
36 ####################################################################
37
2c60e03 @iamcal switch to using regular expressions for the prefix matching, so that we ...
authored
38 function autolink_do($text, $sub, $limit, $tagfill, $auto_title, $force_prefix=null){
ce55782 @iamcal git-svn-id: https://svn.iamcal.com/public/php/lib_autolink/trunk@1803 ac...
authored
39
40 $text_l = StrToLower($text);
41 $cursor = 0;
42 $loop = 1;
43 $buffer = '';
44
45 while (($cursor < strlen($text)) && $loop){
46
47 $ok = 1;
2c60e03 @iamcal switch to using regular expressions for the prefix matching, so that we ...
authored
48 $matched = preg_match($sub, $text_l, $m, PREG_OFFSET_CAPTURE, $cursor);
ce55782 @iamcal git-svn-id: https://svn.iamcal.com/public/php/lib_autolink/trunk@1803 ac...
authored
49
2c60e03 @iamcal switch to using regular expressions for the prefix matching, so that we ...
authored
50 if (!$matched){
ce55782 @iamcal git-svn-id: https://svn.iamcal.com/public/php/lib_autolink/trunk@1803 ac...
authored
51
52 $loop = 0;
53 $ok = 0;
54
55 }else{
56
2c60e03 @iamcal switch to using regular expressions for the prefix matching, so that we ...
authored
57 $pos = $m[0][1];
58 $sub_len = strlen($m[0][0]);
59
ce55782 @iamcal git-svn-id: https://svn.iamcal.com/public/php/lib_autolink/trunk@1803 ac...
authored
60 $pre_hit = substr($text, $cursor, $pos-$cursor);
61 $hit = substr($text, $pos, $sub_len);
62 $pre = substr($text, 0, $pos);
63 $post = substr($text, $pos + $sub_len);
64
65 $fail_text = $pre_hit.$hit;
66 $fail_len = strlen($fail_text);
67
68 #
69 # substring found - first check to see if we're inside a link tag already...
70 #
71
72 $bits = preg_split("!</a>!i", $pre);
73 $last_bit = array_pop($bits);
74 if (preg_match("!<a\s!i", $last_bit)){
75
76 #echo "fail 1 at $cursor<br />\n";
77
78 $ok = 0;
79 $cursor += $fail_len;
80 $buffer .= $fail_text;
81 }
82 }
83
84 #
85 # looks like a nice spot to autolink from - check the pre
86 # to see if there was whitespace before this match
87 #
88
89 if ($ok){
90
91 if ($pre){
5f42dbf @iamcal allow a url to appear immediately after a closing angle bracket - the la...
authored
92 if (!preg_match('![\s\(\[\{>]$!s', $pre)){
ce55782 @iamcal git-svn-id: https://svn.iamcal.com/public/php/lib_autolink/trunk@1803 ac...
authored
93
94 #echo "fail 2 at $cursor ($pre)<br />\n";
95
96 $ok = 0;
97 $cursor += $fail_len;
98 $buffer .= $fail_text;
99 }
100 }
101 }
102
103 #
104 # we want to autolink here - find the extent of the url
105 #
106
107 if ($ok){
108 if (preg_match('/^([a-z0-9\-\.\/\-_%~!?=,:;&+*#@\(\)\$]+)/i', $post, $matches)){
109
110 $url = $hit.$matches[1];
111
ad1d784 @iamcal decode URL before stripping trailing punctuation, then re-encode on outp...
authored
112 $cursor += strlen($url) + strlen($pre_hit);
113 $buffer .= $pre_hit;
114
115 $url = html_entity_decode($url);
116
117
ce55782 @iamcal git-svn-id: https://svn.iamcal.com/public/php/lib_autolink/trunk@1803 ac...
authored
118 #
119 # remove trailing punctuation from url
120 #
121
597c764 @iamcal strip any amount of trailing punctuation from URLs
authored
122 while (preg_match('|[.,!;:?]$|', $url)){
ce55782 @iamcal git-svn-id: https://svn.iamcal.com/public/php/lib_autolink/trunk@1803 ac...
authored
123 $url = substr($url, 0, strlen($url)-1);
ad1d784 @iamcal decode URL before stripping trailing punctuation, then re-encode on outp...
authored
124 $cursor--;
ce55782 @iamcal git-svn-id: https://svn.iamcal.com/public/php/lib_autolink/trunk@1803 ac...
authored
125 }
126 foreach (array('()', '[]', '{}') as $pair){
127 $o = substr($pair, 0, 1);
128 $c = substr($pair, 1, 1);
129 if (preg_match("!^(\\$c|^)[^\\$o]+\\$c$!", $url)){
130 $url = substr($url, 0, strlen($url)-1);
ad1d784 @iamcal decode URL before stripping trailing punctuation, then re-encode on outp...
authored
131 $cursor--;
ce55782 @iamcal git-svn-id: https://svn.iamcal.com/public/php/lib_autolink/trunk@1803 ac...
authored
132 }
133 }
134
2c60e03 @iamcal switch to using regular expressions for the prefix matching, so that we ...
authored
135
ce55782 @iamcal git-svn-id: https://svn.iamcal.com/public/php/lib_autolink/trunk@1803 ac...
authored
136 #
137 # nice-i-fy url here
138 #
139
140 $link_url = $url;
141 $display_url = $url;
142
2c60e03 @iamcal switch to using regular expressions for the prefix matching, so that we ...
authored
143 if ($force_prefix) $link_url = $force_prefix.$link_url;
144
13b7dcd @iamcal it's time we added some global options and stopped passing do much as ar...
authored
145 if ($GLOBALS['autolink_options']['strip_protocols']){
146 if (preg_match('!^(http|https)://!i', $display_url, $m)){
2c60e03 @iamcal switch to using regular expressions for the prefix matching, so that we ...
authored
147
13b7dcd @iamcal it's time we added some global options and stopped passing do much as ar...
authored
148 $display_url = substr($display_url, strlen($m[1])+3);
149 }
ce55782 @iamcal git-svn-id: https://svn.iamcal.com/public/php/lib_autolink/trunk@1803 ac...
authored
150 }
151
152 $display_url = autolink_label($display_url, $limit);
153
2c60e03 @iamcal switch to using regular expressions for the prefix matching, so that we ...
authored
154
ce55782 @iamcal git-svn-id: https://svn.iamcal.com/public/php/lib_autolink/trunk@1803 ac...
authored
155 #
156 # add the url
157 #
a197ccf @nickmoline if the display url is not the same as the link url and the additional at...
nickmoline authored
158
bd0a691 @nickmoline make it optional
nickmoline authored
159 if ($display_url != $link_url && !preg_match('@title=@msi',$tagfill) && $auto_title) {
2c60e03 @iamcal switch to using regular expressions for the prefix matching, so that we ...
authored
160
161 $display_quoted = preg_quote($display_url, '!');
162
163 if (!preg_match("!^(http|https)://{$display_quoted}$!i", $link_url)){
164
165 $tagfill .= ' title="'.$link_url.'"';
af258af @iamcal don't auto-title if the only difference between the display and the link...
authored
166 }
a197ccf @nickmoline if the display url is not the same as the link url and the additional at...
nickmoline authored
167 }
ad1d784 @iamcal decode URL before stripping trailing punctuation, then re-encode on outp...
authored
168
169 $link_url_enc = HtmlSpecialChars($link_url);
170 $display_url_enc = HtmlSpecialChars($display_url);
171
172 $buffer .= "<a href=\"{$link_url_enc}\"$tagfill>{$display_url_enc}</a>";
ce55782 @iamcal git-svn-id: https://svn.iamcal.com/public/php/lib_autolink/trunk@1803 ac...
authored
173
174 }else{
175 #echo "fail 3 at $cursor<br />\n";
176
177 $ok = 0;
178 $cursor += $fail_len;
179 $buffer .= $fail_text;
180 }
181 }
182
183 }
184
185 #
186 # add everything from the cursor to the end onto the buffer.
187 #
188
189 $buffer .= substr($text, $cursor);
190
191 return $buffer;
192 }
193
194 ####################################################################
195
196 function autolink_label($text, $limit){
197
198 if (!$limit){ return $text; }
199
200 if (strlen($text) > $limit){
201 return substr($text, 0, $limit-3).'...';
202 }
203
204 return $text;
205 }
206
207 ####################################################################
208
209 function autolink_email($text, $tagfill=''){
210
211 $atom = '[^()<>@,;:\\\\".\\[\\]\\x00-\\x20\\x7f]+'; # from RFC822
212
213 #die($atom);
214
215 $text_l = StrToLower($text);
216 $cursor = 0;
217 $loop = 1;
218 $buffer = '';
219
220 while(($cursor < strlen($text)) && $loop){
221
222 #
223 # find an '@' symbol
224 #
225
226 $ok = 1;
227 $pos = strpos($text_l, '@', $cursor);
228
229 if ($pos === false){
230
231 $loop = 0;
232 $ok = 0;
233
234 }else{
235
236 $pre = substr($text, $cursor, $pos-$cursor);
237 $hit = substr($text, $pos, 1);
238 $post = substr($text, $pos + 1);
239
240 $fail_text = $pre.$hit;
241 $fail_len = strlen($fail_text);
242
243 #die("$pre::$hit::$post::$fail_text");
244
245 #
246 # substring found - first check to see if we're inside a link tag already...
247 #
248
249 $bits = preg_split("!</a>!i", $pre);
250 $last_bit = array_pop($bits);
251 if (preg_match("!<a\s!i", $last_bit)){
252
253 #echo "fail 1 at $cursor<br />\n";
254
255 $ok = 0;
256 $cursor += $fail_len;
257 $buffer .= $fail_text;
258 }
259 }
260
261 #
262 # check backwards
263 #
264
265 if ($ok){
266 if (preg_match("!($atom(\.$atom)*)\$!", $pre, $matches)){
267
268 # move matched part of address into $hit
269
270 $len = strlen($matches[1]);
271 $plen = strlen($pre);
272
273 $hit = substr($pre, $plen-$len).$hit;
274 $pre = substr($pre, 0, $plen-$len);
275
276 }else{
277
278 #echo "fail 2 at $cursor ($pre)<br />\n";
279
280 $ok = 0;
281 $cursor += $fail_len;
282 $buffer .= $fail_text;
283 }
284 }
285
286 #
287 # check forwards
288 #
289
290 if ($ok){
291 if (preg_match("!^($atom(\.$atom)*)!", $post, $matches)){
292
293 # move matched part of address into $hit
294
295 $len = strlen($matches[1]);
296
297 $hit .= substr($post, 0, $len);
298 $post = substr($post, $len);
299
300 }else{
301 #echo "fail 3 at $cursor ($post)<br />\n";
302
303 $ok = 0;
304 $cursor += $fail_len;
305 $buffer .= $fail_text;
306 }
307 }
308
309 #
310 # commit
311 #
312
313 if ($ok) {
314
315 $cursor += strlen($pre) + strlen($hit);
316 $buffer .= $pre;
317 $buffer .= "<a href=\"mailto:$hit\"$tagfill>$hit</a>";
318
319 }
320
321 }
322
323 #
324 # add everything from the cursor to the end onto the buffer.
325 #
326
327 $buffer .= substr($text, $cursor);
328
329 return $buffer;
330 }
331
332 ####################################################################
333
38233a9 @iamcal updated link to github (not sure the previous link ever actually existed...
authored
334 ?>
Something went wrong with that request. Please try again.