? t.st.patch
? modules/repo.php
? sites/localhost.drupal2
Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.555
diff -u -Ff -r1.555 common.inc
--- includes/common.inc	14 Aug 2006 07:14:48 -0000	1.555
+++ includes/common.inc	17 Aug 2006 21:43:30 -0000
@@ -277,7 +277,7 @@ function drupal_site_offline() {
   drupal_set_header('HTTP/1.0 503 Service unavailable');
   drupal_set_title(t('Site off-line'));
   print theme('maintenance_page', filter_xss_admin(variable_get('site_offline_message',
-    t('%site is currently under maintenance. We should be back shortly. Thank you for your patience.', array('%site' => variable_get('site_name', t('This Drupal site')))))));
+    t('@site is currently under maintenance. We should be back shortly. Thank you for your patience.', array('@site' => variable_get('site_name', t('This Drupal site')))))));
 }
 
 /**
@@ -285,7 +285,7 @@  * Generates a 404 error if the request 
  */
 function drupal_not_found() {
   drupal_set_header('HTTP/1.0 404 Not Found');
-  watchdog('page not found', t('%page not found.', array('%page' => theme('placeholder', $_GET['q']))), WATCHDOG_WARNING);
+  watchdog('page not found', t('%page not found.', array('%page' => $_GET['q'])), WATCHDOG_WARNING);
 
   // Keep old path for reference
   if (!isset($_REQUEST['destination'])) {
@@ -313,7 +313,7 @@  * Generates a 403 error if the request 
  */
 function drupal_access_denied() {
   drupal_set_header('HTTP/1.0 403 Forbidden');
-  watchdog('access denied', t('%page denied access.', array('%page' => theme('placeholder', $_GET['q']))), WATCHDOG_WARNING, l(t('view'), $_GET['q']));
+  watchdog('access denied', t('%page denied access.', array('%page' => $_GET['q'])), WATCHDOG_WARNING, l(t('view'), $_GET['q']));
 
   // Keep old path for reference
   if (!isset($_REQUEST['destination'])) {
@@ -567,8 +567,8 @@  * This makes it easier for translators.
  * is acceptable, if necessary. The suggested syntax for a link embedded
  * within a translation string is:
  * @code
- *   $msg = t('You must log in below or <a href="%url">create a new
- *             account</a> before viewing the next page.', array('%url'
+ *   $msg = t('You must log in below or <a href="@url">create a new
+ *             account</a> before viewing the next page.', array('@url'
  *             => url('user/register')));
  * @endcode
  * We suggest the same syntax for links to other sites. This makes it easy to
@@ -580,6 +580,10 @@  * change link URLs if needed (which hap
  * @param $args
  *   An associative array of replacements to make after translation. Incidences
  *   of any key in this array are replaced with the corresponding value.
+ *   Based on the first character of the key, the value is escaped and/or themed:
+ *    - !variable: inserted as is
+ *    - @variable: escape plain text to HTML (check_plain)
+ *    - %variable: escape text and theme as a placeholder for user-submitted content (check_plain + theme_placeholder)
  * @return
  *   The translated string.
  */
@@ -588,16 +592,38 @@ function t($string, $args = 0) {
   if (function_exists('locale') && $locale != 'en') {
     $string = locale($string);
   }
-
+  static $count = 0;
+  $count++;
   if (!$args) {
     return $string;
   }
   else {
+    // Transform arguments before inserting them
+    array_walk($args, '_t');
     return strtr($string, $args);
   }
 }
 
 /**
+ * Helper function: apply the appropriate transformation to st() and t() placeholders.
+ */
+function _t(&$value, $key) {
+  switch ($key[0]) {
+    // Escaped only
+    case '@':
+      $value = check_plain($value);
+      return;
+    // Escaped and placeholder
+    case '%':
+    default:
+      $value = theme('placeholder', $value);
+      return;
+    // Pass-through
+    case '!':
+  }
+}
+
+/**
  * @defgroup validation Input validation
  * @{
  * Functions to validate user input.
@@ -778,27 +804,27 @@  *   The string for the singular case. P
  *   singular, to ease translation (e.g. use "1 new comment" instead of "1 new").
  * @param $plural
  *   The string for the plural case. Please make sure it is clear this is plural,
- *   to ease translation. Use %count in place of the item count, as in "%count
+ *   to ease translation. Use @count in place of the item count, as in "@count
  *   new comments".
  * @return
  *   A translated string.
  */
 function format_plural($count, $singular, $plural) {
-  if ($count == 1) return t($singular, array("%count" => $count));
+  if ($count == 1) return t($singular, array("@count" => $count));
 
   // get the plural index through the gettext formula
   $index = (function_exists('locale_get_plural')) ? locale_get_plural($count) : -1;
   if ($index < 0) { // backward compatibility
-    return t($plural, array("%count" => $count));
+    return t($plural, array("@count" => $count));
   }
   else {
     switch ($index) {
       case "0":
-        return t($singular, array("%count" => $count));
+        return t($singular, array("@count" => $count));
       case "1":
-        return t($plural, array("%count" => $count));
+        return t($plural, array("@count" => $count));
       default:
-        return t(strtr($plural, array("%count" => '%count['. $index .']')), array('%count['. $index .']' => $count));
+        return t(strtr($plural, array("@count" => '@count['. $index .']')), array('@count['. $index .']' => $count));
     }
   }
 }
@@ -821,7 +847,7 @@   if ($size >= 1024) {
     $size = round($size / 1024, 2);
     $suffix = t('MB');
   }
-  return t('%size %suffix', array('%size' => $size, '%suffix' => $suffix));
+  return t('@size @suffix', array('@size' => $size, '@suffix' => $suffix));
 }
 
 /**
@@ -835,7 +861,7 @@  *   How many different units to display
  *   A translated string representation of the interval.
  */
 function format_interval($timestamp, $granularity = 2) {
-  $units = array('1 year|%count years' => 31536000, '1 week|%count weeks' => 604800, '1 day|%count days' => 86400, '1 hour|%count hours' => 3600, '1 min|%count min' => 60, '1 sec|%count sec' => 1);
+  $units = array('1 year|@count years' => 31536000, '1 week|@count weeks' => 604800, '1 day|@count days' => 86400, '1 hour|@count hours' => 3600, '1 min|@count min' => 60, '1 sec|@count sec' => 1);
   $output = '';
   foreach ($units as $key => $value) {
     $key = explode('|', $key);
Index: includes/database.pgsql.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/database.pgsql.inc,v
retrieving revision 1.32
diff -u -Ff -r1.32 database.pgsql.inc
--- includes/database.pgsql.inc	26 Jul 2006 07:16:08 -0000	1.32
+++ includes/database.pgsql.inc	17 Aug 2006 19:51:16 -0000
@@ -356,7 +356,7 @@  * Verify if the database is set up corr
 function db_check_setup() {
   $encoding = db_result(db_query('SHOW server_encoding'));
   if (!in_array(strtolower($encoding), array('unicode', 'utf8'))) {
-    drupal_set_message(t('Your PostgreSQL database is set up with the wrong character encoding (%encoding). It is possible it will not work as expected. It is advised to recreate it with UTF-8/Unicode encoding. More information can be found in the <a href="%url">PostgreSQL documentation</a>.', array('%encoding' => $encoding, '%url' => 'http://www.postgresql.org/docs/7.4/interactive/multibyte.html')), 'status');
+    drupal_set_message(t('Your PostgreSQL database is set up with the wrong character encoding (%encoding). It is possible it will not work as expected. It is advised to recreate it with UTF-8/Unicode encoding. More information can be found in the <a href="@url">PostgreSQL documentation</a>.', array('%encoding' => $encoding, '@url' => 'http://www.postgresql.org/docs/7.4/interactive/multibyte.html')), 'status');
   }
 }
 
Index: includes/file.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/file.inc,v
retrieving revision 1.81
diff -u -Ff -r1.81 file.inc
--- includes/file.inc	14 Aug 2006 05:33:21 -0000	1.81
+++ includes/file.inc	17 Aug 2006 19:51:16 -0000
@@ -89,12 +89,12 @@ function file_check_directory(&$director
   // Check if directory exists.
   if (!is_dir($directory)) {
     if (($mode & FILE_CREATE_DIRECTORY) && @mkdir($directory)) {
-      drupal_set_message(t('The directory %directory has been created.', array('%directory' => theme('placeholder', $directory))));
+      drupal_set_message(t('The directory %directory has been created.', array('%directory' => $directory)));
       @chmod($directory, 0775); // Necessary for non-webserver users.
     }
     else {
       if ($form_item) {
-        form_set_error($form_item, t('The directory %directory does not exist.', array('%directory' => theme('placeholder', $directory))));
+        form_set_error($form_item, t('The directory %directory does not exist.', array('%directory' => $directory)));
       }
       return FALSE;
     }
@@ -103,11 +103,11 @@         form_set_error($form_item, t('Th
   // Check to see if the directory is writable.
   if (!is_writable($directory)) {
     if (($mode & FILE_MODIFY_PERMISSIONS) && @chmod($directory, 0775)) {
-      drupal_set_message(t('The permissions of directory %directory have been changed to make it writable.', array('%directory' => theme('placeholder', $directory))));
+      drupal_set_message(t('The permissions of directory %directory have been changed to make it writable.', array('%directory' => $directory)));
     }
     else {
-      form_set_error($form_item, t('The directory %directory is not writable', array('%directory' => theme('placeholder', $directory))));
-      watchdog('file system', t('The directory %directory is not writable, because it does not have the correct permissions set.', array('%directory' => theme('placeholder', $directory))), WATCHDOG_ERROR);
+      form_set_error($form_item, t('The directory %directory is not writable', array('%directory' => $directory)));
+      watchdog('file system', t('The directory %directory is not writable, because it does not have the correct permissions set.', array('%directory' => $directory)), WATCHDOG_ERROR);
       return FALSE;
     }
   }
@@ -118,7 +118,7 @@     if (($fp = fopen("$directory/.htacce
       fclose($fp);
     }
     else {
-      $message = t("Security warning: Couldn't write .htaccess file. Please create a .htaccess file in your %directory directory which contains the following lines: <code>%htaccess</code>", array('%directory' => theme('placeholder', $directory), '%htaccess' => '<br />'. str_replace("\n", '<br />', check_plain($htaccess_lines))));
+      $message = t("Security warning: Couldn't write .htaccess file. Please create a .htaccess file in your %directory directory which contains the following lines: <code>!htaccess</code>", array('%directory' => $directory, '!htaccess' => '<br />'. nl2br(check_plain($htaccess_lines))));
       form_set_error($form_item, $message);
       watchdog('security', $message, WATCHDOG_ERROR);
     }
@@ -204,17 +204,17 @@       // @see http://php.net/manual/en/f
 
       case UPLOAD_ERR_INI_SIZE:
       case UPLOAD_ERR_FORM_SIZE:
-        drupal_set_message(t('The file %file could not be saved, because it exceeds the maximum allowed size for uploads.', array('%file' => theme('placeholder', $source))), 'error');
+        drupal_set_message(t('The file %file could not be saved, because it exceeds the maximum allowed size for uploads.', array('%file' => $source)), 'error');
         return 0;
 
       case UPLOAD_ERR_PARTIAL:
       case UPLOAD_ERR_NO_FILE:
-        drupal_set_message(t('The file %file could not be saved, because the upload did not complete.', array('%file' => theme('placeholder', $source))), 'error');
+        drupal_set_message(t('The file %file could not be saved, because the upload did not complete.', array('%file' => $source)), 'error');
         return 0;
 
       // Unknown error
       default:
-        drupal_set_message(t('The file %file could not be saved. An unknown error has occurred.', array('%file' => theme('placeholder', $source))),'error');
+        drupal_set_message(t('The file %file could not be saved. An unknown error has occurred.', array('%file' => $source)),'error');
         return 0;
     }
 
@@ -238,7 +238,7 @@     // Move uploaded files from php's up
     // This overcomes open_basedir restrictions for future file operations.
     if (!move_uploaded_file($_FILES["edit"]["tmp_name"][$source], $file->filepath)) {
       drupal_set_message(t('File upload error. Could not move uploaded file.'));
-      watchdog('file', t('Upload Error. Could not move uploaded file(%file) to destination(%destination).', array('%file' => theme('placeholder', $_FILES["edit"]["tmp_name"][$source]), '%destination' => theme('placeholder', $file->filepath))));
+      watchdog('file', t('Upload Error. Could not move uploaded file (%file) to destination (%destination).', array('%file' => $_FILES["edit"]["tmp_name"][$source], '%destination' => $file->filepath)));
       return FALSE;
     }
 
@@ -318,8 +318,8 @@   $basename = file_check_path($directory
   // Make sure we at least have a valid directory.
   if ($basename === FALSE) {
     $source = is_object($source) ? $source->filepath : $source;
-    drupal_set_message(t('The selected file %file could not be uploaded, because the destination %directory is not properly configured.', array('%file' => theme('placeholder', $source), '%directory' => theme('placeholder', $dest))), 'error');
-    watchdog('file system', t('The selected file %file could not not be uploaded, because the destination %directory could not be found, or because its permissions do not allow the file to be written.', array('%file' => theme('placeholder', $source), '%directory' => theme('placeholder', $dest))), WATCHDOG_ERROR);
+    drupal_set_message(t('The selected file %file could not be uploaded, because the destination %directory is not properly configured.', array('%file' => $source, '%directory' => $dest)), 'error');
+    watchdog('file system', t('The selected file %file could not not be uploaded, because the destination %directory could not be found, or because its permissions do not allow the file to be written.', array('%file' => $source, '%directory' => $dest)), WATCHDOG_ERROR);
     return 0;
   }
 
@@ -334,7 +334,7 @@       $basename = $file->filename;
 
   $source = realpath($source);
   if (!file_exists($source)) {
-    drupal_set_message(t('The selected file %file could not be copied, because no file by that name exists. Please check that you supplied the correct filename.', array('%file' => theme('placeholder', $source))), 'error');
+    drupal_set_message(t('The selected file %file could not be copied, because no file by that name exists. Please check that you supplied the correct filename.', array('%file' => $source)), 'error');
     return 0;
   }
 
@@ -366,13 +366,13 @@           } while (file_exists($dest));
           break;
 
         case FILE_EXISTS_ERROR:
-          drupal_set_message(t('The selected file %file could not be copied, because a file by that name already exists in the destination.', array('%file' => theme('placeholder', $source))), 'error');
+          drupal_set_message(t('The selected file %file could not be copied, because a file by that name already exists in the destination.', array('%file' => $source)), 'error');
           return 0;
       }
     }
 
     if (!@copy($source, $dest)) {
-      drupal_set_message(t('The selected file %file could not be copied.', array('%file' => theme('placeholder', $source))), 'error');
+      drupal_set_message(t('The selected file %file could not be copied.', array('%file' => $source)), 'error');
       return 0;
     }
 
@@ -421,7 +421,7 @@     $path_current = is_object($source) ?
     if ($path_original == $path_current || file_delete($path_original)) {
       return 1;
     }
-    drupal_set_message(t('The removal of the original file %file has failed.', array('%file' => theme('placeholder', $path_original))), 'error');
+    drupal_set_message(t('The removal of the original file %file has failed.', array('%file' => $path_original)), 'error');
   }
   return 0;
 }
Index: includes/form.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/form.inc,v
retrieving revision 1.133
diff -u -Ff -r1.133 form.inc
--- includes/form.inc	10 Aug 2006 15:42:32 -0000	1.133
+++ includes/form.inc	17 Aug 2006 19:51:16 -0000
@@ -283,7 +283,7 @@       // An empty textfield returns '' s
       // and a textfield could return '0' and empty('0') returns TRUE so we
       // need a special check for the '0' string.
       if ($elements['#required'] && empty($elements['#value']) && $elements['#value'] !== '0') {
-        form_error($elements, t('%name field is required.', array('%name' => $elements['#title'])));
+        form_error($elements, t('!name field is required.', array('!name' => $elements['#title'])));
       }
 
       // Add legal choice check if element has #options. Can be skipped, but then you must validate your own element.
@@ -299,7 +299,7 @@           $value = $elements['#type'] ==
           foreach ($value as $v) {
             if (!isset($options[$v])) {
               form_error($elements, t('An illegal choice has been detected. Please contact the site administrator.'));
-              watchdog('form', t('Illegal choice %choice in %name element.', array('%choice' => theme('placeholder', check_plain($v)), '%name' => theme_placeholder(empty($elements['#title']) ? $elements['#parents'][0] : $elements['#title']))), WATCHDOG_ERROR);
+              watchdog('form', t('Illegal choice %choice in !name element.', array('%choice' => $v, '!name' => empty($elements['#title']) ? $elements['#parents'][0] : $elements['#title'])), WATCHDOG_ERROR);
             }
           }
         }
@@ -1147,10 +1147,10 @@   $required = !empty($element['#required
   if (!empty($element['#title'])) {
     $title = $element['#title'];
     if (!empty($element['#id'])) {
-      $output .= ' <label for="'. form_clean_id($element['#id']) .'">'. t('%title: %required', array('%title' => $title, '%required' => $required)) ."</label>\n";
+      $output .= ' <label for="'. form_clean_id($element['#id']) .'">'. t('!title: !required', array('!title' => $title, '!required' => $required)) ."</label>\n";
     }
     else {
-      $output .= ' <label>'. t('%title: %required', array('%title' => $title, '%required' => $required)) ."</label>\n";
+      $output .= ' <label>'. t('!title: !required', array('!title' => $title, '!required' => $required)) ."</label>\n";
     }
   }
 
Index: includes/image.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/image.inc,v
retrieving revision 1.13
diff -u -Ff -r1.13 image.inc
--- includes/image.inc	5 Jul 2006 11:45:51 -0000	1.13
+++ includes/image.inc	17 Aug 2006 19:51:16 -0000
@@ -58,7 +58,7 @@     if (function_exists($function)) {
       return call_user_func_array($function, $params);
     }
     else {
-      watchdog('php', t("The selected image handling toolkit '%toolkit' can not correctly process '%function'.", array('%toolkit' => "<em>$toolkit</em>", '%function' => "<em>$function</em>")), WATCHDOG_ERROR);
+      watchdog('php', t("The selected image handling toolkit %toolkit can not correctly process %function.", array('%toolkit' => $toolkit, '%function' => $function)), WATCHDOG_ERROR);
       return FALSE;
     }
   }
@@ -184,7 +184,7 @@   if (image_gd_check_settings()) {
     return t('The built-in GD2 toolkit is installed and working properly.');
   }
   else {
-    form_set_error('image_toolkit', t("The built-in GD image toolkit requires that the GD module for PHP be installed and configured properly. For more information see %url.", array('%url' => '<a href="http://php.net/image">http://php.net/image</a>')));
+    form_set_error('image_toolkit', t('The built-in GD image toolkit requires that the GD module for PHP be installed and configured properly. For more information see <a href="@url">PHP\'s image documentation</a>.', array('@url' => 'http://php.net/image')));
     return FALSE;
   }
 }
Index: includes/install.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/install.inc,v
retrieving revision 1.13
diff -u -Ff -r1.13 install.inc
--- includes/install.inc	8 Aug 2006 21:18:02 -0000	1.13
+++ includes/install.inc	17 Aug 2006 19:51:16 -0000
@@ -550,5 +550,27 @@  * Hardcoded function for doing the equi
  */
 function st($string, $args = array()) {
   require_once './includes/theme.inc';
-  return strtr($string, array_map('theme_placeholder', $args));
+  $GLOBALS['theme'] = 'theme';
+  // Transform arguments before inserting them
+  array_walk($args, '_st');
+  return strtr($string, $args);
+}
+
+/**
+ * Helper function: apply the appropriate transformation to st() and t() placeholders.
+ */ 
+function _st(&$value, $key) {
+  switch ($key[0]) {
+    // Escaped only
+    case '@':
+      $value = check_plain($value);
+      return;
+    // Escaped and placeholder
+    case '%':
+    default:
+      $value = '<em>'. check_plain($value) .'</em>';
+      return;
+    // Pass-through
+    case '!':
+  }
 }
Index: includes/locale.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/locale.inc,v
retrieving revision 1.86
diff -u -Ff -r1.86 locale.inc
--- includes/locale.inc	11 Aug 2006 17:51:20 -0000	1.86
+++ includes/locale.inc	17 Aug 2006 19:51:16 -0000
@@ -23,13 +23,13 @@   // If only the language was added, and
   // the language addition, we need to inform the user on how to start
   // a translation
   if ($onlylanguage) {
-    drupal_set_message(t('The language %locale has been created, and can now be used to import a translation. More information is available in the <a href="%locale-help">help screen</a>.', array('%locale' => theme('placeholder', t($name)), '%locale-help' => url('admin/help/locale'))));
+    drupal_set_message(t('The language %locale has been created and can now be used to import a translation. More information is available in the <a href="@locale-help">help screen</a>.', array('%locale' => t($name), '@locale-help' => url('admin/help/locale'))));
   }
   else {
-    drupal_set_message(t('The language %locale has been created.', array('%locale' => theme('placeholder', t($name)))));
+    drupal_set_message(t('The language %locale has been created.', array('%locale' => t($name))));
   }
 
-  watchdog('locale', t('The %language language (%locale) has been created.', array('%language' => theme('placeholder', $name), '%locale' => theme('placeholder', $code))));
+  watchdog('locale', t('The %language language (%locale) has been created.', array('%language' => $name, '%locale' => $code)));
 }
 
 /**
@@ -154,7 +154,7 @@   $form['custom language']['langcode'] =
     '#size' => 12,
     '#maxlength' => 60,
     '#required' => TRUE,
-    '#description' => t("Commonly this is an <a href=\"%iso-codes\">ISO 639 language code</a> with an optional country code for regional variants. Examples include 'en', 'en-US' and 'zh-cn'.", array('%iso-codes' => 'http://www.w3.org/WAI/ER/IG/ert/iso639.htm')),
+    '#description' => t("Commonly this is an <a href=\"@iso-codes\">ISO 639 language code</a> with an optional country code for regional variants. Examples include 'en', 'en-US' and 'zh-cn'.", array('@iso-codes' => 'http://www.w3.org/WAI/ER/IG/ert/iso639.htm')),
   );
   $form['custom language']['langname'] = array('#type' => 'textfield',
     '#title' => t('Language name in English'),
@@ -175,7 +175,7 @@  * Validate the language addition form.
  */
 function locale_add_language_form_validate($form_id, $form_values) {
   if ($duplicate = db_num_rows(db_query("SELECT locale FROM {locales_meta} WHERE locale = '%s'", $form_values['langcode'])) != 0) {
-    form_set_error(t('The language %language (%code) already exists.', array('%language' => theme('placeholder', check_plain($form_values['langname'])), '%code' => theme('placeholder', $form_values['langcode']))));
+    form_set_error(t('The language %language (%code) already exists.', array('%language' => $form_values['langname'], '%code' => $form_values['langcode'])));
   }
 
   if (!isset($form_values['langname'])) {
@@ -259,7 +259,7 @@     _locale_add_language($form_values['l
   // Now import strings into the language
   $file = file_check_upload('file');
   if ($ret = _locale_import_po($file, $form_values['langcode'], $form_values['mode']) == FALSE) {
-    $message = t('The translation import of %filename failed.', array('%filename' => theme('placeholder', $file->filename)));
+    $message = t('The translation import of %filename failed.', array('%filename' => $file->filename));
     drupal_set_message($message, 'error');
     watchdog('locale', $message, WATCHDOG_ERROR);
   }
@@ -469,7 +469,7 @@   // Get status information on import pr
   list($headerdone, $additions, $updates) = _locale_import_one_string('report', $mode);
 
   if (!$headerdone) {
-    drupal_set_message(t('The translation file %filename appears to have a missing or malformed header.', array('%filename' => theme('placeholder', $file->filename))), 'error');
+    drupal_set_message(t('The translation file %filename appears to have a missing or malformed header.', array('%filename' => $file->filename)), 'error');
   }
 
   // rebuild locale cache
@@ -479,7 +479,7 @@     drupal_set_message(t('The translatio
   menu_rebuild();
 
   drupal_set_message(t('The translation was successfully imported. There are %number newly created translated strings and %update strings were updated.', array('%number' => $additions, '%update' => $updates)));
-  watchdog('locale', t('Imported %file into %locale: %number new strings added and %update updated.', array('%file' => theme('placeholder', $file->filename), '%locale' => theme('placeholder', $lang), '%number' => $additions, '%update' => $updates)));
+  watchdog('locale', t('Imported %file into %locale: %number new strings added and %update updated.', array('%file' => $file->filename, '%locale' => $lang, '%number' => $additions, '%update' => $updates)));
   return TRUE;
 }
 
@@ -982,8 +982,8 @@   if ($key == 0 || $key == 1) {
   }
 
   // First remove any possibly false indices, then add new ones
-  $entry = preg_replace('/(%count)\[[0-9]\]/', '\\1', $entry);
-  return preg_replace('/(%count)/', "\\1[$key]", $entry);
+  $entry = preg_replace('/(@count)\[[0-9]\]/', '\\1', $entry);
+  return preg_replace('/(@count)/', "\\1[$key]", $entry);
 }
 
 /**
@@ -1083,7 +1083,7 @@     if ($meta->formula && $meta->plurals
       $header .= "\"Plural-Forms: nplurals=". $meta->plurals ."; plural=". strtr($meta->formula, '$', '') .";\\n\"\n";
     }
     $header .= "\n";
-    watchdog('locale', t('Exported %locale translation file: %filename.', array('%locale' => theme('placeholder', $meta->name), '%filename' => theme('placeholder', $filename))));
+    watchdog('locale', t('Exported %locale translation file: %filename.', array('%locale' => $meta->name, '%filename' => $filename)));
   }
 
   // Generating Portable Object Template
@@ -1104,7 +1104,7 @@     $header .= "\"Content-Type: text/pla
     $header .= "\"Content-Transfer-Encoding: 8bit\\n\"\n";
     $header .= "\"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\\n\"\n";
     $header .= "\n";
-    watchdog('locale', t('Exported translation file: %filename.', array('%filename' => theme('placeholder', $filename))));
+    watchdog('locale', t('Exported translation file: %filename.', array('%filename' => $filename)));
   }
 
   // Start download process
@@ -1212,7 +1212,7 @@     elseif (strlen("$cur $word") > $len)
  * Removes plural index information from a string
  */
 function _locale_export_remove_plural($entry) {
-  return preg_replace('/(%count)\[[0-9]\]/', '\\1', $entry);
+  return preg_replace('/(@count)\[[0-9]\]/', '\\1', $entry);
 }
 
 /**
Index: includes/theme.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/theme.inc,v
retrieving revision 1.307
diff -u -Ff -r1.307 theme.inc
--- includes/theme.inc	17 Aug 2006 06:55:26 -0000	1.307
+++ includes/theme.inc	17 Aug 2006 19:51:16 -0000
@@ -338,9 +338,8 @@  * The theme system is described and def
  */
 
 /**
- * Format a dynamic text string for emphasized display in a placeholder.
- *
- * E.g. t('Added term %term', array('%term' => theme('placeholder', $term)))
+ * Formats text for emphasized display in a placeholder inside a sentence.
+ * Used automatically by t().
  *
  * @param $text
  *   The text to format (plain-text).
@@ -606,10 +605,10 @@   if (module_exist('taxonomy')) {
   }
 
   if ($page == 0) {
-    $output .= t('%title by %name', array('%title' => '<h2 class="title">'. check_plain($node->title) .'</h2>', '%name' => theme('username', $node)));
+    $output .= t('!title by !name', array('!title' => '<h2 class="title">'. check_plain($node->title) .'</h2>', '!name' => theme('username', $node)));
   }
   else {
-    $output .= t('by %name', array('%name' => theme('username', $node)));
+    $output .= t('by !name', array('!name' => theme('username', $node)));
   }
 
   if (count($terms)) {
@@ -889,7 +888,7 @@       if (count($children) > 0) {
  * Returns code that emits the 'more help'-link.
  */
 function theme_more_help_link($url) {
-  return '<div class="more-help-link">' . t('[<a href="%link">more help...</a>]', array('%link' => check_url($url))) . '</div>';
+  return '<div class="more-help-link">' . t('[<a href="@link">more help...</a>]', array('@link' => check_url($url))) . '</div>';
 }
 
 /**
Index: includes/unicode.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/unicode.inc,v
retrieving revision 1.18
diff -u -Ff -r1.18 unicode.inc
--- includes/unicode.inc	5 Jul 2006 11:45:51 -0000	1.18
+++ includes/unicode.inc	17 Aug 2006 19:51:16 -0000
@@ -31,7 +31,7 @@   // Check for outdated PCRE library
   // Note: we check if U+E2 is in the range U+E0 - U+E1. This test returns TRUE on old PCRE versions.
   if (preg_match('/[à-á]/u', 'â')) {
     if ($errors) {
-      form_set_error('unicode', t('The PCRE library in your PHP installation is outdated. This will cause problems when handling Unicode text. If you are running PHP 4.3.3 or higher, make sure you are using the PCRE library supplied by PHP. Please refer to the <a href="%url">PHP PCRE documentation</a> for more information.', array('%url' => 'http://www.php.net/pcre')));
+      form_set_error('unicode', t('The PCRE library in your PHP installation is outdated. This will cause problems when handling Unicode text. If you are running PHP 4.3.3 or higher, make sure you are using the PCRE library supplied by PHP. Please refer to the <a href="@url">PHP PCRE documentation</a> for more information.', array('@url' => 'http://www.php.net/pcre')));
     }
     return UNICODE_ERROR;
   }
@@ -44,25 +44,25 @@   if (!function_exists('mb_strlen')) {
   // Check mbstring configuration
   if (ini_get('mbstring.func_overload') != 0) {
     if ($errors) {
-      form_set_error('unicode', t('Multibyte string function overloading in PHP is active and must be disabled. Check the php.ini <em>mbstring.func_overload</em> setting. Please refer to the <a href="%url">PHP mbstring documentation</a> for more information.', array('%url' => 'http://www.php.net/mbstring')));
+      form_set_error('unicode', t('Multibyte string function overloading in PHP is active and must be disabled. Check the php.ini <em>mbstring.func_overload</em> setting. Please refer to the <a href="@url">PHP mbstring documentation</a> for more information.', array('@url' => 'http://www.php.net/mbstring')));
     }
     return UNICODE_ERROR;
   }
   if (ini_get('mbstring.encoding_translation') != 0) {
     if ($errors) {
-      form_set_error('unicode', t('Multibyte string input conversion in PHP is active and must be disabled. Check the php.ini <em>mbstring.encoding_translation</em> setting. Please refer to the <a href="%url">PHP mbstring documentation</a> for more information.', array('%url' => 'http://www.php.net/mbstring')));
+      form_set_error('unicode', t('Multibyte string input conversion in PHP is active and must be disabled. Check the php.ini <em>mbstring.encoding_translation</em> setting. Please refer to the <a href="@url">PHP mbstring documentation</a> for more information.', array('@url' => 'http://www.php.net/mbstring')));
     }
     return UNICODE_ERROR;
   }
   if (ini_get('mbstring.http_input') != 'pass') {
     if ($errors) {
-      form_set_error('unicode', t('Multibyte string input conversion in PHP is active and must be disabled. Check the php.ini <em>mbstring.http_input</em> setting. Please refer to the <a href="%url">PHP mbstring documentation</a> for more information.', array('%url' => 'http://www.php.net/mbstring')));
+      form_set_error('unicode', t('Multibyte string input conversion in PHP is active and must be disabled. Check the php.ini <em>mbstring.http_input</em> setting. Please refer to the <a href="@url">PHP mbstring documentation</a> for more information.', array('@url' => 'http://www.php.net/mbstring')));
     }
     return UNICODE_ERROR;
   }
   if (ini_get('mbstring.http_output') != 'pass') {
     if ($errors) {
-      form_set_error('unicode', t('Multibyte string output conversion in PHP is active and must be disabled. Check the php.ini <em>mbstring.http_output</em> setting. Please refer to the <a href="%url">PHP mbstring documentation</a> for more information.', array('%url' => 'http://www.php.net/mbstring')));
+      form_set_error('unicode', t('Multibyte string output conversion in PHP is active and must be disabled. Check the php.ini <em>mbstring.http_output</em> setting. Please refer to the <a href="@url">PHP mbstring documentation</a> for more information.', array('@url' => 'http://www.php.net/mbstring')));
     }
     return UNICODE_ERROR;
   }
@@ -78,8 +78,8 @@  * Return the required Unicode status an
  */
 function unicode_settings() {
   $status = _unicode_check(TRUE);
-  $options = array(UNICODE_SINGLEBYTE => t('Standard PHP: operations on Unicode strings are emulated on a best-effort basis. Install the <a href="%url">PHP mbstring extension</a> for improved Unicode support.', array('%url' => 'http://www.php.net/mbstring')),
-                   UNICODE_MULTIBYTE => t('Multi-byte: operations on Unicode strings are supported through the <a href="%url">PHP mbstring extension</a>.', array('%url' => 'http://www.php.net/mbstring')),
+  $options = array(UNICODE_SINGLEBYTE => t('Standard PHP: operations on Unicode strings are emulated on a best-effort basis. Install the <a href="@url">PHP mbstring extension</a> for improved Unicode support.', array('@url' => 'http://www.php.net/mbstring')),
+                   UNICODE_MULTIBYTE => t('Multi-byte: operations on Unicode strings are supported through the <a href="@url">PHP mbstring extension</a>.', array('@url' => 'http://www.php.net/mbstring')),
                    UNICODE_ERROR => t('Invalid: the current configuration is incompatible with Drupal.'));
   $form['settings'] = array('#type' => 'item', '#title' => t('String handling method'), '#value' => $options[$status]);
   return $form;
@@ -128,7 +128,7 @@       $encoding = 'utf-8';
       $data = ereg_replace('^(<\?xml[^>]+encoding)="([^"]+)"', '\\1="utf-8"', $out);
     }
     else {
-      watchdog('php', t("Could not convert XML encoding '%s' to UTF-8.", array('%s' => $encoding)), WATCHDOG_WARNING);
+      watchdog('php', t("Could not convert XML encoding %s to UTF-8.", array('%s' => $encoding)), WATCHDOG_WARNING);
       return 0;
     }
   }
@@ -161,7 +161,7 @@   else if (function_exists('recode_strin
     $out = @recode_string($encoding .'..utf-8', $data);
   }
   else {
-    watchdog('php', t("Unsupported encoding '%s'. Please install iconv, GNU recode or mbstring for PHP.", array('%s' => $encoding)), WATCHDOG_ERROR);
+    watchdog('php', t("Unsupported encoding %s. Please install iconv, GNU recode or mbstring for PHP.", array('%s' => $encoding)), WATCHDOG_ERROR);
     return FALSE;
   }
 
