Exemplo n.º 1
0
/**
 * Convert plaintext URI to HTML links.
 * 
 * Code from WordPress 
 * https://github.com/WordPress/WordPress/blob/master/wp-includes/formatting.php
 *
 * @param  string $text
 * @return string
 */
function make_clickable($text)
{
    $urlPattern = '~
		([\\s(<.,;:!?])
		(
			[\\w]{1,20}+://
			(?=\\S{1,2000}\\s)
			[\\w\\x80-\\xff#%\\~/@\\[\\]*(+=&$-]*+
			(?:
				[\'.,;:!?)]
				[\\w\\x80-\\xff#%\\~/@\\[\\]*(+=&$-]++
			)*
		)
		(\\)?)
	~xS';
    $ftpPattern = '#([\\s>])((www|ftp)\\.[\\w\\x80-\\xff\\#$%&~/.\\-;:=,?@\\[\\]+]+)#is';
    $emailPattern = '#([\\s>])([.0-9a-z_+-]+)@(([0-9a-z-]+\\.)+[0-9a-z]{2,})#i';
    $r = '';
    $textarr = preg_split('/(<[^<>]+>)/', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
    $nested = 0;
    foreach ($textarr as $piece) {
        if (preg_match('|^<code[\\s>]|i', $piece) || preg_match('|^<pre[\\s>]|i', $piece)) {
            $nested++;
        } elseif ((strtolower($piece) === '</code>' || strtolower($piece) === '</pre>') && $nested) {
            $nested--;
        }
        if ($nested || empty($piece) || $piece[0] === '<' && !preg_match('|^<\\s*[\\w]{1,20}+://|', $piece)) {
            $r .= $piece;
            continue;
        }
        if (strlen($piece) > 10000) {
            foreach (_split_str_by_whitespace($piece, 2100) as $chunk) {
                if (strlen($chunk) > 2101) {
                    $r .= $chunk;
                } else {
                    $r .= make_clickable($chunk);
                }
            }
        } else {
            $ret = " {$piece} ";
            $ret = preg_replace_callback($urlPattern, '_make_url_clickable_cb', $ret);
            $ret = preg_replace_callback($ftpPattern, '_make_web_ftp_clickable_cb', $ret);
            $ret = preg_replace_callback($emailPattern, '_make_email_clickable_cb', $ret);
            $ret = substr($ret, 1, -1);
            $r .= $ret;
        }
    }
    return preg_replace('#(<a([ \\r\\n\\t]+[^>]+?>|>))<a [^>]+?>([^>]+?)</a></a>#i', "\$1\$3</a>", $r);
}
Exemplo n.º 2
0
/**
 * Convert plaintext URI to HTML links.
 *
 * Converts URI, www and ftp, and email addresses. Finishes by fixing links
 * within links.
 *
 * @since 0.71
 *
 * @param string $text Content to convert URIs.
 * @return string Content with converted URIs.
 */
function make_clickable($text)
{
    $r = '';
    $textarr = preg_split('/(<[^<>]+>)/', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
    // split out HTML tags
    foreach ($textarr as $piece) {
        if (empty($piece) || $piece[0] == '<' && !preg_match('|^<\\s*[\\w]{1,20}+://|', $piece)) {
            $r .= $piece;
            continue;
        }
        // Long strings might contain expensive edge cases ...
        if (10000 < strlen($piece)) {
            // ... break it up
            foreach (_split_str_by_whitespace($piece, 2100) as $chunk) {
                // 2100: Extra room for scheme and leading and trailing paretheses
                if (2101 < strlen($chunk)) {
                    $r .= $chunk;
                    // Too big, no whitespace: bail.
                } else {
                    $r .= make_clickable($chunk);
                }
            }
        } else {
            $ret = " {$piece} ";
            // Pad with whitespace to simplify the regexes
            $url_clickable = '~
				([\\s(<.,;:!?])                                        # 1: Leading whitespace, or punctuation
				(                                                      # 2: URL
					[\\w]{1,20}+://                                # Scheme and hier-part prefix
					(?=\\S{1,2000}\\s)                               # Limit to URLs less than about 2000 characters long
					[\\w\\x80-\\xff#%\\~/@\\[\\]*(+=&$-]*+         # Non-punctuation URL character
					(?:                                            # Unroll the Loop: Only allow puctuation URL character if followed by a non-punctuation URL character
						[\'.,;:!?)]                            # Punctuation URL character
						[\\w\\x80-\\xff#%\\~/@\\[\\]*(+=&$-]++ # Non-punctuation URL character
					)*
				)
				(\\)?)                                                  # 3: Trailing closing parenthesis (for parethesis balancing post processing)
			~xS';
            // The regex is a non-anchored pattern and does not have a single fixed starting character.
            // Tell PCRE to spend more time optimizing since, when used on a page load, it will probably be used several times.
            $ret = preg_replace_callback($url_clickable, '_make_url_clickable_cb', $ret);
            $ret = preg_replace_callback('#([\\s>])((www|ftp)\\.[\\w\\x80-\\xff\\#$%&~/.\\-;:=,?@\\[\\]+]+)#is', '_make_web_ftp_clickable_cb', $ret);
            $ret = preg_replace_callback('#([\\s>])([.0-9a-z_+-]+)@(([0-9a-z-]+\\.)+[0-9a-z]{2,})#i', '_make_email_clickable_cb', $ret);
            $ret = substr($ret, 1, -1);
            // Remove our whitespace padding.
            $r .= $ret;
        }
    }
    // Cleanup of accidental links within links
    $r = preg_replace('#(<a( [^>]+?>|>))<a [^>]+?>([^>]+?)</a></a>#i', "\$1\$3</a>", $r);
    return $r;
}
Exemplo n.º 3
0
/**
 * Convert plaintext URI to HTML links.
 *
 * Converts URI, www and ftp, and email addresses. Finishes by fixing links
 * within links.
 *
 * This custom version of WordPress's make_clickable() skips links inside of
 * pre and code tags.
 *
 * @since 2.4.0 bbPress (r4941)
 *
 * @param string $text Content to convert URIs.
 * @return string Content with converted URIs.
 */
function bbp_make_clickable($text = '')
{
    $r = '';
    $textarr = preg_split('/(<[^<>]+>)/', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
    // split out HTML tags
    $nested_code_pre = 0;
    // Keep track of how many levels link is nested inside <pre> or <code>
    foreach ($textarr as $piece) {
        if (preg_match('|^<code[\\s>]|i', $piece) || preg_match('|^<pre[\\s>]|i', $piece) || preg_match('|^<script[\\s>]|i', $piece) || preg_match('|^<style[\\s>]|i', $piece)) {
            $nested_code_pre++;
        } elseif ($nested_code_pre && ('</code>' === strtolower($piece) || '</pre>' === strtolower($piece) || '</script>' === strtolower($piece) || '</style>' === strtolower($piece))) {
            $nested_code_pre--;
        }
        if ($nested_code_pre || empty($piece) || $piece[0] === '<' && !preg_match('|^<\\s*[\\w]{1,20}+://|', $piece)) {
            $r .= $piece;
            continue;
        }
        // Long strings might contain expensive edge cases ...
        if (10000 < strlen($piece)) {
            // ... break it up
            foreach (_split_str_by_whitespace($piece, 2100) as $chunk) {
                // 2100: Extra room for scheme and leading and trailing paretheses
                if (2101 < strlen($chunk)) {
                    $r .= $chunk;
                    // Too big, no whitespace: bail.
                } else {
                    $r .= bbp_make_clickable($chunk);
                }
            }
        } else {
            $ret = " {$piece} ";
            // Pad with whitespace to simplify the regexes
            $ret = apply_filters('bbp_make_clickable', $ret, $text);
            $ret = substr($ret, 1, -1);
            // Remove our whitespace padding.
            $r .= $ret;
        }
    }
    // Cleanup of accidental links within links
    return preg_replace('#(<a([ \\r\\n\\t]+[^>]+?>|>))<a [^>]+?>([^>]+?)</a></a>#i', "\$1\$3</a>", $r);
}