diff --git modules/field/modules/text/text.test modules/field/modules/text/text.test
index 1843f36..1b4e7ae 100644
--- modules/field/modules/text/text.test
+++ modules/field/modules/text/text.test
@@ -198,7 +198,10 @@ class TextFieldTestCase extends DrupalWebTestCase {
     // Create a new text format that does not escape HTML, and grant the user
     // access to it.
     $this->drupalLogin($this->admin_user);
-    $edit = array('name' => $this->randomName());
+    $edit = array(
+      'name' => $this->randomName(),
+      'machine_name' => drupal_strtolower($this->randomName()),
+    );
     $this->drupalPost('admin/config/content/formats/add', $edit, t('Save configuration'));
     filter_formats_reset();
     $this->checkPermissions(array(), TRUE);
@@ -386,8 +389,15 @@ class TextTranslationTestCase extends DrupalWebTestCase {
   function setUp() {
     parent::setUp('locale', 'translation');
 
-    $this->format = 3;
-    $this->admin = $this->drupalCreateUser(array('administer languages', 'administer content types', 'access administration pages', 'bypass node access', "use text format $this->format"));
+    $full_html_format = db_query_range('SELECT * FROM {filter_format} WHERE name = :name', 0, 1, array(':name' => 'Full HTML'))->fetchObject();
+    $this->format = $full_html_format->format;
+    $this->admin = $this->drupalCreateUser(array(
+      'administer languages',
+      'administer content types',
+      'access administration pages',
+      'bypass node access',
+      filter_permission_name($full_html_format),
+    ));
     $this->translator = $this->drupalCreateUser(array('create article content', 'edit own article content', 'translate content'));
 
     // Enable an additional language.
diff --git modules/filter/filter.admin.inc modules/filter/filter.admin.inc
index e793b69..5464c9d 100644
--- modules/filter/filter.admin.inc
+++ modules/filter/filter.admin.inc
@@ -96,7 +96,11 @@ function theme_filter_admin_overview($variables) {
 function filter_admin_format_page($format = NULL) {
   if (!isset($format->name)) {
     drupal_set_title(t('Add text format'));
-    $format = (object) array('name' => '', 'format' => 0);
+    $format = (object) array(
+      'format' => 0,
+      'machine_name' => '',
+      'name' => '',
+    );
   }
   return drupal_get_form('filter_admin_format_form', $format);
 }
@@ -122,6 +126,14 @@ function filter_admin_format_form($form, &$form_state, $format) {
     '#default_value' => $format->name,
     '#required' => TRUE,
   );
+  $form['machine_name'] = array(
+    '#type' => 'textfield', // @todo http://drupal.org/node/902644
+    '#default_value' => $format->machine_name,
+    '#machine_name_exists' => 'filter_format_load',
+    // Since the machine name needs to relate to the text format ID, it cannot
+    // be changed after initial creation.
+    '#disabled' => !empty($format->format),
+  );
 
   // Add user role access selection.
   $form['roles'] = array(
diff --git modules/filter/filter.install modules/filter/filter.install
index 1297c0b..5d0e417 100644
--- modules/filter/filter.install
+++ modules/filter/filter.install
@@ -19,6 +19,13 @@ function filter_schema() {
         'default' => 0,
         'description' => 'Foreign key: The {filter_format}.format to which this filter is assigned.',
       ),
+      'format_machine_name' => array(
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+        'description' => 'Foreign key: The {filter_format}.machine_name to which this filter is assigned.',
+      ),
       'module' => array(
         'type' => 'varchar',
         'length' => 64,
@@ -66,12 +73,19 @@ function filter_schema() {
         'not null' => TRUE,
         'description' => 'Primary Key: Unique ID for format.',
       ),
+      'machine_name' => array(
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+        'description' => 'Machine name of the format.',
+      ),
       'name' => array(
         'type' => 'varchar',
         'length' => 255,
         'not null' => TRUE,
         'default' => '',
-        'description' => 'Name of the text format (Filtered HTML).',
+        'description' => 'Name of the format.',
         'translatable' => TRUE,
       ),
       'cache' => array(
@@ -90,6 +104,7 @@ function filter_schema() {
     ),
     'primary key' => array('format'),
     'unique keys' => array(
+      'machine_name' => array('machine_name'),
       'name' => array('name'),
     ),
     'indexes' => array(
@@ -113,6 +128,7 @@ function filter_install() {
   // installation profiles to have other properties.
   $plain_text_format = array(
     'name' => 'Plain text',
+    'machine_name' => 'plain_text',
     'weight' => 10,
     'filters' => array(
       // Escape all HTML.
@@ -173,6 +189,24 @@ function filter_update_7000() {
       'weight' => array('weight'),
     ),
   ));
+  // Add a new {filter_format}.machine_name column.
+  db_add_field('filter_format', 'machine_name', array(
+    'type' => 'varchar',
+    'length' => 255,
+    'not null' => TRUE,
+    'default' => '',
+    'description' => 'Machine name of the format.',
+  ));
+  // Auto-generate machine names.
+  $formats = db_query('SELECT format, name FROM {filter_format}')->fetchAllKeyed();
+  foreach ($formats as $format => $name) {
+    $machine_name = preg_replace('@[^a-z0-9]+@', '_', drupal_strtolower($name));
+    db_update('filter_format')
+      ->fields(array('machine_name' => $machine_name))
+      ->condition('format', $format)
+      ->execute();
+  }
+  db_add_unique_key('filter_format', 'machine_name', array('machine_name'));
 }
 
 /**
@@ -215,6 +249,13 @@ function filter_update_7003() {
         'default' => 0,
         'description' => 'Foreign key: The {filter_format}.format to which this filter is assigned.',
       ),
+      'format_machine_name' => array(
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+        'description' => 'Foreign key: The {filter_format}.machine_name to which this filter is assigned.',
+      ),
       'module' => array(
         'type' => 'varchar',
         'length' => 64,
@@ -269,6 +310,7 @@ function filter_update_7003() {
       '0' => 'php_code',
     ),
   );
+  $machine_names = db_query('SELECT format, machine_name FROM {filter_format}')->fetchAllKeyed();
 
   // Loop through each filter and make changes to the core filter table by
   // each record from the old to the new table.
@@ -307,6 +349,7 @@ function filter_update_7003() {
         db_insert('filter')
           ->fields(array(
             'format' => $record->format,
+            'format_machine_name' => $machine_names[$record->format],
             'module' => $module,
             'name' => $new_name,
             'weight' => $record->weight,
@@ -343,7 +386,7 @@ function filter_update_7005() {
     $format_roles = ($format->format == $default_format ? $all_roles : explode(',', $format->roles));
     foreach ($format_roles as $format_role) {
       if (in_array($format_role, $all_roles)) {
-        _update_7000_user_role_grant_permissions($format_role, array('use text format ' . $format->format), 'filter');
+        _update_7000_user_role_grant_permissions($format_role, array('use text format ' . $format->machine_format), 'filter');
       }
     }
   }
@@ -428,9 +471,9 @@ function filter_update_7005() {
 function filter_update_7008() {
   // Build the list of permissions to grant.
   $permissions = array();
-  foreach (db_query('SELECT format FROM {filter_format}')->fetchCol() as $format_id) {
+  foreach (db_query('SELECT format, machine_name FROM {filter_format}')->fetchAllKeyed() as $format_id => $machine_name) {
     if ($format_id != variable_get('filter_fallback_format')) {
-      $permissions[] = 'use text format ' . $format_id;
+      $permissions[] = 'use text format ' . $machine_name;
     }
   }
   // Grant text format permissions to all roles that can 'administer filters'.
diff --git modules/filter/filter.module modules/filter/filter.module
index d36253d..acdb24d 100644
--- modules/filter/filter.module
+++ modules/filter/filter.module
@@ -221,6 +221,7 @@ function filter_format_save(&$format) {
     }
 
     $fields = array();
+    $fields['format_machine_name'] = $format->machine_name;
     $fields['weight'] = $format->filters[$name]['weight'];
     $fields['status'] = $format->filters[$name]['status'];
     $fields['module'] = $format->filters[$name]['module'];
@@ -328,8 +329,8 @@ function filter_permission() {
  *   is malformed or is the fallback format (which is available to all users).
  */
 function filter_permission_name($format) {
-  if (isset($format->format) && $format->format != filter_fallback_format()) {
-    return 'use text format ' . $format->format;
+  if (isset($format->format) && isset($format->machine_name) && $format->format != filter_fallback_format()) {
+    return 'use text format ' . $format->machine_name;
   }
   return FALSE;
 }
@@ -384,6 +385,10 @@ function filter_formats($account = NULL) {
       ->orderBy('weight')
       ->execute()
       ->fetchAllAssoc('format');
+
+    // Allow modules to alter the list of formats; e.g., to load formats
+    // exported into code.
+    drupal_alter('filter_formats', $formats['all']);
   }
 
   // Build a list of user-specific formats.
diff --git modules/filter/filter.test modules/filter/filter.test
index 4a737d9..449300b 100644
--- modules/filter/filter.test
+++ modules/filter/filter.test
@@ -24,6 +24,7 @@ class FilterCRUDTestCase extends DrupalWebTestCase {
     // Add a text format with minimum data only.
     $format = new stdClass();
     $format->name = 'Empty format';
+    $format->machine_name = 'empty_format';
     filter_format_save($format);
     $this->verifyTextFormat($format);
     $this->verifyFilters($format);
@@ -31,6 +32,7 @@ class FilterCRUDTestCase extends DrupalWebTestCase {
     // Add another text format specifying all possible properties.
     $format = new stdClass();
     $format->name = 'Custom format';
+    $format->machine_name = 'custom_format';
     $format->filters = array(
       'filter_url' => array(
         'status' => 1,
@@ -79,6 +81,7 @@ class FilterCRUDTestCase extends DrupalWebTestCase {
       ->execute()
       ->fetchObject();
     $this->assertEqual($db_format->format, $format->format, t('Database: Proper format id for text format %format.', $t_args));
+    $this->assertEqual($db_format->machine_name, $format->machine_name, t('Database: Proper machine name for text format %format.', $t_args));
     $this->assertEqual($db_format->name, $format->name, t('Database: Proper title for text format %format.', $t_args));
     $this->assertEqual($db_format->cache, $format->cache, t('Database: Proper cache indicator for text format %format.', $t_args));
     $this->assertEqual($db_format->weight, $format->weight, t('Database: Proper weight for text format %format.', $t_args));
@@ -86,6 +89,7 @@ class FilterCRUDTestCase extends DrupalWebTestCase {
     // Verify filter_format_load().
     $filter_format = filter_format_load($format->format);
     $this->assertEqual($filter_format->format, $format->format, t('filter_format_load: Proper format id for text format %format.', $t_args));
+    $this->assertEqual($filter_format->machine_name, $format->machine_name, t('filter_format_load: Proper machine name for text format %format.', $t_args));
     $this->assertEqual($filter_format->name, $format->name, t('filter_format_load: Proper title for text format %format.', $t_args));
     $this->assertEqual($filter_format->cache, $format->cache, t('filter_format_load: Proper cache indicator for text format %format.', $t_args));
     $this->assertEqual($filter_format->weight, $format->weight, t('filter_format_load: Proper weight for text format %format.', $t_args));
@@ -121,7 +125,8 @@ class FilterCRUDTestCase extends DrupalWebTestCase {
       // Verify that filter settings were properly stored.
       $this->assertEqual(unserialize($filter->settings), isset($format_filters[$name]['settings']) ? $format_filters[$name]['settings'] : array(), t('Database: Proper filter settings for %filter in text format %format.', $t_args));
 
-      // Verify that each filter has a module name assigned.
+      // Verify that each filter has a machine and module name assigned.
+      $this->assertEqual($filter->format_machine_name, $format->machine_name, t('Database: Proper machine name for %filter in text format %format.', $t_args));
       $this->assertTrue(!empty($filter->module), t('Database: Proper module name for %filter in text format %format.', $t_args));
 
       // Remove the filter from the copy of saved $format to check whether all
@@ -143,7 +148,8 @@ class FilterCRUDTestCase extends DrupalWebTestCase {
       // Verify that filter settings were properly stored.
       $this->assertEqual($filter->settings, isset($format_filters[$name]['settings']) ? $format_filters[$name]['settings'] : array(), t('filter_list_format: Proper filter settings for %filter in text format %format.', $t_args));
 
-      // Verify that each filter has a module name assigned.
+      // Verify that each filter has a machine and module name assigned.
+      $this->assertEqual($filter->format_machine_name, $format->machine_name, t('filter_list_format: Proper machine name for %filter in text format %format.', $t_args));
       $this->assertTrue(!empty($filter->module), t('filter_list_format: Proper module name for %filter in text format %format.', $t_args));
 
       // Remove the filter from the copy of saved $format to check whether all
@@ -270,6 +276,7 @@ class FilterAdminTestCase extends DrupalWebTestCase {
     // Add format.
     $edit = array();
     $edit['name'] = $this->randomName();
+    $edit['machine_name'] = drupal_strtolower($this->randomName());
     $edit['roles[2]'] = 1;
     $edit['filters[' . $second_filter . '][status]'] = TRUE;
     $edit['filters[' . $first_filter . '][status]'] = TRUE;
@@ -424,7 +431,10 @@ class FilterFormatAccessTestCase extends DrupalWebTestCase {
     $this->drupalLogin($this->admin_user);
     $formats = array();
     for ($i = 0; $i < 2; $i++) {
-      $edit = array('name' => $this->randomName());
+      $edit = array(
+        'name' => $this->randomName(),
+        'machine_name' => drupal_strtolower($this->randomName()),
+      );
       $this->drupalPost('admin/config/content/formats/add', $edit, t('Save configuration'));
       $this->resetFilterCaches();
       $format_id = db_query("SELECT format FROM {filter_format} WHERE name = :name", array(':name' => $edit['name']))->fetchField();
@@ -577,7 +587,10 @@ class FilterDefaultFormatTestCase extends DrupalWebTestCase {
     $this->drupalLogin($admin_user);
     $formats = array();
     for ($i = 0; $i < 2; $i++) {
-      $edit = array('name' => $this->randomName());
+      $edit = array(
+        'name' => $this->randomName(),
+        'machine_name' => drupal_strtolower($this->randomName()),
+      );
       $this->drupalPost('admin/config/content/formats/add', $edit, t('Save configuration'));
       $this->resetFilterCaches();
       $format_id = db_query("SELECT format FROM {filter_format} WHERE name = :name", array(':name' => $edit['name']))->fetchField();
@@ -1606,6 +1619,7 @@ class FilterHooksTestCase extends DrupalWebTestCase {
     $name = $this->randomName();
     $edit = array();
     $edit['name'] = $name;
+    $edit['machine_name'] = drupal_strtolower($this->randomName());
     $edit['roles[1]'] = 1;
     $this->drupalPost('admin/config/content/formats/add', $edit, t('Save configuration'));
     $this->assertRaw(t('Added text format %format.', array('%format' => $name)), t('New format created.'));
diff --git modules/php/php.install modules/php/php.install
index bc5d7d6..1a8bbb4 100644
--- modules/php/php.install
+++ modules/php/php.install
@@ -18,6 +18,7 @@ function php_enable() {
   if (!$format_exists) {
     $php_format = array(
       'name' => 'PHP code',
+      'machine_name' => 'php_code',
       // 'Plain text' format is installed with a weight of 10 by default. Use a
       // higher weight here to ensure that this format will not be the default
       // format for anyone.
diff --git modules/search/search.test modules/search/search.test
index 3dbbd1b..9d91ad5 100644
--- modules/search/search.test
+++ modules/search/search.test
@@ -696,9 +696,9 @@ class SearchCommentTestCase extends DrupalWebTestCase {
     // Enable check_plain() for 'Filtered HTML' text format.
     $filtered_html_format_id = db_query_range('SELECT format FROM {filter_format} WHERE name = :name', 0, 1, array(':name' => 'Filtered HTML'))->fetchField();
     $edit = array(
-      'filters[filter_html_escape][status]' => $filtered_html_format_id,
+      'filters[filter_html_escape][status]' => TRUE,
     );
-    $this->drupalPost('admin/config/content/formats/1', $edit, t('Save configuration'));
+    $this->drupalPost('admin/config/content/formats/' . $filtered_html_format_id, $edit, t('Save configuration'));
     // Allow anonymous users to search content.
     $edit = array(
       DRUPAL_ANONYMOUS_RID . '[search content]' => 1,
diff --git profiles/standard/standard.install profiles/standard/standard.install
index a93b6b3..711d7a5 100644
--- profiles/standard/standard.install
+++ profiles/standard/standard.install
@@ -10,6 +10,7 @@ function standard_install() {
   // Add text formats.
   $filtered_html_format = array(
     'name' => 'Filtered HTML',
+    'machine_name' => 'filtered_html',
     'weight' => 0,
     'filters' => array(
       // URL filter.
@@ -39,6 +40,7 @@ function standard_install() {
 
   $full_html_format = array(
     'name' => 'Full HTML',
+    'machine_name' => 'full_html',
     'weight' => 1,
     'filters' => array(
       // URL filter.
