[dev] Patch for Text::highlightQuotes()

Jason Rust jrust at rustyparts.com
Fri May 9 02:13:32 PDT 2003


In seeking to find a solution to highlighting quoted blocks for another
app I came up with the solution in the patch below.  I think it may be a
better method than the previous way because it puts only one span around
the whole quoted block instead of a span around each line.  This cuts
down on the number of times the regexp is run and the amount of html
outputted to the browser, so it should be a bit faster.  I've tested it
out with some complex forwards and it's held up fine.

-Jason

Index: Text.php
===================================================================
RCS file: /repository/horde/lib/Text.php,v
retrieving revision 1.55
diff -u -r1.55 Text.php
--- Text.php	13 Mar 2003 19:42:44 -0000	1.55
+++ Text.php	9 May 2003 06:04:59 -0000
@@ -453,11 +453,18 @@
      */
     function highlightQuotes($text, $level = 5)
     {
-        $text = implode("\n", preg_replace('|^(\s*&gt;.+)$|', '<span class="quoted1">\1</span>', explode("\n", $text)));
-        $indent = 1;
-        while (preg_match('|&gt;(\s?&gt;){' . $indent . '}|', $text)) {
-            $text = implode("\n", preg_replace('|^<span class="quoted' . ((($indent - 1) % $level) + 1) . '">(\s*&gt;(\s?&gt;){' . $indent . '}.+)$|', '<span class="quoted' . (($indent % $level) + 1) . '">\1', explode("\n", $text)));
-            $indent++;
+        // have to use global var since the class is called statically (can't use class property)
+        $GLOBALS['_tmp_maxQuoteChars'] = 0;
+        preg_replace_callback("/^\s*((&gt;\s?)+)/m", array('Text', '_countQuoteChars'), $text);
+        // go through each level of quote block and put the appropriate style around it.
+        // important to work downwards so blocks with less quote chars aren't matched 
+        // until it's their turn 
+        for ($i = $GLOBALS['_tmp_maxQuoteChars']; $i > 0; $i--) {
+            $text = preg_replace(
+                    // finds a quote block across multiple newlines
+                    "/(\n)( *(&gt;\s?)\{$i}(?! ?&gt;).*?)(\n|$)(?! *(&gt; ?)\{$i})/s", 
+                    '\1<span class="quoted' . ((($i - 1) % $level) + 1) . '">\2</span>\4', 
+                    $text);
         }
 
         return $text;
@@ -487,4 +494,16 @@
         return $text;
     }
 
+    /**
+     * Called by the preg_replace_callback function in highlightQuotes(). This method finds
+     * the maximum number of quote characters in all of the quote blocks.
+     *
+     * @param array $matches The matches from the regexp
+     */
+    function _countQuoteChars($matches) {
+        $num = count(preg_split('/&gt;\s?/', $matches[1])) - 1;
+        if ($num > $GLOBALS['_tmp_maxQuoteChars']) {
+            $GLOBALS['_tmp_maxQuoteChars'] = $num;
+        }
+    }
 }


More information about the dev mailing list