Index: tableofcontents.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/tableofcontents/tableofcontents.module,v
retrieving revision 1.2.4.2.2.2.2.9
diff -u -r1.2.4.2.2.2.2.9 tableofcontents.module
--- tableofcontents.module	17 Oct 2008 18:48:19 -0000	1.2.4.2.2.2.2.9
+++ tableofcontents.module	18 Oct 2008 00:15:19 -0000
@@ -189,43 +189,8 @@
             'anchor' => $anchor)
           );
         }
-        // Build HTML for the Table of Contents
-        $toc_html = "<div class=\"toc\">\n<div class=\"toc-title\">" .
-        $toc_options["title"] . " [<a href=\"#\" class=\"toc-toggle\">" . t('hide') . "</a>]</div>\n<div class=\"toc-list\">\n<" .
-        $toc_options["list"] . ">\n";
-
-        $depth = $toc_options["minlevel"];
-        foreach ($toc as $index=>$title) {
-
-          // process nested lists
-          $curdepth = $title['level'];
-          if ($curdepth <= $toc_options["maxlevel"]) {
-            // Close list items but not before no items have been added
-            if ($curdepth == $depth && $index != 0) $toc_html .= "</li>\n";
-            // Be sure to deal with skipping between non-adjacent h levels
-            while ($curdepth != $depth) {
-              if ($curdepth > $depth) {
-                $toc_html .= "\n<" . $toc_options["list"] . ">\n";
-                $depth++;
-              }
-              else if ($curdepth < $depth) {
-                $toc_html .= "</li>\n</" . $toc_options["list"] . ">\n";
-                $depth--;
-                if ($curdepth == $depth) $toc_html .= "</li>\n";
-              }
-            }
-
-            // insert the li element
-            $toc_html .= "\t<li><a href=\"#".$title['anchor']."\">".$title['heading']."</a>";
-          }
-        }
-        // Did we recurse back out? If not, close open lists.
-        while ($depth > $toc_options["minlevel"]) {
-          $toc_html .= "</li>\n</" . $toc_options["list"] . ">\n";
-          $depth = $depth -1;
-        }
-        $toc_html .= "</li>\n";
         
+        // If attachments are enabled, prepare the $files variable
         if ($toc_options["attachments"] == "yes") {
           $nid = explode('/', $_GET['q']);
           if (isset($nid[0]) && $nid[0] == 'node' && isset($nid[1]) && is_numeric($nid[1])) {
@@ -233,25 +198,12 @@
             $node = node_load($nid);
           }
           if (!empty($node->files)) {
-            $toc_html .= '<li><a href="#attachments">' . t("Attachments") . "</a>";
-            $toc_html .= "<" . $toc_options["list"] . ">";
-            foreach($node->files as $file) {
-              if ($file->list && !$file->remove) {
-                $toc_html .= '<li>';
-
-                // If there is no function providing phptemplate_file_icon in template.php or similar
-                // then this will fail gracefully.
-                $toc_html .= theme('file_icon', $file);
-
-                $file_href = $href = file_create_url((strpos($file->fid, 'upload') === FALSE ? $file->filepath : file_create_filename($file->filename, file_create_path())));
-                $file_text = $file->description ? $file->description : $file->filename;
-
-                $toc_html .= l($file_text, $file_href) . "</li>\n";
-              }
-            }
+            $files = $node->files;
           }
         }
-        $toc_html .= "</".$toc_options["list"].">\n</div>\n</div>";
+        
+        // Build HTML for the Table of Contents.
+        $toc_html = theme('tableofcontents_toc', $toc, $toc_options, $files);
 
         // replace all tableofcontents markers with generated ToC html
         return preg_replace('!<\!-- ?tableofcontents(.*)-->!', $toc_html, $text);
@@ -270,8 +222,7 @@
  * with attachments, but since this only occurs during editing or creating the load should be
  * pretty minimal.
  */
-
-function tableofcontents_nodeapi (&$node, $op, $a3 = NULL, $a4 = NULL) {
+function tableofcontents_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
   switch ($op) {
     case 'prepare':
       if (isset($node->files)) {
@@ -282,3 +233,95 @@
       break;
   }
 }
+
+/**
+ * Implementation of hook_theme
+ * @return
+ *   Array of theme hooks this module implements.
+ */
+function tableofcontents_theme() {
+  return array(
+    'tableofcontents_toc' => array(
+      'arguments' => array(
+        'toc' => NULL,
+        'options' => NULL,
+        'files' => array(),
+      ),
+    ),
+  );
+}
+
+/**
+ * Theme the output of a table of contents.
+ * 
+ * @param $toc
+ *   Array containing the table of contents.
+ * @param $options
+ *   The array of options for the table of contents.
+ * @param $files
+ *   Optional array of files to render in the table of contents.
+ * @return
+ *   Rendered HTML to be displayed.
+ */
+function theme_tableofcontents_toc($toc, $options, $files = array()) {
+  $output = "<div class=\"toc\">\n<div class=\"toc-title\">" .
+  $options["title"] . " [<a href=\"#\" class=\"toc-toggle\">" . t('hide') . "</a>]</div>\n<div class=\"toc-list\">\n<" .
+  $options["list"] . ">\n";
+
+  $depth = $options["minlevel"];
+  foreach ($toc as $index=>$title) {
+
+    // Process nested lists.
+    $curdepth = $title['level'];
+    if ($curdepth <= $options["maxlevel"]) {
+      // Close list items but not before no items have been added.
+      if ($curdepth == $depth && $index != 0) $output .= "</li>\n";
+      // Be sure to deal with skipping between non-adjacent h levels.
+      while ($curdepth != $depth) {
+        if ($curdepth > $depth) {
+          $output .= "\n<" . $options["list"] . ">\n";
+          $depth++;
+        }
+        else if ($curdepth < $depth) {
+          $output .= "</li>\n</" . $options["list"] . ">\n";
+          $depth--;
+          if ($curdepth == $depth) $output .= "</li>\n";
+        }
+      }
+
+      // insert the li element
+      $output .= "\t<li><a href=\"#".$title['anchor']."\">".$title['heading']."</a>";
+    }
+  }
+  // Did we recurse back out? If not, close open lists.
+  while ($depth > $options["minlevel"]) {
+    $output .= "</li>\n</" . $options["list"] . ">\n";
+    $depth = $depth - 1;
+  }
+  $output .= "</li>\n";
+  
+  // If we've been passed an array of files, add them to the table of contents.
+  if (!empty($files)) {
+    $output .= '<li><a href="#attachments">' . t("Attachments") . "</a>";
+    $output .= "<" . $options["list"] . ">";
+    foreach($files as $file) {
+      if ($file->list && !$file->remove) {
+        $output .= '<li>';
+
+        // If there is no function providing phptemplate_file_icon in
+        // template.php or similar then this will fail gracefully.
+        $output .= theme('file_icon', $file);
+
+        $file_href = $href = file_create_url((strpos($file->fid, 'upload') === FALSE ? $file->filepath : file_create_filename($file->filename, file_create_path())));
+        $file_text = $file->description ? $file->description : $file->filename;
+
+        $output .= l($file_text, $file_href) . "</li>\n";
+      }
+    }
+    $output .= "</" . $options['list'] . "></li>\n";
+  }
+  
+  $output .= "</".$options["list"].">\n</div>\n</div>";
+  
+  return $output;
+}
