Index: modules/filter/filter.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/filter/filter.module,v
retrieving revision 1.360
diff -u -r1.360 filter.module
--- modules/filter/filter.module	1 Dec 2010 00:00:21 -0000	1.360
+++ modules/filter/filter.module	8 Dec 2010 19:59:10 -0000
@@ -1195,22 +1195,24 @@
  * Settings callback for the HTML filter.
  */
 function _filter_html_settings($form, &$form_state, $filter, $format, $defaults) {
+  $filter->settings += $defaults;
+
   $settings['allowed_html'] = array(
     '#type' => 'textfield',
     '#title' => t('Allowed HTML tags'),
-    '#default_value' => isset($filter->settings['allowed_html']) ? $filter->settings['allowed_html'] : $defaults['allowed_html'],
+    '#default_value' => $filter->settings['allowed_html'],
     '#maxlength' => 1024,
     '#description' => t('A list of HTML tags that can be used. JavaScript event attributes, JavaScript URLs, and CSS are always stripped.'),
   );
   $settings['filter_html_help'] = array(
     '#type' => 'checkbox',
     '#title' => t('Display basic HTML help in long filter tips'),
-    '#default_value' => isset($filter->settings['filter_html_help']) ? $filter->settings['filter_html_help'] : $defaults['filter_html_help'],
+    '#default_value' => $filter->settings['filter_html_help'],
   );
   $settings['filter_html_nofollow'] = array(
     '#type' => 'checkbox',
     '#title' => t('Add rel="nofollow" to all links'),
-    '#default_value' => isset($filter->settings['filter_html_nofollow']) ? $filter->settings['filter_html_nofollow'] : $defaults['filter_html_nofollow'],
+    '#default_value' => $filter->settings['filter_html_nofollow'],
   );
   return $settings;
 }
@@ -1336,10 +1338,12 @@
  * Settings callback for URL filter.
  */
 function _filter_url_settings($form, &$form_state, $filter, $format, $defaults) {
+  $filter->settings += $defaults;
+
   $settings['filter_url_length'] = array(
     '#type' => 'textfield',
     '#title' => t('Maximum link text length'),
-    '#default_value' => isset($filter->settings['filter_url_length']) ? $filter->settings['filter_url_length'] : $defaults['filter_url_length'],
+    '#default_value' => $filter->settings['filter_url_length'],
     '#size' => 5,
     '#maxlength' => 4,
     '#field_suffix' => t('characters'),
Index: modules/filter/filter.api.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/filter/filter.api.php,v
retrieving revision 1.21
diff -u -r1.21 filter.api.php
--- modules/filter/filter.api.php	18 Sep 2010 02:18:35 -0000	1.21
+++ modules/filter/filter.api.php	8 Dec 2010 19:59:10 -0000
@@ -14,114 +14,29 @@
 /**
  * Define content filters.
  *
- * Content in Drupal is passed through a group of filters before it is output.
- * This lets a module modify content to the site administrator's liking.
+ * User submitted content is passed through a group of filters before it is
+ * output in HTML, in order to remove insecure or unwanted parts, correct or
+ * enhance the formatting, transform special keywords, etc. A group of filters
+ * is referred to as a "text format". Administrators can create as many text
+ * formats as needed. Individual filters can be enabled and configured
+ * differently for each text format.
  *
- * This hook allows modules to declare input filters they provide. A module can
- * contain as many filters as it wants.
- *
- * The overall, logical flow is as follows:
- * - hook_filter_info() is invoked to retrieve one or more filter definitions.
- * - The site administrator enables and configures the filter, where the
- *   following properties may be used:
- *   - 'title': The filter's title.
- *   - 'description': The filter's short-description.
- *   Additionally, if a filter is configurable:
- *   - 'settings callback': A form builder function name providing a settings
- *     form for the filter.
- *   - 'default settings': An array containing default settings for the filter.
- * - When a form containing a text format-enabled text widget/textarea is
- *   rendered, the following property are checked:
- *   - 'tips callback': A function name providing filter guidelines to be
- *      displayed in the text format widget.
- * - When a content using a text format is rendered, the following properties
- *   may be used:
- *   - 'prepare callback': A name of a function that escapes the to be filtered
- *     content before the actual filtering happens.
- *   - 'process callback': The name the function that performs the actual
- *     filtering.
+ * This hook is invoked by filter_get_filters() and allows modules to register
+ * input filters they provide.
  *
  * Filtering is a two-step process. First, the content is 'prepared' by calling
  * the 'prepare callback' function for every filter. The purpose of the 'prepare
  * callback' is to escape HTML-like structures. For example, imagine a filter
  * which allows the user to paste entire chunks of programming code without
- * requiring manual escaping of special HTML characters like @< or @&. If the
+ * requiring manual escaping of special HTML characters like < or &. If the
  * programming code were left untouched, then other filters could think it was
- * HTML and change it. For most filters however, the prepare-step is not
- * necessary, and they can just return the input without changes.
- *
- * Filters should not use the 'prepare callback' step for anything other than
- * escaping, because that would short-circuit the control the user has over the
- * order in which filters are applied.
- *
- * The second step is the actual processing step. The result from the prepare
- * step gets passed to all the filters again, this time with the 'process
- * callback' function. It's here where filters should perform actual changing of
- * the content: transforming URLs into hyperlinks, converting smileys into
- * images, etc.
- *
- * An important aspect of the filtering system is 'text formats'. Every text
- * format is an entire filter setup: which filters to enable, in what order
- * and with what settings.
- *
- * Filters that require settings should provide the form controls to configure
- * the settings in a form builder function, specified in 'settings callback'.
- * The filter system stores the settings in the database per text format.
- *
- * If the filter's behavior depends on an extensive list and/or external data
- * (e.g. a list of smileys, a list of glossary terms) then filters are allowed
- * to provide a separate, global configuration page rather than provide settings
- * per format. In that case, there should be a link from the format-specific
- * settings to the separate settings page.
- *
- * The $filter object with the current settings is passed to the 'settings
- * callback' function. If 'default settings' were defined in hook_filter_info(),
- * those are passed as second argument to the 'settings callback'. Each filter
- * should apply either the default settings or the configured settings contained
- * in $filter->settings.
- *
- * 'settings callback' is invoked with the following arguments (most filter
- * implementations will only need $form_state, $filter and $defaults):
- * - $form: The prepopulated form array, which will usually have no use here.
- * - &$form_state: The form state of the (entire) configuration form.
- * - $filter: The filter object containing settings for the given format.
- * - $format: The format object being configured.
- * - $defaults: The default settings for the filter, as defined in 'default
- *   settings' in hook_filter_info().
- * - $filters: Complete list of filter objects that are enabled for the given
- *   format.
- *
- * @code
- *   function mymodule_filter_settings($form, &$form_state, $filter, $format, $defaults, $filters) {
- *     $settings['mymodule_url_length'] = array(
- *       '#type' => 'textfield',
- *       '#title' => t('Maximum link text length'),
- *       '#default_value' => isset($filter->settings['mymodule_url_length']) ? $filter->settings['mymodule_url_length'] : $defaults['mymodule_url_length'],
- *     );
- *     return $settings;
- *   }
- * @endcode
- *
- * 'prepare callback' and 'process callback' are invoked with the following
- * arguments:
- * - $text: The text to be filtered.
- * - $filter: The filter object containing settings for the given format.
- * - $format: The format object of the text to be filtered.
- * - $langcode: (optional) The language code of the text to be filtered.
- * - $cache: Boolean whether check_markup() will cache the filtered $text in
- *   {cache_filter}.
- * - $cache_id: The cache ID used for $text in {cache_filter} when $cache is
- *   TRUE.
- *
- * @see check_markup()
- *
- * 'prepare callback' and 'process callback' functions may access the filter
- * settings in $filter->settings['mymodule_url_length'].
+ * HTML and change it. For many filters, the prepare step is not necessary.
  *
- * 'tips callback' is invoked with the following parameters:
- * - $filter: The filter object containing settings for the given format.
- * - $format: The format object of the text to be filtered.
- * - $long: Boolean whether to return long or short filter guidelines.
+ * The second step is the actual processing step. The result from passing the
+ * text through all the filters' prepare steps gets passed to all the filters
+ * again, this time with the 'process callback' function. The process callbacks
+ * should then actually change the content: transform URLs into hyperlinks,
+ * convert smileys into images, etc.
  *
  * For performance reasons content is only filtered once; the result is stored
  * in the cache table and retrieved from the cache the next time the same piece
@@ -131,36 +46,37 @@
  * caching for the entire format, not just for one filter.
  *
  * Beware of the filter cache when developing your module: it is advised to set
- * your filter to 'cache' => FALSE while developing, but be sure to remove it
- * again if it's not needed. You can clear the cache by running the SQL query
- * 'DELETE * FROM cache_filter';
+ * your filter to 'cache' => FALSE while developing, but be sure to remove that
+ * setting if it's not needed, when you are no longer in development mode.
  *
  * @return
- *   An array of filter items. Each filter item has a unique name, prefixed
- *   with the name of the module that provides it. The item is an associative
- *   array that may contain the following key-value pairs:
- *   - 'title': (required) The administrative title of the filter.
- *   - 'description': A short, administrative description of what this filter
- *     does.
- *   - 'prepare callback': A callback function to call in the 'prepare' step
- *     of the filtering.
- *   - 'process callback': (required) The callback function to call in the
- *     'process' step of the filtering.
- *   - 'settings callback': A callback function that provides form controls
- *     for the filter's settings. Each filter should apply either the default
- *     settings or the configured settings contained in $filter->settings. The
- *     user submitted values are stored in the database.
- *   - 'default settings': An array containing default settings for a filter to
- *     be applied when the filter has not been configured yet.
- *   - 'tips callback': A callback function that provides tips for using the
- *     filter. A module's tips should be informative and to the point. Short
- *     tips are preferably one-liners.
- *   - 'cache': Specifies whether the filtered text can be cached. TRUE by
- *     default. Note that defining FALSE makes the entire text format not
+ *   An associative array of filters, whose keys are internal filter names,
+ *   which should be unique and therefore prefixed with the name of the module.
+ *   Each value is an associative array describing the filter, with the
+ *   following elements (all are optional except as noted):
+ *   - title: (required) An administrative summary of what the filter does.
+ *   - description: Additional administrative information about the filter's
+ *     behavior, if needed for clarification.
+ *   - settings callback: The name of a function that returns configuration form
+ *     elements for the filter. See hook_filter_FILTER_settings() for details.
+ *   - default settings: An associative array containing default settings for
+ *     the filter, to be applied when the filter has not been configured yet.
+ *   - prepare callback: The name of a function that escapes the content before
+ *     the actual filtering happens. See hook_filter_FILTER_prepare() for
+ *     details.
+ *   - process callback: (required) The name the function that performs the
+ *     actual filtering. See hook_filter_FILTER_process() for details.
+ *   - cache (default TRUE): Specifies whether the filtered text can be cached.
+ *     Note that setting this to FALSE makes the entire text format not
  *     cacheable, which may have an impact on the site's overall performance.
+ *     See filter_format_allowcache() for details.
+ *   - tips callback: The name of a function that returns end-user-facing filter
+ *     usage guidelines for the filter. See hook_filter_FILTER_tips() for
+ *     details.
+ *   - weight: A default weight for the filter in new text formats.
  *
- * For a detailed usage example, see filter_example.module. For an example of
- * using multiple filters in one module, see filter_filter_info().
+ * @see filter_example.module
+ * @see hook_filter_info_alter()
  */
 function hook_filter_info() {
   $filters['filter_html'] = array(
@@ -203,6 +119,164 @@
 }
 
 /**
+ * @} End of "addtogroup hooks".
+ */
+
+/**
+ * Settings callback for hook_filter_info().
+ *
+ * Note: This is not really a hook. The function name is manually specified via
+ * 'settings callback' in hook_filter_info(), with this recommended callback
+ * name pattern. It is called from filter_admin_format_form().
+ *
+ * This callback function is used to provide a settings form for filter
+ * settings, for filters that need settings on a per-text-format basis. This
+ * function should return the form elements for the settings; the filter
+ * module will take care of saving the settings in the database.
+ *
+ * If the filter's behavior depends on an extensive list and/or external data
+ * (e.g. a list of smileys, a list of glossary terms), then the filter module
+ * can choose to provide a separate, global configuration page rather than
+ * per-text-format settings. In that case, the settings callback function
+ * should provide a link to the separate settings page.
+ *
+ * @param $form
+ *   The prepopulated form array of the filter administration form.
+ * @param $form_state
+ *   The state of the (entire) configuration form.
+ * @param $filter
+ *   The filter object containing the current settings for the given format,
+ *   in $filter->settings.
+ * @param $format
+ *   The format object being configured.
+ * @param $defaults
+ *   The default settings for the filter, as defined in 'default settings' in
+ *   hook_filter_info(). These should be combined with $filter->settings to
+ *   define the form element defaults.
+ * @param $filters
+ *   The complete list of filter objects that are enabled for the given format.
+ *
+ * @return
+ *   An array of form elements defining settings for the filter. Array keys
+ *   should match the array keys in $filter->settings and $defaults.
+ */
+function hook_filter_FILTER_settings($form, &$form_state, $filter, $format, $defaults, $filters) {
+  $filter->settings += $defaults;
+
+  $elements = array();
+  $elements['nofollow'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Add rel="nofollow" to all links'),
+    '#default_value' => $filter->settings['nofollow'],
+  );
+  return $elements;
+}
+
+/**
+ * Prepare callback for hook_filter_info().
+ *
+ * Note: This is not really a hook. The function name is manually specified via
+ * 'prepare callback' in hook_filter_info(), with this recommended callback
+ * name pattern. It is called from check_markup().
+ *
+ * See hook_filter_info() for a description of the filtering process. Filters
+ * should not use the 'prepare callback' step for anything other than escaping,
+ * because that would short-circuit the control the user has over the order in
+ * which filters are applied.
+ *
+ * @param $text
+ *   The text string to be filtered.
+ * @param $filter
+ *   The filter object containing settings for the given format.
+ * @param $format
+ *   The text format object assigned to the text to be filtered.
+ * @param $langcode
+ *   The language code of the text to be filtered.
+ * @param $cache
+ *   A Boolean indicating whether the filtered text is going to be cached in
+ *   {cache_filter}.
+ * @param $cache_id
+ *   The ID of the filtered text in {cache_filter}, if $cache is TRUE.
+ *
+ * @return
+ *   The prepared, escaped text.
+ */
+function hook_filter_FILTER_prepare($text, $filter, $format, $langcode, $cache, $cache_id) {
+  // Escape <code> and </code> tags.
+  $text = preg_replace('|<code>(.+?)</code>|se', "[codefilter_code]$1[/codefilter_code]", $text);
+  return $text;
+}
+
+/**
+ * Process callback for hook_filter_info().
+ *
+ * Note: This is not really a hook. The function name is manually specified via
+ * 'process callback' in hook_filter_info(), with this recommended callback
+ * name pattern. It is called from check_markup().
+ *
+ * See hook_filter_info() for a description of the filtering process. This step
+ * is where the filter actually transforms the text.
+ *
+ * @param $text
+ *   The text string to be filtered.
+ * @param $filter
+ *   The filter object containing settings for the given format.
+ * @param $format
+ *   The text format object assigned to the text to be filtered.
+ * @param $langcode
+ *   The language code of the text to be filtered.
+ * @param $cache
+ *   A Boolean indicating whether the filtered text is going to be cached in
+ *   {cache_filter}.
+ * @param $cache_id
+ *   The ID of the filtered text in {cache_filter}, if $cache is TRUE.
+ *
+ * @return
+ *   The filtered text.
+ */
+function hook_filter_FILTER_process($text, $filter, $format, $langcode, $cache, $cache_id) {
+  $text = preg_replace('|\[codefilter_code\](.+?)\[/codefilter_code\]|se', "<pre>$1</pre>", $text);
+
+  return $text;
+}
+
+/**
+ * Tips callback for hook_filter_info().
+ *
+ * Note: This is not really a hook. The function name is manually specified via
+ * 'tips callback' in hook_filter_info(), with this recommended callback
+ * name pattern. It is called from _filter_tips().
+ *
+ * A filter's tips should be informative and to the point. Short tips are
+ * preferably one-liners.
+ *
+ * @param $filter
+ *   An object representing the filter.
+ * @param $format
+ *   An object representing the text format the filter is contained in.
+ * @param $long
+ *   Whether this callback should return a short tip to display in a form
+ *   (FALSE), or whether a more elaborate filter tips should be returned for
+ *   theme_filter_tips() (TRUE).
+ *
+ * @return
+ *   Translated text to display as a tip.
+ */
+function hook_filter_FILTER_tips($filter, $format, $long) {
+ if ($long) {
+    return t('Lines and paragraphs are automatically recognized. The &lt;br /&gt; line break, &lt;p&gt; paragraph and &lt;/p&gt; close paragraph tags are inserted automatically. If paragraphs are not recognized simply add a couple blank lines.');
+  }
+  else {
+    return t('Lines and paragraphs break automatically.');
+  }
+}
+
+/**
+ * @addtogroup hooks
+ * @{
+ */
+
+/**
  * Perform actions when a new text format has been created.
  *
  * @param $format
