diff --git a/image_effects_text/image_effects_text.inc b/image_effects_text/image_effects_text.inc
index 76adb41..b6aabee 100644
--- a/image_effects_text/image_effects_text.inc
+++ b/image_effects_text/image_effects_text.inc
@@ -58,7 +58,7 @@ function image_effects_text_form_inc(array $data) {
   module_load_include('inc', 'imagecache_actions', 'utility-color');
 
   // Note: we also need to check for the existence of the module: admin has
-  //   all rights, so user_acccess(...) returns TRUE even if the module is not
+  //   all rights, so user_access(...) returns TRUE even if the module is not
   //   enabled and the permission does not exist.
   // A user without the 'use PHP for settings' permission (defined by the core
   // PHP filter module) may not:
@@ -77,6 +77,7 @@ function image_effects_text_form_inc(array $data) {
     'fontfile' => drupal_get_path('module', 'image_effects_text') . '/Komika_display.ttf',
     'text_source' => 'text',
     'text' => t('Hello World!'),
+    'token' => '[file:basename]',
     'php' => 'if (!$image_context[\'entity\']) {
   return \'' . t('No referring entity') . '\';
 }
@@ -90,6 +91,8 @@ if ($field) {
 ',
   );
   $data += $defaults;
+  $tokens = token_info();
+  $tokens = array_keys($tokens['types']);
   $form = array(
     'size' => array(
       '#type' => 'textfield',
@@ -117,14 +120,22 @@ if ($field) {
       '#title' => t('Horizontal alignment'),
       '#default_value' => $data['halign'],
       '#description' => t('The horizontal alignment of the text around the given %xpos.', array('%xpos' => t('X offset'))),
-      '#options' => array('left' => t('Left'), 'center' => t('Center'), 'right' => t('Right')),
+      '#options' => array(
+        'left' => t('Left'),
+        'center' => t('Center'),
+        'right' => t('Right')
+      ),
     ),
     'valign' => array(
       '#type' => 'select',
       '#title' => t('Vertical alignment'),
       '#default_value' => $data['valign'],
       '#description' => t('The vertical alignment of the text around the given %ypos.', array('%ypos' => t('Y offset'))),
-      '#options' => array('top' => t('Top'), 'center' => t('Center'), 'bottom' => t('Bottom')),
+      '#options' => array(
+        'top' => t('Top'),
+        'center' => t('Center'),
+        'bottom' => t('Bottom')
+      ),
     ),
     'RGB' => imagecache_rgb_form($data['RGB']),
     'alpha' => array(
@@ -157,6 +168,7 @@ if ($field) {
 <li><strong>Image alt</strong>: the alt text of an image field referring to this image is taken.</li>
 <li><strong>Image title</strong>: the title text of an image field referring to this image is taken.</li>
 <li><strong>Static text</strong>: a text that will be the same for each image, e.g. a copyright message. You can define the text in the text field below the drop down.</li>
+<li><strong>Token</strong>: a text with token replacement, so it can differ per image. You can define the text in the text field below the drop down.</li>
 <li><strong>PHP code</strong>: a piece of PHP code that returns the text to display. You can define the PHP code in the text area below the drop down. You will need the \'%use_php\' permission, defined by the \'PHP filter\' module.</li>
 </ul>
 <p>See the help in README.txt for an extensive explanation of the possibilities.</p>',
@@ -166,7 +178,13 @@ if ($field) {
       '#type' => 'select',
       '#title' => t('Text source'),
       '#default_value' => $data['text_source'],
-      '#options' => array('alt' => t('Image alt'), 'title' => t('Image title'), 'text' => t('Static text'), 'php' => t('PHP code')),
+      '#options' => array(
+        'alt' => t('Image alt'),
+        'title' => t('Image title'),
+        'text' => t('Static text'),
+        'token' => t('Token'),
+        'php' => t('PHP code'),
+      ),
     ),
     'text' => array(
       '#type' => 'textfield',
@@ -176,6 +194,33 @@ if ($field) {
         'visible' => array(':input[name="data[text_source]"]' => array('value' => 'text')),
       ),
     ),
+    'token' => array(
+      '#type' => 'textfield',
+      '#title' => t('Text with token replacement'),
+      '#default_value' => $data['token'],
+      '#states' => array(
+        'visible' => array(':input[name="data[text_source]"]' => array('value' => 'token')),
+      ),
+    ),
+    'token_help' => array(
+      '#type' => 'fieldset',
+      '#title' => t('Token replacement patterns'),
+      '#collapsible' => TRUE,
+      '#collapsed' => TRUE,
+      'tree' => array(
+        '#theme' => 'token_tree',
+        '#token_types' => $tokens,
+      ),
+      'token_module_notice' => array(
+        '#markup' => !module_exists('token') ? t('You might want to enable token.module to view token replacement patterns.') : '',
+      ),
+      'entity_token_module_notice' => array(
+        '#markup' => !module_exists('entity_token') ? t('You might want to enable entity_token.module to get token options for all entities and field properties.') : '',
+      ),
+      '#states' => array(
+        'visible' => array(':input[name="data[text_source]"]' => array('value' => 'token')),
+      ),
+    ),
     'php' => array(
       '#type' => 'textarea',
       '#rows' => 12,
@@ -248,6 +293,9 @@ function theme_image_effects_text_summary(array $variables) {
     case 'text':
       $text = $data['text'];
       break;
+    case 'token':
+      $text = $data['token'];
+      break;
     case 'php':
       $text = 'PHP code';
       break;
@@ -298,7 +346,7 @@ function image_effects_text_effect_inc(stdClass $image, array $data) {
 
   // Convert color from hex (as it is stored in the UI).
   $params['RGB'] = $data['RGB'];
-  if($params['RGB']['HEX'] && $deduced = imagecache_actions_hex2rgba($params['RGB']['HEX'])) {
+  if ($params['RGB']['HEX'] && $deduced = imagecache_actions_hex2rgba($params['RGB']['HEX'])) {
     $params['RGB'] += $deduced;
   }
 
@@ -340,7 +388,7 @@ function image_gd_image_effects_text(stdClass $image, array $params) {
         // Get height of bounding box.
         $height = $bounds[1] - $bounds[7];
         // Shift ypos down (full height on bottom, half the height on center).
-        $params['ypos'] += $params['valign'] === 'center' ? (int) ($height/2) : $height;
+        $params['ypos'] += $params['valign'] === 'center' ? (int) ($height / 2) : $height;
       }
     }
     // Adjust X position for horizontal alignment (if different from left).
@@ -358,7 +406,7 @@ function image_gd_image_effects_text(stdClass $image, array $params) {
         // Get width of bounding box.
         $width = $bounds[2] - $bounds[0];
         // Shift xpos to the left (full width on right, half the width on center).
-        $params['xpos'] -= $params['halign'] === 'center' ? (int) ($width/2) : $width;
+        $params['xpos'] -= $params['halign'] === 'center' ? (int) ($width / 2) : $width;
       }
     }
 
@@ -462,7 +510,7 @@ function image_imagemagick_image_effects_text(stdClass $image, array $params) {
 
   // Convert color and alpha to Imagemagick rgba color argument.
   $alpha = $params['alpha'] / 100;
-  $color = 'rgba(' . $params['RGB']['red']. ',' . $params['RGB']['green'] . ',' . $params['RGB']['blue'] . ','. $alpha . ')';
+  $color = 'rgba(' . $params['RGB']['red'] . ',' . $params['RGB']['green'] . ',' . $params['RGB']['blue'] . ',' . $alpha . ')';
 
   // Set gravity for the alignment and calculate the translation to the
   // requested x and y offset as starting from the gravity point.
@@ -592,7 +640,7 @@ function image_effects_text_get_offset($position, $width, $height, $length) {
         break;
       case 'center':
         // half the current dimension as provided by $length.
-        $value += $sign * $length/2;
+        $value += $sign * $length / 2;
         $sign = 1;
         break;
       default:
@@ -624,7 +672,9 @@ function image_effects_text_get_offset($position, $width, $height, $length) {
  */
 function image_effects_text_get_text(stdClass $image, array $data) {
   if ($data['text_source'] === 'text') {
+    // Replace \n with a newline character, except when preceded by a \.
     $text = preg_replace('/([^\\\\])\\\\n/', "$1\n", $data['text']);
+    // Replace \\n by \n.
     $text = preg_replace('/\\\\\\\\n/', '\n', $text);
   }
   else {
@@ -651,6 +701,22 @@ function image_effects_text_get_text(stdClass $image, array $data) {
         }
       }
     }
+    elseif ($data['text_source'] === 'token') {
+      $token_data = array();
+      foreach ($image_context['referring_entities'] as /*$field_name =>*/ $field_referring_entities) {
+        foreach ($field_referring_entities as $entity_type => $entities) {
+          foreach ($entities as /*$entity_id =>*/ $entity) {
+            // We can pass only 1 entity per given type to token_replace().
+            $token_data[$entity_type] = $entity;
+            break;
+          }
+        }
+      }
+      if ($image_context['managed_file']) {
+        $token_data['file'] = $image_context['managed_file'];
+      }
+      $text = token_replace($data['token'], $token_data, array('clear' => TRUE));
+    }
     else { // $data['text_source'] === 'php'
       // Process the php using php_eval (rather than eval), but with GLOBAL
       // variables, so they can be passed successfully.
@@ -658,7 +724,7 @@ function image_effects_text_get_text(stdClass $image, array $data) {
       $GLOBALS['image'] = $image;
       // We don't need to check_plain() the resulting text, as the text is not
       // rendered in a browser but processed on the server.
-      $text = module_exists('php') ? php_eval('<'.'?php global $image, $image_context; ' . $data['php'] . ' ?'.'>') : '';
+      $text = module_exists('php') ? php_eval('<' . '?php global $image, $image_context; ' . $data['php'] . ' ?' . '>') : '';
 
       unset($GLOBALS['image']);
       unset($GLOBALS['image_context']);
