From b48d31fb7e7abfc6f6a668c2c945d6c34e38b332 Mon Sep 17 00:00:00 2001
From: webflo <florian@webflo.org>
Date: Sun, 20 Feb 2011 12:39:38 +0100
Subject: [PATCH] d7 port, improved filter process, use themeing functions

---
 contrib/image_caption_filter.info   |    4 +-
 contrib/image_caption_filter.module |  197 +++++++++++++++++++++++++----------
 image_caption.info                  |    4 +-
 3 files changed, 145 insertions(+), 60 deletions(-)

diff --git contrib/image_caption_filter.info contrib/image_caption_filter.info
index ed94890..989087e 100755
--- contrib/image_caption_filter.info
+++ contrib/image_caption_filter.info
@@ -1,5 +1,5 @@
 ; $Id$
 name = Image caption filter
 description = Create captions on images using the title attribute.
-core = 6.x
-version = 6.x-1.x-dev
+core = 7.x
+files[] = image_caption_filter.module
\ No newline at end of file
diff --git contrib/image_caption_filter.module contrib/image_caption_filter.module
index 20bf7c5..7e97009 100755
--- contrib/image_caption_filter.module
+++ contrib/image_caption_filter.module
@@ -15,70 +15,157 @@
 */
 
 /**
-* Display help and module information
-* @param path which path of the site we're displaying help
-* @param arg array that holds the current path as would be returned from arg() function
-* @return help text for the path
-*/
-function image_caption_filter_help($path, $arg) {
-  $output = '';
-  switch ($path) {
-    case "admin/help#image_caption_filter":
-      $output = '<p>' .  t("Adds captions to images") . '</p>';
-      break;
-  }
-  return $output;
-} //function image_caption_filter_help
+ * Implements hook_filter_info().
+ */
+function image_caption_filter_filter_info() {
+  $filters['filter_image_caption'] = array(
+    'title' => t('Image caption filter'),
+    'settings callback' => 'image_caption_filter_filter_filter_image_caption_settings',
+    'process callback' => 'image_caption_filter_filter_filter_image_caption_process',
+    'tips callback' => 'image_caption_filter_filter_filter_image_caption_tips',
+    'default settings' => array(
+      'classes' => variable_get('image_caption_filter_classes', 'image-left image-right standalone-image'),
+    ),
+  );
+ 
+  return $filters;
+}
 
-//filter hook implementation
-function image_caption_filter_filter($op, $delta = 0, $format = -1, $text = '') {
-  switch ($op) {
-    case 'list':
-      return array(0 => t('Image caption filter'));
-
-    case 'description':
-      return t('Adds captions to images via a filter');
+/**
+ * Implements hook_filter_FILTER_settings().
+ */
+function image_caption_filter_filter_filter_image_caption_settings($form, &$form_state, $filter, $format, $defaults, $filters) {
+  $filter->settings += $defaults;
+  $elements = array();
+  
+  $elements['classes'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Classes to be searched for image captions'),
+    '#default_value' => $filter->settings['classes'],
+    '#size' => 80,
+    '#description' => t('Enter a space-separated list of classes. The filter will only operate on images which have one of these CSS classes and have a title attribute and a width set.'),
+    '#required' => TRUE,
+  );
+  
+  return $elements;
+}
 
-    case 'prepare':
-      // Nothing to prepare
-      return $text;
+/**
+ * Implements hook_filter_FILTER_process().
+ */
+function image_caption_filter_filter_filter_image_caption_process($text, $filter, $format, $langcode, $cache, $cache_id) {
+  image_caption_filter_active_classes(array_filter(explode(' ', $filter->settings['classes'])));
+  return preg_replace_callback('|(<img.*?>)|s', '_image_caption_filter_do_img_titles', $text);
+}
 
-    case "process":
-      //Look for <img> tags and run the doImgTitles function on the <img> tag
-      $text = preg_replace_callback('|(<img.*?>)|s', 'doImgTitles', $text);
-      return $text;
+/**
+ * Implements hook_filter_FILTER_tips().
+ *
+ * Display help and module information
+ * @param path which path of the site we're displaying help
+ * @param arg array that holds the current path as would be returned from arg() function
+ * @return help text for the path
+ */
+function image_caption_filter_filter_filter_image_caption_tips($filter, $format, $long = FALSE) {
+  return '<p>' . t("Adds captions to images") . '</p>';
+}
 
-    default:
-      return $text;
+/**
+ * Storage for active class names
+ * 
+ * _image_caption_filter_do_img_titles() is called by preg_replace_callback() and this function allows only one argument.
+ */
+function image_caption_filter_active_classes($classes = NULL) {
+  static $_classes = array();
+  if ($classes != NULL) { 
+    $_classes = $classes; 
   }
-} //function image_caption_filter_filter
+  
+  return $_classes;
+}
 
+/**
+ * Helper function to do the actual manipulation.
+ */
+function _image_caption_filter_do_img_titles($img_tag_matches, $active_classes = NULL) {
+  $img_tag = $img_tag_matches[0];
+  $return_text = $img_tag;
 
-//helper function to do the actual manipulation
-function doImgTitles($matches) {
-  $imgText = $matches[0];
+  // only execute this filter on img tags with (at least) one of the classes we are interested in
+  $has_class = preg_match('/class=\"(.+?)\"/i', $img_tag, $matches) > 0;
+  if ($has_class) {
+    $class = $matches[1];
+    // formally, class is a space separated list of classes, but we allow all horizontal whitespace in any quantity
+    // that's why we use preg_split instead of explode
+    $classes = preg_split('/\s+/', $class, null, PREG_SPLIT_NO_EMPTY);
 
-  //Get the title out of the <img> tag
-  preg_match ('/title=\"(.+?)\"/i', $imgText, $matches);
-  $title = $matches[1];
+    // get active classes via image_caption_filter_active_classes() because preg_replace_callback() does not support addional arguments.
+    if ($active_classes == NULL) {
+      $active_classes = image_caption_filter_active_classes();
+    }
 
-  //Get the width out of the <img> tag
-  preg_match ('/width=\"(.+?)\"/i', $imgText, $matches);
-  $width = $matches[1];
+    if (count(array_intersect($classes, $active_classes)) > 0) {
+      // only execute this filter on img tags that have a title attribute
+      $has_title = preg_match('/title=\"(.+?)\"/i', $img_tag, $matches) > 0;
+      if ($has_title) {
+        $title = $matches[1];
 
-  //Get class out of the <img> tag
-  preg_match ('/class=\"(.+?)\"/i', $imgText, $matches);
-  $class = $matches[1];
+        // search for width specified as an inline style or width attribute,
+        // if no width specified, don't output it on the outer span, assume width will be handled with css external to this module/filter
+        $width = '';
+        if (preg_match('/width:\s*(\d+)px/i', $img_tag, $matches) == 1 || preg_match ('/width=\"(\d+?)\"/i', $img_tag, $matches) == 1) {
+          $width = $matches[1];
+        }
 
-  //Only insert the caption and modify the <img> tag if it is has a title attribute and is one of the classes we are interested in
-  if (in_array($class, array('image-left', 'image-right', 'standalone-image')) && ($title)) {
-    $imgText = preg_replace ('/class=\"(.+?)\"/i', '', $imgText);
-    $returnText = "<div class=\"" . $class . "\" style=\"width: " . $width . "px\">"
-                  . $imgText 
-                  . "<div class=\"caption\">" . $title . "</div></div>";
-    return $returnText;
-  }
-  return $imgText;
-} //function doImgTitles
+        // search for float specified as an inline style on the image
+        $float = '';
+        if (preg_match('/float:\s*(\w+)/i', $img_tag, $matches) == 1) {
+          $float = $matches[1];
+        }
+
+        // remove the class from the image tag
+        $img_tag = preg_replace('/class=\"(.+?)\"/i', '', $img_tag);
 
-?>
+        // build the image and caption
+        $caption = array(
+          'img' => array(
+            '#type' => 'markup',
+            '#markup' => $img_tag,
+          ),
+          'caption' => array(
+            '#type' => 'html_tag',
+            '#tag' => 'span',
+            '#attributes' => array(
+              'class' => 'caption',
+            ),
+            '#value' => $title,
+          ),
+        );
+
+        // build the wrapping elemement.
+        $element = array(
+          'image_caption' => array(
+            '#type' => 'html_tag',
+            '#tag' => 'span',
+            '#attributes' => array(
+              'class' => $class
+            ),
+            '#value' => render($caption),
+          ),
+        );
+
+        if (!empty($width)) {
+          $element['image_caption']['#attributes']['style'][] = 'width:' . $width . 'px;';
+        }
+        
+        if (!empty($float)) {
+          $element['image_caption']['#attributes']['style'][] = 'float:' . $float;
+        }
+        
+        $return_text = render($element);
+      }
+    }
+  }
+  
+  return $return_text;
+}
diff --git image_caption.info image_caption.info
index 2253580..5cf009b 100644
--- image_caption.info
+++ image_caption.info
@@ -1,6 +1,4 @@
 ;$Id;
 name = "Image Caption"
 description = "Provides a caption for images using jquery."
-core = "6.x"
-php = "4.7"
-version = "6.x-1.0"
\ No newline at end of file
+core = "7.x"
\ No newline at end of file
-- 
1.7.3.3

