diff --git a/chessboard.module b/chessboard.module
index fe15b2c..7299f75 100644
--- a/chessboard.module
+++ b/chessboard.module
@@ -199,38 +199,89 @@ function chessboard_process_chessboard_notation($elements) {
  */
 function chessboard_elements() {
   $types = array();
+  $image_directory_path = drupal_get_path('module', 'chessboard') . '/default';
+  $dimensions = array(
+    'square' => array(
+      'width' => 40,
+      'height' => 40,
+    ),
+    'border-h' => array(
+      'width' => 40,
+      'height' => 4,
+    ),
+    'border-v' => array(
+      'width' => 4,
+      'height' => 40,
+    ),
+    'border-c' => array(
+      'width' => 4,
+      'height' => 4,
+    ),
+  );
+  $class_attributes = array(
+    'square' => array(
+      'class' => 'chessboard-square',
+    ),
+    'border-h' => array(
+      'class' => 'chessboard-border-h',
+    ),
+    'border-v' => array(
+      'class' => 'chessboard-border-v',
+    ),
+    'border-c' => array(
+      'class' => 'chessboard-border-c',
+    ),
+  );
   $types['chessboard_diagram'] = array(
     '#attached' => array(
       'css' => array(
         drupal_get_path('module', 'chessboard') . '/chessboard.css' => array('media' => 'all', 'preprocess' => FALSE),
       ),
     ),
-    '#dimensions' => array(
-      'square' => array(
-        'width' => 40,
-        'height' => 40,
-      ),
-      'border-h' => array(
-        'width' => 40,
-        'height' => 4,
-      ),
-      'border-v' => array(
-        'width' => 4,
-        'height' => 40,
-      ),
-      'border-c' => array(
-        'width' => 4,
-        'height' => 4,
-      ),
-    ),
+    '#dimensions' => $dimensions,
     '#file_max' => 8,
-    '#image_directory_path' => drupal_get_path('module', 'chessboard') . '/default',
+    '#image_directory_path' => $image_directory_path,
     '#item' => NULL,
     '#pre_render' => array('chessboard_process_chessboard_notation'),
     '#prefix' => '<div class="chessboard">',
     '#suffix' => '</div>',
     '#theme' => 'chessboard',
   );
+  // Construct the translation table
+  $size_attributes = $dimensions;
+
+  // Empty and marked squares
+  $table_tiles = array(
+    '-0' => array('#theme' => 'chessboard_image', '#path' => $image_directory_path . '/' . chessboard_piece_filename('-', 0), '#width' => $size_attributes['square']['width'], '#height' => $size_attributes['square']['height'], '#alt' => '-', '#title' => '', '#attributes' => $class_attributes['square']),
+    '-1' => array('#theme' => 'chessboard_image', '#path' => $image_directory_path . '/' . chessboard_piece_filename('-', 1), '#width' => $size_attributes['square']['width'], '#height' => $size_attributes['square']['height'], '#alt' => '-', '#title' => '', '#attributes' => $class_attributes['square']),
+    'x0' => array('#theme' => 'chessboard_image', '#path' => $image_directory_path . '/' . chessboard_piece_filename('x', 0), '#width' => $size_attributes['square']['width'], '#height' => $size_attributes['square']['height'], '#alt' => 'x', '#title' => '', '#attributes' => $class_attributes['square']),
+    'x1' => array('#theme' => 'chessboard_image', '#path' => $image_directory_path . '/' . chessboard_piece_filename('x', 1), '#width' => $size_attributes['square']['width'], '#height' => $size_attributes['square']['height'], '#alt' => 'x', '#title' => '', '#attributes' => $class_attributes['square']),
+  );
+
+  // Pieces
+  $pieces = 'kqbnrp';
+  for ($i=0; $i<6; $i++) {
+    $piece = $pieces[$i];
+    $table_tiles += array(
+      strtoupper($piece) . '0' => array('#theme' => 'chessboard_image', '#path' => $image_directory_path . '/' . chessboard_piece_filename(strtoupper($piece), 0), '#width' => $size_attributes['square']['width'], '#height' => $size_attributes['square']['height'], '#alt' => strtoupper($piece), '#title' => '', '#attributes' => $class_attributes['square']),
+      strtoupper($piece) . '1' => array('#theme' => 'chessboard_image', '#path' => $image_directory_path . '/' . chessboard_piece_filename(strtoupper($piece), 1), '#width' => $size_attributes['square']['width'], '#height' => $size_attributes['square']['height'], '#alt' => strtoupper($piece), '#title' => '', '#attributes' => $class_attributes['square']),
+      $piece . '0' => array('#theme' => 'chessboard_image', '#path' => $image_directory_path . '/' . chessboard_piece_filename($piece, 0), '#width' => $size_attributes['square']['width'], '#height' => $size_attributes['square']['height'], '#alt' => $piece, '#title' => '', '#attributes' => $class_attributes['square']),
+      $piece . '1' => array('#theme' => 'chessboard_image', '#path' => $image_directory_path . '/' . chessboard_piece_filename($piece, 1), '#width' => $size_attributes['square']['width'], '#height' => $size_attributes['square']['height'], '#alt' => $piece, '#title' => '', '#attributes' => $class_attributes['square']),
+    );
+  }
+
+  // Borders
+  $table_tiles += array(
+    'T' => array('#theme' => 'chessboard_image', '#path' => $image_directory_path . '/' . chessboard_border_filename('T'), '#width' => $size_attributes['border-h']['width'], '#height' => $size_attributes['border-h']['height'], '#title' => '', '#attributes' => $class_attributes['border-h']),
+    'B' => array('#theme' => 'chessboard_image', '#path' => $image_directory_path . '/' . chessboard_border_filename('B'), '#width' => $size_attributes['border-h']['width'], '#height' => $size_attributes['border-h']['height'], '#title' => '', '#attributes' => $class_attributes['border-h']),
+    'L' => array('#theme' => 'chessboard_image', '#path' => $image_directory_path . '/' . chessboard_border_filename('L'), '#width' => $size_attributes['border-v']['width'], '#height' => $size_attributes['border-v']['height'], '#title' => '', '#attributes' => $class_attributes['border-v']),
+    'R' => array('#theme' => 'chessboard_image', '#path' => $image_directory_path . '/' . chessboard_border_filename('R'), '#width' => $size_attributes['border-v']['width'], '#height' => $size_attributes['border-v']['height'], '#title' => '', '#attributes' => $class_attributes['border-v']),
+    'TL' => array('#theme' => 'chessboard_image', '#path' => $image_directory_path . '/' . chessboard_border_filename('TL'), '#width' => $size_attributes['border-c']['width'], '#height' => $size_attributes['border-c']['height'], '#title' => '', '#attributes' => $class_attributes['border-c']),
+    'TR' => array('#theme' => 'chessboard_image', '#path' => $image_directory_path . '/' . chessboard_border_filename('TR'), '#width' => $size_attributes['border-c']['width'], '#height' => $size_attributes['border-c']['height'], '#title' => '', '#attributes' => $class_attributes['border-c']),
+    'BL' => array('#theme' => 'chessboard_image', '#path' => $image_directory_path . '/' . chessboard_border_filename('BL'), '#width' => $size_attributes['border-c']['width'], '#height' => $size_attributes['border-c']['height'], '#title' => '', '#attributes' => $class_attributes['border-c']),
+    'BR' => array('#theme' => 'chessboard_image', '#path' => $image_directory_path . '/' . chessboard_border_filename('BR'), '#width' => $size_attributes['border-c']['width'], '#height' => $size_attributes['border-c']['height'], '#title' => '', '#attributes' => $class_attributes['border-c']),
+  );
+  $types['chessboard_diagram']['#table_tiles'] = $table_tiles;
   return $types;
 }
 
@@ -244,10 +295,13 @@ function chessboard_theme() {
       'arguments' => array('element' => NULL),
       'file' => 'chessboard_render.php',
     ),
+    'chessboard_image' => array(
+      'arguments' => array('element' => NULL),
+      'file' => 'chessboard_render.php',
+    ),
   );
 }
 
-
 /**
  * Return data from the persistent cache when given an array of cache IDs.
  *
diff --git a/chessboard_render.php b/chessboard_render.php
index ffdf84b..f607897 100644
--- a/chessboard_render.php
+++ b/chessboard_render.php
@@ -9,67 +9,9 @@ function template_preprocess_chessboard(&$variables) {
 
   $image_directory_path = $variables['element']['#image_directory_path'];
   if (!isset($tables_xhtml[$image_directory_path])) {
-    $groups = array('square', 'border-h', 'border-v', 'border-c');
-    $class_attributes = array(
-      'square' => array(
-        'class' => 'chessboard-square',
-      ),
-      'border-h' => array(
-        'class' => 'chessboard-border-h',
-      ),
-      'border-v' => array(
-        'class' => 'chessboard-border-v',
-      ),
-      'border-c' => array(
-        'class' => 'chessboard-border-c',
-      ),
-    );
-    $size_attributes = $variables['element']['#dimensions'];
-    $group_attributes = array();
-    foreach ($groups as $group) {
-      if (!isset($size_attributes[$group])) {
-        $size_attributes[$group] = array();
-      }
-      if (!isset($class_attributes[$group])) {
-        $class_attributes[$group] = array();
-      }
-      $group_attributes[$group] = $size_attributes[$group] + $class_attributes[$group];
+    foreach($variables['element']['#table_tiles'] as $code => $tile) {
+      $tables_xhtml[$image_directory_path][$code] = drupal_render($tile);
     }
-
-    // Construct the translation table
-
-    // Empty and marked squares
-    $table_xhtml = array(
-      '-0' => strtr(theme('image', $image_directory_path . '/' . chessboard_piece_filename('-', 0), '-', NULL, $group_attributes['square'], FALSE), array('"  ' => '" ')),
-      '-1' => strtr(theme('image', $image_directory_path . '/' . chessboard_piece_filename('-', 1), '-', NULL, $group_attributes['square'], FALSE), array('"  ' => '" ')),
-      'x0' => strtr(theme('image', $image_directory_path . '/' . chessboard_piece_filename('x', 0), 'x', NULL, $group_attributes['square'], FALSE), array('"  ' => '" ')),
-      'x1' => strtr(theme('image', $image_directory_path . '/' . chessboard_piece_filename('x', 1), 'x', NULL, $group_attributes['square'], FALSE), array('"  ' => '" ')),
-    );
-
-    // Pieces
-    $pieces = 'kqbnrp';
-    for ($i=0; $i<6; $i++) {
-      $piece = $pieces[$i];
-      $table_xhtml += array(
-        strtoupper($piece) . '0' => strtr(theme('image', $image_directory_path . '/' . chessboard_piece_filename(strtoupper($piece), 0), strtoupper($piece), NULL, $group_attributes['square'], FALSE), array('"  ' => '" ')),
-        strtoupper($piece) . '1' => strtr(theme('image', $image_directory_path . '/' . chessboard_piece_filename(strtoupper($piece), 1), strtoupper($piece), NULL, $group_attributes['square'], FALSE), array('"  ' => '" ')),
-        $piece . '0' => strtr(theme('image', $image_directory_path . '/' . chessboard_piece_filename($piece, 0), $piece, NULL, $group_attributes['square'], FALSE), array('"  ' => '" ')),
-        $piece . '1' => strtr(theme('image', $image_directory_path . '/' . chessboard_piece_filename($piece, 1), $piece, NULL, $group_attributes['square'], FALSE), array('"  ' => '" ')),
-      );
-    }
-
-    // Borders
-    $table_xhtml += array(
-      'T' => strtr(theme('image', $image_directory_path . '/' . chessboard_border_filename('T'), '', NULL, $group_attributes['border-h'], FALSE), array('"  ' => '" ')),
-      'B' => strtr(theme('image', $image_directory_path . '/' . chessboard_border_filename('B'), '', NULL, $group_attributes['border-h'], FALSE), array('"  ' => '" ')),
-      'L' => strtr(theme('image', $image_directory_path . '/' . chessboard_border_filename('L'), '', NULL, $group_attributes['border-v'], FALSE), array('"  ' => '" ')),
-      'R' => strtr(theme('image', $image_directory_path . '/' . chessboard_border_filename('R'), '', NULL, $group_attributes['border-v'], FALSE), array('"  ' => '" ')),
-      'TL' => strtr(theme('image', $image_directory_path . '/' . chessboard_border_filename('TL'), '', NULL, $group_attributes['border-c'], FALSE), array('"  ' => '" ')),
-      'TR' => strtr(theme('image', $image_directory_path . '/' . chessboard_border_filename('TR'), '', NULL, $group_attributes['border-c'], FALSE), array('"  ' => '" ')),
-      'BL' => strtr(theme('image', $image_directory_path . '/' . chessboard_border_filename('BL'), '', NULL, $group_attributes['border-c'], FALSE), array('"  ' => '" ')),
-      'BR' => strtr(theme('image', $image_directory_path . '/' . chessboard_border_filename('BR'), '', NULL, $group_attributes['border-c'], FALSE), array('"  ' => '" ')),
-    );
-    $tables_xhtml[$image_directory_path] = $table_xhtml;
   }
   $variables['table_xhtml'] = $tables_xhtml[$image_directory_path];
   // For convenience.
@@ -78,3 +20,28 @@ function template_preprocess_chessboard(&$variables) {
   $variables['border'] = $variables['element']['#border'];
   $variables['board'] = $variables['element']['#board'];
 }
+
+/**
+ *  Returns HTML for an image.
+ *
+ * @param $element
+ *    An associative array containing:
+ *    - #path
+ *    - #width
+ *    - #height
+ *    - #alt
+ *    - #title
+ *    - #attributes
+ *
+ * @ingroup themable
+ */
+function theme_chessboard_image($element) {
+  $path = $element['#path'];
+  $width = $element['#width'];
+  $height = $element['#height'];
+  $alt = $element['#alt'];
+  $title = $element['#title'];
+  $attributes = array('width' => $width, 'height' => $height) + $element['#attributes'];
+  $getsize = FALSE;
+  return strtr(theme('image', $path, $alt, $title, $attributes, $getsize), array('"  ' => '" '));
+}
