+/**
+ * WordPress implementation of PHP sprintf() with filters.
+ *
+ * @since 2.5.0
+ * @link http://www.php.net/sprintf
+ *
+ * @param string $pattern The string which formatted args are inserted.
+ * @param mixed $args,... Arguments to be formatted into the $pattern string.
+ * @return string The formatted string.
+ */
+function wp_sprintf( $pattern ) {
+ $args = func_get_args( );
+ $len = strlen($pattern);
+ $start = 0;
+ $result = '';
+ $arg_index = 0;
+ while ( $len > $start ) {
+ // Last character: append and break
+ if ( strlen($pattern) - 1 == $start ) {
+ $result .= substr($pattern, -1);
+ break;
+ }
+
+ // Literal %: append and continue
+ if ( substr($pattern, $start, 2) == '%%' ) {
+ $start += 2;
+ $result .= '%';
+ continue;
+ }
+
+ // Get fragment before next %
+ $end = strpos($pattern, '%', $start + 1);
+ if ( false === $end )
+ $end = $len;
+ $fragment = substr($pattern, $start, $end - $start);
+
+ // Fragment has a specifier
+ if ( $pattern{$start} == '%' ) {
+ // Find numbered arguments or take the next one in order
+ if ( preg_match('/^%(\d+)\$/', $fragment, $matches) ) {
+ $arg = isset($args[$matches[1]]) ? $args[$matches[1]] : '';
+ $fragment = str_replace("%{$matches[1]}$", '%', $fragment);
+ } else {
+ ++$arg_index;
+ $arg = isset($args[$arg_index]) ? $args[$arg_index] : '';
+ }
+
+ // Apply filters OR sprintf
+ $_fragment = apply_filters( 'wp_sprintf', $fragment, $arg );
+ if ( $_fragment != $fragment )
+ $fragment = $_fragment;
+ else
+ $fragment = sprintf($fragment, strval($arg) );
+ }
+
+ // Append to result and move to next fragment
+ $result .= $fragment;
+ $start = $end;
+ }
+ return $result;
+}
+
+/**
+ * Localize list items before the rest of the content.
+ *
+ * The '%l' must be at the first characters can then contain the rest of the
+ * content. The list items will have ', ', ', and', and ' and ' added depending
+ * on the amount of list items in the $args parameter.
+ *
+ * @since 2.5.0
+ *
+ * @param string $pattern Content containing '%l' at the beginning.
+ * @param array $args List items to prepend to the content and replace '%l'.
+ * @return string Localized list items and rest of the content.
+ */
+function wp_sprintf_l($pattern, $args) {
+ // Not a match
+ if ( substr($pattern, 0, 2) != '%l' )
+ return $pattern;
+
+ // Nothing to work with
+ if ( empty($args) )
+ return '';
+
+ // Translate and filter the delimiter set (avoid ampersands and entities here)
+ $l = apply_filters('wp_sprintf_l', array(
+ /* translators: used between list items, there is a space after the coma */
+ 'between' => __(', '),
+ /* translators: used between list items, there is a space after the and */
+ 'between_last_two' => __(', and '),
+ /* translators: used between only two list items, there is a space after the and */
+ 'between_only_two' => __(' and '),
+ ));
+
+ $args = (array) $args;
+ $result = array_shift($args);
+ if ( count($args) == 1 )
+ $result .= $l['between_only_two'] . array_shift($args);
+ // Loop when more than two args
+ $i = count($args);
+ while ( $i ) {
+ $arg = array_shift($args);
+ $i--;
+ if ( 0 == $i )
+ $result .= $l['between_last_two'] . $arg;
+ else
+ $result .= $l['between'] . $arg;
+ }
+ return $result . substr($pattern, 2);
+}
+
+/**
+ * Safely extracts not more than the first $count characters from html string.
+ *
+ * UTF-8, tags and entities safe prefix extraction. Entities inside will *NOT*
+ * be counted as one character. For example & will be counted as 4, < as
+ * 3, etc.
+ *
+ * @since 2.5.0
+ *
+ * @param integer $str String to get the excerpt from.
+ * @param integer $count Maximum number of characters to take.
+ * @return string The excerpt.
+ */
+function wp_html_excerpt( $str, $count ) {
+ $str = strip_tags( $str );
+ $str = mb_substr( $str, 0, $count );
+ // remove part of an entity at the end
+ $str = preg_replace( '/&[^;\s]{0,6}$/', '', $str );
+ return $str;
+}
+
+/**
+ * Add a Base url to relative links in passed content.
+ *
+ * By default it supports the 'src' and 'href' attributes. However this can be
+ * changed via the 3rd param.
+ *
+ * @since 2.7.0
+ *
+ * @param string $content String to search for links in.
+ * @param string $base The base URL to prefix to links.
+ * @param array $attrs The attributes which should be processed.
+ * @return string The processed content.
+ */
+function links_add_base_url( $content, $base, $attrs = array('src', 'href') ) {
+ $attrs = implode('|', (array)$attrs);
+ return preg_replace_callback("!($attrs)=(['\"])(.+?)\\2!i",
+ create_function('$m', 'return _links_add_base($m, "' . $base . '");'),
+ $content);
+}
+
+/**
+ * Callback to add a base url to relative links in passed content.
+ *
+ * @since 2.7.0
+ * @access private
+ *
+ * @param string $m The matched link.
+ * @param string $base The base URL to prefix to links.
+ * @return string The processed link.
+ */
+function _links_add_base($m, $base) {
+ //1 = attribute name 2 = quotation mark 3 = URL
+ return $m[1] . '=' . $m[2] .
+ (strpos($m[3], 'http://') === false ?
+ path_join($base, $m[3]) :
+ $m[3])
+ . $m[2];
+}
+
+/**
+ * Adds a Target attribute to all links in passed content.
+ *
+ * This function by default only applies to <a> tags, however this can be
+ * modified by the 3rd param.
+ *
+ * <b>NOTE:</b> Any current target attributed will be striped and replaced.
+ *
+ * @since 2.7.0
+ *
+ * @param string $content String to search for links in.
+ * @param string $target The Target to add to the links.
+ * @param array $tags An array of tags to apply to.
+ * @return string The processed content.
+ */
+function links_add_target( $content, $target = '_blank', $tags = array('a') ) {
+ $tags = implode('|', (array)$tags);
+ return preg_replace_callback("!<($tags)(.+?)>!i",
+ create_function('$m', 'return _links_add_target($m, "' . $target . '");'),
+ $content);
+}
+/**
+ * Callback to add a target attribute to all links in passed content.
+ *
+ * @since 2.7.0
+ * @access private
+ *
+ * @param string $m The matched link.
+ * @param string $target The Target to add to the links.
+ * @return string The processed link.
+ */
+function _links_add_target( $m, $target ) {
+ $tag = $m[1];
+ $link = preg_replace('|(target=[\'"](.*?)[\'"])|i', '', $m[2]);
+ return '<' . $tag . $link . ' target="' . $target . '">';
+}
+
+// normalize EOL characters and strip duplicate whitespace
+function normalize_whitespace( $str ) {
+ $str = trim($str);
+ $str = str_replace("\r", "\n", $str);
+ $str = preg_replace( array( '/\n+/', '/[ \t]+/' ), array( "\n", ' ' ), $str );
+ return $str;
+}
+