From 417161c23d9493397844772c9564bbf931797ff0 Mon Sep 17 00:00:00 2001
From: Helior Colorado <me@helior.info>
Date: Wed, 20 Jun 2012 12:36:47 -0700
Subject: [PATCH] Support for input filters.

---
 advanced_help.module |  105 +++++++++++++++++++++++++++++++++++++++++++++++--
 help/ini-file.html   |   10 ++++-
 2 files changed, 109 insertions(+), 6 deletions(-)

diff --git a/advanced_help.module b/advanced_help.module
index ad55411..fad638d 100644
--- a/advanced_help.module
+++ b/advanced_help.module
@@ -614,11 +614,14 @@ function advanced_help_view_topic($module, $topic, $popup = FALSE) {
     $output = preg_replace('/&base_url&([^"]+)"/', strtr(url('$1'), array('%24' => '$')) . '"', $output);

     // Run the line break filter if requested
-    if (!empty($info['line break'])) {
+    if (array_search('filter_autop', $info['input filters']) !== FALSE) {
       // Remove the header since it adds an extra <br /> to the filter.
       $output = preg_replace('/^<!--[^\n]*-->\n/', '', $output);
+    }

-      $output = _filter_autop($output);
+    // Execute the available input filters
+    if (!empty($info['input filters'])) {
+      $output = advanced_help_check_markup($output, $info['input filters']);
     }

     if (!empty($info['navigation'])) {
@@ -685,6 +688,87 @@ function advanced_help_view_topic($module, $topic, $popup = FALSE) {
 }

 /**
+ * A customized version of check_markup() that will prepare and process text
+ * directly through a series of available input filters.
+ *
+ * @param $text
+ *   The text to be filtered.
+ * @param $input_filters
+ *   An array of input filter names requested to use for processing.
+ * @param $langcode
+ *   Optional: the language code of the text to be filtered, e.g. 'en' for
+ *   English. This allows filters to be language aware so language specific
+ *   text replacement can be implemented.
+ *
+ * @return
+ *   A string of processed text.
+ */
+function advanced_help_check_markup($text, $input_filters, $langcode = '') {
+  // There is no format object.
+  $format = NULL;
+  // Input format caching is disabled.
+  $cache = FALSE;
+  $cache_id = '';
+
+  // Convert all Windows and Mac newlines to a single newline, so filters only
+  // need to deal with one possibility.
+  $text = str_replace(array("\r\n", "\r"), "\n", $text);
+
+  $filter_info = filter_get_filters();
+  $filters = advanced_help_get_filters($input_filters);
+
+  // Give filters the chance to escape HTML-like data such as code or formulas.
+  foreach ($filters as $name => $filter) {
+    if ($filter->status && isset($filter_info[$name]['prepare callback']) && function_exists($filter_info[$name]['prepare callback'])) {
+      $function = $filter_info[$name]['prepare callback'];
+      $text = $function($text, $filter, $format, $langcode, $cache, $cache_id);
+    }
+  }
+
+  // Perform filtering.
+  foreach ($filters as $name => $filter) {
+    if ($filter->status && isset($filter_info[$name]['process callback']) && function_exists($filter_info[$name]['process callback'])) {
+      $function = $filter_info[$name]['process callback'];
+      $text = $function($text, $filter, $format, $langcode, $cache, $cache_id);
+    }
+  }
+
+  return $text;
+}
+
+/**
+ * Create an array of available filter objects.
+ *
+ * @param $input_filters
+ *   An array of filter names.
+ *
+ * @return
+ *   An array of filter objects.
+ */
+function advanced_help_get_filters($input_filters = array()) {
+  $filter_info = filter_get_filters();
+  $filters = array();
+
+  foreach ($input_filters as $name) {
+    if (isset($filter_info[$name])) {
+      $info = array(
+        'format' => NULL,
+        'module' => $filter_info[$name]['module'],
+        'name' => $name,
+        'weight' => $filter_info[$name]['weight'],
+        'status' => TRUE,
+        'settings' => isset($filter_info[$name]['default settings']) ? $filter_info[$name]['default settings'] : array(),
+        'title' => $filter_info[$name]['title'],
+      );
+
+      $filters[$name] = (object) $info;
+    }
+  }
+
+  return $filters;
+}
+
+/**
  * Get the information for a single help topic.
  */
 function advanced_help_get_topic($module, $topic) {
@@ -767,6 +851,16 @@ function _advanced_help_parse_ini() {
         foreach ($info as $name => $topic) {
           // Each topic should have a name, a title, a file and of course the path.
           $file = !empty($topic['file']) ? $topic['file'] : $name;
+          $extension = !empty($topic['extension']) ? $topic['extension'] : (isset($cache['settings'][$module]['extension']) ? $cache['settings'][$module]['extension'] : 'html');
+
+          // Determine which input filters to use for processing the content of the help file.
+          $input_filters = isset($topic['input filters']) ? $topic['input filters'] : (isset($cache['settings'][$module]['input filters']) ? $cache['settings'][$module]['input filters'] : array());
+          $line_break = isset($topic['line break']) ? $topic['line break'] : (isset($cache['settings'][$module]['line break']) ? $cache['settings'][$module]['line break'] : FALSE);
+          // Add the line break input filter if requested, and hasn't already been added.
+          if ($line_break && (array_search('filter_autop', $input_filters) === FALSE)) {
+            array_unshift($input_filters, 'filter_autop');
+          }
+
           $cache['topics'][$module][$name] = array(
             'name' => $name,
             'title' => !empty($translation[$name]['title']) ? $translation[$name]['title'] : $topic['title'],
@@ -774,9 +868,10 @@ function _advanced_help_parse_ini() {
             'parent' => isset($topic['parent']) ? $topic['parent'] : 0,
             'popup width' => isset($topic['popup width']) ? $topic['popup width'] : 500,
             'popup height' => isset($topic['popup height']) ? $topic['popup height'] : 500,
-            'file' => isset($topic['readme file']) ? $file : $file . '.html', // require extension
+            'file' => isset($topic['readme file']) ? $file : "$file.$extension", // require extension
             'path' => $path, // not in .ini file
-            'line break' => isset($topic['line break']) ? $topic['line break'] : (isset($cache['settings'][$module]['line break']) ? $cache['settings'][$module]['line break'] : FALSE),
+            'line break' => $line_break,
+            'input filters' => $input_filters,
             'navigation' => isset($topic['navigation']) ? $topic['navigation'] : (isset($cache['settings'][$module]['navigation']) ? $cache['settings'][$module]['navigation'] : TRUE),
             'css' => isset($topic['css']) ? $topic['css'] : (isset($cache['settings'][$module]['css']) ? $cache['settings'][$module]['css'] : NULL),
             'readme file' => isset($topic['readme file']) ? $topic['readme file'] : FALSE,
@@ -868,7 +963,7 @@ function advanced_help_search_status() {
       }
     }
   }
-
+
   $last_cron = variable_get('advanced_help_last_cron', array('time' => 0));
   $indexed = 0;
   if ($last_cron['time'] != 0) {
diff --git a/help/ini-file.html b/help/ini-file.html
index 375fe67..ed8baeb 100644
--- a/help/ini-file.html
+++ b/help/ini-file.html
@@ -6,6 +6,8 @@ Global settings may be put into a section named <strong>[advanced help settings]
 <dl>
 <dt><strong>line break</strong></dt>
 <dd>If set to any value, the line break filter will be applied to all help files defined by this module, unless that help file specifically is set otherwise. By default, the line break filter is not applied; however, help files can be much easier to write with the line break filter on.</dd>
+<dt><strong>input filters</strong></dt>
+<dd>Specify an array of input filters to process your help file. This will make it possible to write help files in alternative formats, such as Markdown or Textile.</dd>
 <dt><strong>navigation</strong></dt>
 <dd>If set to true, the navigation will be displayed at the end of the help topic: previous topic, next topic, and child topics.</dd>
 <dt><strong>css</strong></dt>
@@ -14,6 +16,8 @@ Global settings may be put into a section named <strong>[advanced help settings]
 <dd>May be set to override the module name as displayed in both the module index as well as the navigation and breadcrumb trail. In general this does not need to be set, but a few modules may want to use a more friendly name than appears in the .info file.</dd>
 <dt><strong>index name</strong></dt>
 <dd>This may be set to change the name of the module in the module index. It overrides the 'name' setting above, as well as the module name in its .info file.</dd>
+<dt><strong>extension</strong></dt>
+<dd>The file extension of the help files. The default is "html", however, alternative file extensions such as "txt", "md", etc. can be used.</dd>
 <dt><strong>hide</strong></dt>
 <dd>This may be used to hide a module in the module index. This is particularly useful for modules who insert their help files into the hierarchy of another module, as might be done by modules that extend Views or CCK. By setting "hide = TRUE" the module will not appear as its own entry.</dd>
 </dl>
@@ -23,13 +27,17 @@ Each section after that will correspond to a single help file, and each one may
 <dt><strong>title</strong></dt>
 <dd>The title of the topic, presented to the user and used in links. If you have special characters in your title, be sure to enclose it in quotes.</dd>
 <dt><strong>file</strong></dt>
-<dd>The filename, without the .html extension, used for the topic. This is optional; if not specified, the topic name wil be the file name.</dd>
+<dd>The filename, without the extension (e.g. ".html"), used for the topic. This is optional; if not specified, the topic name wil be the file name.</dd>
+<dt><strong>extension</strong></dt>
+<dd>The file extension of the help file. The default is "html", however, alternative file extensions such as "txt", "md", etc. can be used.</dd>
 <dt><strong>weight</strong></dt>
 <dd>The weight, used for sorting topics on the administration page. Defaults to 0 of unspecified. Items with the same weight are sorted alphabetically.</dd>
 <dt><strong>parent</strong></dt>
 <dd>The topic ID to use in a hierarchy; children will be listed beneath parents in the topic list, and will have the parent in their breadcrumb trail. You may parent this topic to another module's topic by using module%topic as the identifier. For example, 'views%display' will make this a child of the 'display' topic in the 'views' module.</dd>
 <dt><strong>line break</strong></dt>
 <dd>If set to true, linebreaks will be converted into br and p tags automatically. If unspecified, will default to off. Set to 0 to disable the filter if this has been turned on in the global settings.</dd>
+<dt><strong>input filters</strong></dt>
+<dd>Specify an array of input filters to process your help file. This will make it possible to write help files in alternative formats, such as Markdown or Textile.</dd>
 <dt><strong>css</strong></dt>
 <dd>Specify a css file that will be used for this file. This .css file must reside in the help directory along with the .html files. This will override any .css file added by the global system.</dd>
 <dt><strong>popup width</strong></dt>
--
1.7.7.5 (Apple Git-26)

