Index: includes/locale.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/locale.inc,v retrieving revision 1.214 diff -u -p -r1.214 locale.inc --- includes/locale.inc 27 Apr 2009 20:19:35 -0000 1.214 +++ includes/locale.inc 3 May 2009 21:44:13 -0000 @@ -2266,7 +2266,7 @@ function _locale_translate_seek() { foreach ($strings as $lid => $string) { $rows[] = array( $groups[$string['group']], - array('data' => check_plain(truncate_utf8($string['source'], 150, FALSE, TRUE)) . '
' . $string['location'] . ''), + array('data' => check_plain(drupal_truncate_chars($value['source'], 150, array('append' => TRUE))) . '
' . $string['location'] . ''), array('data' => _locale_translate_language_list($string['languages'], $limit_language), 'align' => 'center'), array('data' => l(t('edit'), "admin/international/translate/edit/$lid", array('query' => drupal_get_destination())), 'class' => 'nowrap'), array('data' => l(t('delete'), "admin/international/translate/delete/$lid", array('query' => drupal_get_destination())), 'class' => 'nowrap'), Index: includes/theme.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/theme.inc,v retrieving revision 1.481 diff -u -p -r1.481 theme.inc --- includes/theme.inc 3 May 2009 08:12:12 -0000 1.481 +++ includes/theme.inc 3 May 2009 21:44:13 -0000 @@ -1629,12 +1629,7 @@ function theme_username($object) { if ($object->uid && $object->name) { // Shorten the name when it is too long or it will break many tables. - if (drupal_strlen($object->name) > 20) { - $name = drupal_substr($object->name, 0, 15) . '...'; - } - else { - $name = $object->name; - } + $name = drupal_truncate_chars($object->name, 20, array('append' => TRUE)); if (user_access('access user profiles')) { $output = l($name, 'user/' . $object->uid, array('attributes' => array('title' => t('View user profile.')))); Index: includes/unicode.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/unicode.inc,v retrieving revision 1.37 diff -u -p -r1.37 unicode.inc --- includes/unicode.inc 2 Jan 2009 22:09:53 -0000 1.37 +++ includes/unicode.inc 3 May 2009 21:44:13 -0000 @@ -190,8 +190,8 @@ function drupal_convert_to_utf8($data, $ * * Use this function whenever you want to chop off a string at an unsure * location. On the other hand, if you're sure that you're splitting on a - * character boundary (e.g. after using strpos() or similar), you can safely use - * substr() instead. + * character boundary (e.g. after using drupal_strlen() or similar), you can + * safely use substr() instead. * * @param $string * The string to truncate. @@ -218,24 +218,36 @@ function drupal_truncate_bytes($string, * The string to truncate. * @param $len * An upper limit on the returned string length. - * @param $wordsafe - * Flag to truncate at last space within the upper limit. Defaults to FALSE. - * @param $dots - * Flag to add trailing dots. Defaults to FALSE. + * @param $options + * An associative array of additional options, with the following keys: + * - 'wordsave' + * Flag to truncate at last space within the upper limit. Defaults to + * FALSE. + * - 'append' + * Flag to add trailing string. Defaults to FALSE. + * - 'dots' + * If 'append' is TRUE, append this string to the end of $string. Defaults + * to "...". * @return * The truncated string. */ -function truncate_utf8($string, $len, $wordsafe = FALSE, $dots = FALSE) { +function drupal_truncate_chars($string, $len, $options = array()) { + // Merge in defaults. + $options += array( + 'wordsave' => FALSE, + 'append' => FALSE, + 'dots' => '...', + ); if (drupal_strlen($string) <= $len) { return $string; } - if ($dots) { - $len -= 4; - } - - if ($wordsafe) { + if ($options['wordsafe']) { + if ($options['append']) { + // Make room for dots, if needed. + $len -= drupal_strlen($options['dots']) + 1; + } $string = drupal_substr($string, 0, $len + 1); // leave one more character if ($last_space = strrpos($string, ' ')) { // space exists AND is not on position 0 $string = substr($string, 0, $last_space); @@ -243,15 +255,18 @@ function truncate_utf8($string, $len, $w else { $string = drupal_substr($string, 0, $len); } + if ($options['append']) { + $string .= ' ' . $options['dots']; + } + } + elseif ($options['append']) { + $len -= drupal_strlen($options['dots']); // Make room for dots. + $string = drupal_substr($string, 0, $len) . $options['dots']; } else { $string = drupal_substr($string, 0, $len); } - if ($dots) { - $string .= ' ...'; - } - return $string; } @@ -265,8 +280,8 @@ function truncate_utf8($string, $len, $w * * Notes: * - Only encode strings that contain non-ASCII characters. - * - We progressively cut-off a chunk with truncate_utf8(). This is to ensure - * each chunk starts and ends on a character boundary. + * - We progressively cut-off a chunk with drupal_truncate_bytes(). This is to + * ensure each chunk starts and ends on a byte boundary. * - Using \n as the chunk separator may cause problems on some systems and may * have to be changed to \r\n or \r. */ Index: includes/database/mysql/schema.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/database/mysql/schema.inc,v retrieving revision 1.18 diff -u -p -r1.18 schema.inc --- includes/database/mysql/schema.inc 25 Apr 2009 16:57:19 -0000 1.18 +++ includes/database/mysql/schema.inc 3 May 2009 21:44:13 -0000 @@ -358,7 +358,7 @@ class DatabaseSchema_mysql extends Datab // Truncate comment to maximum comment length. if (isset($length)) { // Add table prefixes before truncating. - $comment = truncate_utf8($this->connection->prefixTables($comment), $length, TRUE, TRUE); + $comment = drupal_truncate_chars($this->connection->prefixTables($comment), $length, array('wordsafe' => TRUE, 'append' => TRUE)); } return $this->connection->quote($comment); Index: modules/aggregator/aggregator.parser.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/aggregator/aggregator.parser.inc,v retrieving revision 1.1 diff -u -p -r1.1 aggregator.parser.inc --- modules/aggregator/aggregator.parser.inc 22 Dec 2008 19:38:31 -0000 1.1 +++ modules/aggregator/aggregator.parser.inc 3 May 2009 21:44:13 -0000 @@ -123,7 +123,7 @@ function aggregator_parse_feed(&$data, $ $item['TITLE'] = $item['TITLE']; } elseif (!empty($item['DESCRIPTION'])) { - $item['TITLE'] = preg_replace('/^(.*)[^\w;&].*?$/', "\\1", truncate_utf8($item['DESCRIPTION'], 40)); + $item['TITLE'] = preg_replace('/^(.*)[^\w;&].*?$/', "\\1", drupal_truncate_chars($item['DESCRIPTION'], 40)); } else { $item['TITLE'] = ''; Index: modules/book/book.module =================================================================== RCS file: /cvs/drupal/drupal/modules/book/book.module,v retrieving revision 1.492 diff -u -p -r1.492 book.module --- modules/book/book.module 3 May 2009 10:11:34 -0000 1.492 +++ modules/book/book.module 3 May 2009 21:44:13 -0000 @@ -934,7 +934,7 @@ function _book_toc_recurse($tree, $inden } if (!in_array($data['link']['mlid'], $exclude)) { - $toc[$data['link']['mlid']] = $indent . ' ' . truncate_utf8($data['link']['title'], 30, TRUE, TRUE); + $toc[$data['link']['mlid']] = $indent . ' ' . drupal_truncate_chars($data['link']['title'], 30, array('wordsafe' => TRUE, 'append' => TRUE)); if ($data['below']) { _book_toc_recurse($data['below'], $indent . '--', $toc, $exclude, $depth_limit); } Index: modules/comment/comment.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/comment/comment.admin.inc,v retrieving revision 1.18 diff -u -p -r1.18 comment.admin.inc --- modules/comment/comment.admin.inc 26 Apr 2009 19:44:38 -0000 1.18 +++ modules/comment/comment.admin.inc 3 May 2009 21:44:13 -0000 @@ -87,7 +87,7 @@ function comment_admin_overview($type = foreach ($result as $comment) { $options[$comment->cid] = array( - 'subject' => l($comment->subject, 'node/' . $comment->nid, array('attributes' => array('title' => truncate_utf8($comment->comment, 128)), 'fragment' => 'comment-' . $comment->cid)), + 'subject' => l($comment->subject, 'node/' . $comment->nid, array('attributes' => array('title' => drupal_truncate_chars($comment->comment, 128)), 'fragment' => 'comment-' . $comment->cid)), 'author' => theme('username', $comment), 'posted_in' => l($comment->node_title, 'node/' . $comment->nid), 'time' => format_date($comment->timestamp, 'small'), Index: modules/comment/comment.module =================================================================== RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v retrieving revision 1.708 diff -u -p -r1.708 comment.module --- modules/comment/comment.module 3 May 2009 10:11:34 -0000 1.708 +++ modules/comment/comment.module 3 May 2009 21:44:13 -0000 @@ -1747,7 +1747,7 @@ function _comment_form_submit(&$comment_ // 2) Strip out all HTML tags // 3) Convert entities back to plain-text. // Note: format is checked by check_markup(). - $comment_values['subject'] = truncate_utf8(trim(decode_entities(strip_tags(check_markup($comment_values['comment'], $comment_values['comment_format'])))), 29, TRUE); + $comment_values['subject'] = drupal_truncate_chars(trim(decode_entities(strip_tags(check_markup($comment_values['comment'], $comment_values['comment_format'])))), 29, array('wordsafe' => TRUE)); // Edge cases where the comment body is populated only by HTML tags will // require a default subject. if ($comment_values['subject'] == '') { Index: modules/dblog/dblog.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/dblog/dblog.admin.inc,v retrieving revision 1.16 diff -u -p -r1.16 dblog.admin.inc --- modules/dblog/dblog.admin.inc 26 Apr 2009 19:44:38 -0000 1.16 +++ modules/dblog/dblog.admin.inc 3 May 2009 21:44:14 -0000 @@ -89,7 +89,7 @@ function dblog_overview() { $icons[$dblog->severity], t($dblog->type), format_date($dblog->timestamp, 'small'), - l(truncate_utf8(_dblog_format_message($dblog), 56, TRUE, TRUE), 'admin/reports/event/' . $dblog->wid, array('html' => TRUE)), + l(drupal_truncate_chars(_dblog_format_message($dblog), 56, array('wordsafe' => TRUE, 'append' => TRUE)), 'admin/reports/event/' . $dblog->wid, array('html' => TRUE)), theme('username', $dblog), $dblog->link, ), @@ -137,7 +137,7 @@ function dblog_top($type) { $rows = array(); foreach ($result as $dblog) { - $rows[] = array($dblog->count, truncate_utf8(_dblog_format_message($dblog), 56, TRUE, TRUE)); + $rows[] = array($dblog->count, drupal_truncate_chars(_dblog_format_message($dblog), 56, array('wordsafe' => TRUE, 'append' => TRUE))); } if (empty($rows)) { Index: modules/filter/filter.module =================================================================== RCS file: /cvs/drupal/drupal/modules/filter/filter.module,v retrieving revision 1.248 diff -u -p -r1.248 filter.module --- modules/filter/filter.module 25 Apr 2009 18:01:10 -0000 1.248 +++ modules/filter/filter.module 3 May 2009 21:44:14 -0000 @@ -846,12 +846,7 @@ function _filter_url_trim($text, $length $_length = $length; } - // Use +3 for '...' string length. - if (strlen($text) > $_length + 3) { - $text = substr($text, 0, $_length) . '...'; - } - - return $text; + return drupal_truncate_chars($text, $_length, array('append' => TRUE)); } /** Index: modules/menu/menu.module =================================================================== RCS file: /cvs/drupal/drupal/modules/menu/menu.module,v retrieving revision 1.184 diff -u -p -r1.184 menu.module --- modules/menu/menu.module 11 Apr 2009 22:19:45 -0000 1.184 +++ modules/menu/menu.module 3 May 2009 21:44:14 -0000 @@ -235,7 +235,7 @@ function _menu_parents_recurse($tree, $m break; } if ($data['link']['mlid'] != $exclude && $data['link']['hidden'] >= 0) { - $title = $indent . ' ' . truncate_utf8($data['link']['title'], 30, TRUE, FALSE); + $title = $indent . ' ' . drupal_truncate_chars($data['link']['title'], 30, array('wordsafe' => TRUE)); if ($data['link']['hidden']) { $title .= ' (' . t('disabled') . ')'; } Index: modules/node/node.module =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.module,v retrieving revision 1.1044 diff -u -p -r1.1044 node.module --- modules/node/node.module 3 May 2009 10:11:34 -0000 1.1044 +++ modules/node/node.module 3 May 2009 21:44:14 -0000 @@ -417,7 +417,7 @@ function node_teaser($body, $format = NU // sentence boundaries. // The teaser may not be longer than maximum length specified. Initial slice. - $teaser = truncate_utf8($body, $size); + $teaser = drupal_truncate_chars($body, $size); // Store the actual length of the UTF8 string -- which might not be the same // as $size. Index: modules/search/search.module =================================================================== RCS file: /cvs/drupal/drupal/modules/search/search.module,v retrieving revision 1.288 diff -u -p -r1.288 search.module --- modules/search/search.module 20 Apr 2009 21:28:15 -0000 1.288 +++ modules/search/search.module 3 May 2009 21:44:14 -0000 @@ -401,7 +401,7 @@ function search_index_split($text) { * Helper function for array_walk in search_index_split. */ function _search_index_truncate(&$text) { - $text = truncate_utf8($text, 50); + $text = drupal_truncate_chars($text, 50); } /** @@ -1271,7 +1271,7 @@ function search_excerpt($keys, $text) { // If we didn't find anything, return the beginning. if (count($ranges) == 0) { - return truncate_utf8($text, 256) . ' ...'; + return drupal_truncate_chars($text, 260, array('wordsafe' => TRUE, 'append' => TRUE)); } // Sort the text ranges by starting position. Index: modules/statistics/statistics.module =================================================================== RCS file: /cvs/drupal/drupal/modules/statistics/statistics.module,v retrieving revision 1.303 diff -u -p -r1.303 statistics.module --- modules/statistics/statistics.module 3 May 2009 10:11:35 -0000 1.303 +++ modules/statistics/statistics.module 3 May 2009 21:44:15 -0000 @@ -351,7 +351,7 @@ function statistics_block_view($delta = */ function _statistics_link($path, $width = 35) { $title = drupal_get_path_alias($path); - $title = truncate_utf8($title, $width, FALSE, TRUE); + $title = drupal_truncate_chars($title, $width, array('append' => TRUE)); return l($title, $path); }