Index: quote.module
===================================================================
--- quote.module (revision 2)
+++ quote.module (revision 49)
@@ -173,4 +173,10 @@
     '#tree' => TRUE
   );
+  $form['quote']['max_depth'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Maximum Quote Depth'),
+    '#description' => t('Select the quote limit at which quotes will stop nesting. 0 for no limit.'),
+    '#default_value' => _quote_variable_get('max_depth')
+  );
   $form['quote']['node_types'] = array(
     '#type' => 'checkboxes',
@@ -220,5 +226,6 @@
       'node_types' => array('blog', 'story'),
       'node_link_display' => 1,
-      'subject_required' => 1
+      'subject_required' => 1,
+      'max_depth' => 0
     );
     $variables = variable_get('quote', array());
@@ -242,5 +249,78 @@
 function _quote_filter_process($text) {
   // Thanks: function based on code from punbb.org
-  if (strstr($text, '[quote')) {
+  // quote nesting function cleaned up from http://www.nickm.org/projects/phpBB/nested_quote_limit_mod.txt
+
+  if ($num_quotes = preg_match_all ("/\[quote/si", $text, $matches)) {
+
+    $max_depth = _quote_variable_get('max_depth');
+
+    if ($max_depth > 0 && $num_quotes > $max_depth) {
+      // Define default values.
+      $curr_pos = 1;
+      $level = 0;
+      while (isset ($curr_pos) && ($curr_pos < strlen ($text))) {
+        // Find all instances of quote tags.
+        $curr_pos_cmp[0] = strpos ($text, "[quote", $curr_pos);
+        $curr_pos_cmp[1] = strpos ($text, "[/quote]", $curr_pos);
+
+        // Filter out all the empty values to determine if we should
+        // continue or bail. Also makes the array play nice with min ().
+        $curr_pos_cmp = array_filter ($curr_pos_cmp, '_quote_return_ints');
+
+        if (!empty ($curr_pos_cmp)) {
+          // Find the first tag we should deal with.
+          $curr_pos = min ($curr_pos_cmp);
+
+          // Set everything to false so things won't get messy with the loop.
+          $quote_open = null;
+          $quote_close = null;
+
+          // Find out which type of tag we're dealing with.
+          switch ($curr_pos) {
+            case $curr_pos_cmp[0]:
+              $quote_open = true;
+              break;
+            case $curr_pos_cmp[1]:
+              $quote_close = true;
+              break;
+          }
+        } else {
+          // $curr_pos_cmp array is empty so there's nothing left to do.
+          $curr_pos = null;
+        }
+
+        // If we have a tag we'll start.
+        if (isset ($curr_pos)) {
+          // If we're in front of an opening quote tag at the maxmimum
+          // level, we'll insert a [quote_kill] tag.
+          if (isset($quote_open) && $level == $max_depth) {
+            $text = substr_replace ($text, "[quote_kill", $curr_pos, 0);
+            $curr_pos += strlen ("[quote_kill");
+          }
+
+          // Depending on the type of tag we have, increase or decrease
+          // the level count and set the cursor ahead of the tag.
+          if (isset ($quote_open)) {
+            $level++;
+            $curr_pos += strlen ("[quote");
+          } else if (isset ($quote_close)) {
+            $level--;
+            $curr_pos += strlen ("[/quote]");
+          }
+
+          // Now we're positioned after a quote closing quote tag at
+          // the maximum level, so we'll insert an ending [/quote_kill] tag
+          if (isset ($quote_close) && $level == $max_depth) {
+            $text = substr_replace ($text, "[/quote_kill]", $curr_pos, 0);
+            $curr_pos += strlen ("[/quote_kill]");
+          }
+        }
+      }
+
+	  // We've now traversed all of the text and have inserted [quote_kill]
+      // tags as needed. Now all we delete the tags and everything inside.
+      $text = preg_replace ("/(\s*)\[quote_kill(.*?)\[\/quote_kill\](\s*)/si", ' ', $text);
+    }
+
     $pre = '<div class="quote-msg"><div class="quote-author">';
     $post = '</div>';
@@ -253,4 +333,11 @@
 
 /**
+ * Helper function that came with the nesting code.
+ */
+function _quote_return_ints ($var) {
+  return (is_int ($var)) ? $var : null;
+}
+
+/**
  * Helper function that returns node types.
  */
