includes/wikiformat.php
changeset 1027 98c052fc3337
parent 801 eb8b23f11744
child 1031 8a4b75e73137
--- a/includes/wikiformat.php	Sun Jun 21 00:16:21 2009 -0400
+++ b/includes/wikiformat.php	Sun Jun 21 00:20:32 2009 -0400
@@ -13,633 +13,312 @@
  */
 
 /**
- * Parse structured wiki text and render into arbitrary formats such as XHTML.
- *
- * PHP versions 4 and 5
+ * Framework for parsing and rendering various formats. In Enano by default, this is MediaWiki-style wikitext being
+ * rendered to XHTML, but this framework allows other formats to be supported as well.
  *
- * @category   Text
- * @package    Text_Wiki
- * @author     Paul M. Jones <pmjones@php.net>
- * @license    http://www.gnu.org/licenses/lgpl.html
- * @version    CVS: $Id: Wiki.php,v 1.44 2006/03/02 04:04:59 justinpatrin Exp $
- * @link       http://wiki.ciaweb.net/yawiki/index.php?area=Text_Wiki
- *
- * This code was modified for use in Enano. The Text_Wiki engine is licensed
- * under the GNU Lesser General Public License; see
- * http://www.gnu.org/licenses/lgpl.html for details.
- *
+ * @package Enano
+ * @subpackage Content
+ * @author Dan Fuhry <dan@enanocms.org>
+ * @copyright (C) 2009 Enano CMS Project
+ * @license GNU General Public License, version 2 or later <http://www.gnu.org/licenses/gpl-2.0.html>
  */
 
-require_once ENANO_ROOT.'/includes/wikiengine/Parse.php';
-require_once ENANO_ROOT.'/includes/wikiengine/Render.php';
-
-class Text_Wiki {
-
-  var $rules = array(
-        'Prefilter',
-        'Delimiter',
-        'Code',
-        'Function',
-        'Html',
-        'Raw',
-        'Include',
-        'Embed',
-        'Anchor',
-        'Heading',
-        'Toc',
-        'Horiz',
-        'Break',
-        'Blockquote',
-        'List',
-        'Deflist',
-        'Table',
-        'Image',
-        'Phplookup',
-        'Center',
-        'Newline',
-        'Paragraph',
-        'Url',
-        'Freelink',
-        'Interwiki',
-        'Wikilink',
-        'Colortext',
-        'Strong',
-        'Bold',
-        'Emphasis',
-        'Italic',
-        'Underline',
-        'Tt',
-        'Superscript',
-        'Subscript',
-        'Revise',
-        'Tighten'
+class Carpenter
+{
+  /**
+   * Parser token
+   * @const string
+   */
+  
+  const PARSER_TOKEN = "\xFF";
+  
+  /**
+   * Parsing engine
+   * @var string
+   */
+  
+  private $parser = 'mediawiki';
+  
+  /**
+   * Rendering engine
+   * @var string
+   */
+  
+  private $renderer = 'xhtml';
+  
+  /**
+   * Rendering flags
+   */
+  
+  public $flags = RENDER_WIKI_DEFAULT;
+  
+  /**
+   * List of rendering rules
+   * @var array
+   */
+  
+  private $rules = array(
+      'lang',
+      'templates',
+      'tables',
+      'heading',
+      // note: can't be named list ("list" is a PHP language construct)
+      'multilist',
+      'bold',
+      'italic',
+      'underline',
+      'externalwithtext',
+      'externalnotext',
+      'image',
+      'internallink',
+      'paragraph'
     );
-
-    var $disable = array(
-        'Html',
-        'Include',
-        'Embed',
-        'Tighten',
-        'Image',
-        'Wikilink'
-    );
-
-    var $parseConf = array();
-
-    var $renderConf = array(
-        'Docbook' => array(),
-        'Latex' => array(),
-        'Pdf' => array(),
-        'Plain' => array(),
-        'Rtf' => array(),
-        'Xhtml' => array()
-    );
-
-    var $formatConf = array(
-        'Docbook' => array(),
-        'Latex' => array(),
-        'Pdf' => array(),
-        'Plain' => array(),
-        'Rtf' => array(),
-        'Xhtml' => array()
-    );
-    var $delim = "\xFF";
-    var $tokens = array();
-    var $_countRulesTokens = array();
-    var $source = '';
-    var $parseObj = array();
-    var $renderObj = array();
-    var $formatObj = array();
-    var $path = array(
-        'parse' => array(),
-        'render' => array()
-    );
-    var $_dirSep = DIRECTORY_SEPARATOR;
-    function Text_Wiki($rules = null)
+  
+  /**
+   * List of render hooks
+   * @var array
+   */
+  
+  private $hooks = array();
+  
+  /* private $rules = array('prefilter', 'delimiter', 'code', 'function', 'html', 'raw', 'include', 'embed', 'anchor',
+           'heading', 'toc', 'horiz', 'break', 'blockquote', 'list', 'deflist', 'table', 'image',
+           'phplookup', 'center', 'newline', 'paragraph', 'url', 'freelink', 'interwiki',
+           'wikilink', 'colortext', 'strong', 'bold', 'emphasis', 'italic', 'underline', 'tt',
+           'superscript', 'subscript', 'revise', 'tighten'); */
+  
+  /**
+   * Render the text!
+   * @param string Text to render
+   * @return string
+   */
+  
+  public function render($text)
+  {
+    $parser_class = "Carpenter_Parse_" . ucwords($this->parser);
+    $renderer_class = "Carpenter_Render_" . ucwords($this->renderer);
+    
+    // include files, if we haven't already
+    if ( !class_exists($parser_class) )
+    {
+      require_once( ENANO_ROOT . "/includes/wikiengine/parse_{$this->parser}.php");
+    }
+    
+    if ( !class_exists($renderer_class) )
     {
-        if (is_array($rules)) {
-            $this->rules = $rules;
+      require_once( ENANO_ROOT . "/includes/wikiengine/render_{$this->renderer}.php");
+    }
+    
+    $parser = new $parser_class;
+    $renderer = new $renderer_class;
+    
+    // run prehooks
+    foreach ( $this->hooks as $hook )
+    {
+      if ( $hook['when'] === PO_FIRST )
+      {
+        $text = call_user_func($hook['callback'], $text);
+        if ( !is_string($text) || empty($text) )
+        {
+          trigger_error("Hook returned empty/invalid text: " . print_r($hook['callback'], true), E_USER_WARNING);
+          // *sigh*
+          $text = '';
         }
-        
-        global $plugins;
-        // This code can be run from the installer, so in some cases $plugins
-        // isn't initted. (Bug in 1.1.2, fixed for 1.1.3)
-        if ( is_object($plugins) )
+      }
+    }
+    
+    // perform render
+    foreach ( $this->rules as $rule )
+    {
+      // run prehooks
+      foreach ( $this->hooks as $hook )
+      {
+        if ( $hook['when'] === PO_BEFORE && $hook['rule'] === $rule )
         {
-          $code = $plugins->setHook('text_wiki_construct');
-          foreach ( $code as $cmd )
+          $text = call_user_func($hook['callback'], $text);
+          if ( !is_string($text) || empty($text) )
           {
-              eval($cmd);
+            trigger_error("Hook returned empty/invalid text: " . print_r($hook['callback'], true), E_USER_WARNING);
+            // *sigh*
+            $text = '';
           }
         }
-
-        $this->addPath(
-            'parse',
-            $this->fixPath(ENANO_ROOT) . 'includes/wikiengine/Parse/Default/'
-        );
-        $this->addPath(
-            'render',
-            $this->fixPath(ENANO_ROOT) . 'includes/wikiengine/Render/'
-        );
-
-    }
-
-    public static function singleton($parser = 'Default', $rules = null)
-    {
-        static $only = array();
-        if (!isset($only[$parser])) {
-            $ret = Text_Wiki::factory($parser, $rules);
-            if (!$ret) {
-                return $ret;
-            }
-            $only[$parser] =& $ret;
-        }
-        return $only[$parser];
-    }
-
-    public static function factory($parser = 'Default', $rules = null)
-    {
-        $d=getcwd();
-        chdir(ENANO_ROOT);
-        
-        $class = 'Text_Wiki_' . $parser;
-        $c2 = $parser;
-        $file = ENANO_ROOT . '/includes/wikiengine/' . str_replace('_', '/', $c2).'.php';
-        if (!class_exists($class)) {
-            $fp = @fopen($file, 'r', true);
-            if ($fp === false) {
-                die_semicritical('Wiki formatting engine error', '<p>Could not find file '.$file.' in include_path</p>');
-            }
-            fclose($fp);
-            include_once($file);
-            if (!class_exists($class)) {
-                die_semicritical('Wiki formatting engine error', '<p>Class '.$class.' does not exist after including '.$file.'</p>');
-            }
-        }
-        
-        chdir($d);
-
-        $obj = new $class($rules);
-        return $obj;
-    }
-
-    function setParseConf($rule, $arg1, $arg2 = null)
-    {
-        $rule = ucwords(strtolower($rule));
-
-        if (! isset($this->parseConf[$rule])) {
-            $this->parseConf[$rule] = array();
-        }
-
-                                if (is_array($arg1)) {
-            $this->parseConf[$rule] = $arg1;
-        } else {
-            $this->parseConf[$rule][$arg1] = $arg2;
-        }
-    }
-
-    function getParseConf($rule, $key = null)
-    {
-        $rule = ucwords(strtolower($rule));
-
-                if (! isset($this->parseConf[$rule])) {
-            return null;
-        }
-
-                if (is_null($key)) {
-            return $this->parseConf[$rule];
-        }
-
-                if (isset($this->parseConf[$rule][$key])) {
-                        return $this->parseConf[$rule][$key];
-        } else {
-                        return null;
-        }
-    }
-
-    function setRenderConf($format, $rule, $arg1, $arg2 = null)
-    {
-        $format = ucwords(strtolower($format));
-        $rule = ucwords(strtolower($rule));
-
-        if (! isset($this->renderConf[$format])) {
-            $this->renderConf[$format] = array();
-        }
-
-        if (! isset($this->renderConf[$format][$rule])) {
-            $this->renderConf[$format][$rule] = array();
-        }
-
-                                if (is_array($arg1)) {
-            $this->renderConf[$format][$rule] = $arg1;
-        } else {
-            $this->renderConf[$format][$rule][$arg1] = $arg2;
-        }
-    }
-
-    function getRenderConf($format, $rule, $key = null)
-    {
-        $format = ucwords(strtolower($format));
-        $rule = ucwords(strtolower($rule));
-
-        if (! isset($this->renderConf[$format]) ||
-            ! isset($this->renderConf[$format][$rule])) {
-          return null;
-        }
-
-        if (is_null($key)) {
-          return $this->renderConf[$format][$rule];
-        }
-
-        if (isset($this->renderConf[$format][$rule][$key])) {
-          return $this->renderConf[$format][$rule][$key];
-        } else {
-          return null;
-        }
-
-    }
-
-    function setFormatConf($format, $arg1, $arg2 = null)
-    {
-      if (! is_array($this->formatConf[$format])) {
-        $this->formatConf[$format] = array();
       }
-
-      if (is_array($arg1)) {
-        $this->formatConf[$format] = $arg1;
-      } else {
-        $this->formatConf[$format][$arg1] = $arg2;
-      }
-    }
-
-    function getFormatConf($format, $key = null)
-    {
-      if (! isset($this->formatConf[$format])) {
-        return null;
-      }
-
-      if (is_null($key)) {
-        return $this->formatConf[$format];
-      }
-
-      if (isset($this->formatConf[$format][$key])) {
-        return $this->formatConf[$format][$key];
-      } else {
-        return null;
-      }
-    }
-
-    function insertRule($name, $tgt = null)
-    {
-      $name = ucwords(strtolower($name));
-      if (! is_null($tgt)) {
-        $tgt = ucwords(strtolower($tgt));
-      }
-      if (in_array($name, $this->rules)) {
-        return null;
-      }
-
-      if (! is_null($tgt) && $tgt != '' &&
-        ! in_array($tgt, $this->rules)) {
-        return false;
-      }
-
-      if (is_null($tgt)) {
-        $this->rules[] = $name;
-        return true;
-      }
-
-      if ($tgt == '') {
-        array_unshift($this->rules, $name);
-        return true;
-      }
-
-      $tmp = $this->rules;
-      $this->rules = array();
-
-      foreach ($tmp as $val) {
-        $this->rules[] = $val;
-        if ($val == $tgt) {
-          $this->rules[] = $name;
-        }
-      }
-
-      return true;
-    }
-
-    function deleteRule($name)
-    {
-      $name = ucwords(strtolower($name));
-      $key = array_search($name, $this->rules);
-      if ($key !== false) {
-        unset($this->rules[$key]);
-      }
-    }
-
-    function changeRule($old, $new)
-    {
-      $old = ucwords(strtolower($old));
-      $new = ucwords(strtolower($new));
-      $key = array_search($old, $this->rules);
-      if ($key !== false) {
-        $this->deleteRule($new);
-        $this->rules[$key] = $new;
-      }
-    }
-
-    function enableRule($name)
-    {
-      $name = ucwords(strtolower($name));
-      $key = array_search($name, $this->disable);
-      if ($key !== false) {
-        unset($this->disable[$key]);
-      }
-    }
-
-    function disableRule($name)
-    {
-      $name = ucwords(strtolower($name));
-      $key = array_search($name, $this->disable);
-      if ($key === false) {
-        $this->disable[] = $name;
-      }
-    }
-
-    function transform($text, $format = 'Xhtml')
-    {
-      $this->parse($text);
-      return $this->render($format);
-    }
-
-    function parse($text)
-    {
-      $this->source = $text;
-
-      $this->tokens = array();
-      $this->_countRulesTokens = array();
-
-      foreach ($this->rules as $name) {
-        if (! in_array($name, $this->disable)) {
-          $this->loadParseObj($name);
-
-          if (is_object($this->parseObj[$name])) {
-            $this->parseObj[$name]->parse();
+      
+      // execute rule
+      $text = $this->perform_render_step($text, $rule, $parser, $renderer);
+      
+      // run posthooks
+      foreach ( $this->hooks as $hook )
+      {
+        if ( $hook['when'] === PO_AFTER && $hook['rule'] === $rule )
+        {
+          $text = call_user_func($hook['callback'], $text);
+          if ( !is_string($text) || empty($text) )
+          {
+            trigger_error("Hook returned empty/invalid text: " . print_r($hook['callback'], true), E_USER_WARNING);
+            // *sigh*
+            $text = '';
           }
-          // For debugging
-          // echo('<p>' . $name . ':</p><pre>'.htmlspecialchars($this->source).'</pre>');
         }
       }
     }
-
-    function render($format = 'Xhtml')
+    
+    // run posthooks
+    foreach ( $this->hooks as $hook )
     {
-      $format = ucwords(strtolower($format));
-
-      $output = '';
-
-      $in_delim = false;
-
-      $key = '';
-
-      $result = $this->loadFormatObj($format);
-      if ($this->isError($result)) {
-        return $result;
-      }
-      
-      if (is_object($this->formatObj[$format])) {
-        $output .= $this->formatObj[$format]->pre();
-      }
-
-      foreach (array_keys($this->_countRulesTokens) as $rule) {
-        $this->loadRenderObj($format, $rule);
-      }
-      
-      $k = strlen($this->source);
-      for ($i = 0; $i < $k; $i++) {
-
-        $char = $this->source{$i};
-
-        if ($in_delim) {
-
-          if ($char == $this->delim) {
-
-            $key = (int)$key;
-            $rule = $this->tokens[$key][0];
-            $opts = $this->tokens[$key][1];
-            $output .= $this->renderObj[$rule]->token($opts);
-            $in_delim = false;
-
-          } else {
-
-            $key .= $char;
-
-          }
-
-        } else {
-
-          if ($char == $this->delim) {
-            $key = '';
-            $in_delim = true;
-          } else {
-            $output .= $char;
-          }
+      if ( $hook['when'] === PO_LAST )
+      {
+        $text = call_user_func($hook['callback'], $text);
+        if ( !is_string($text) || empty($text) )
+        {
+          trigger_error("Hook returned empty/invalid text: " . print_r($hook['callback'], true), E_USER_WARNING);
+          // *sigh*
+          $text = '';
         }
       }
-
-      if (is_object($this->formatObj[$format])) {
-        $output .= $this->formatObj[$format]->post();
-      }
-
-      return $output;
     }
-
-    function getSource()
-    {
-      return $this->source;
-    }
-
-    function getTokens($rules = null)
-    {
-        if (is_null($rules)) {
-            return $this->tokens;
-        } else {
-            settype($rules, 'array');
-            $result = array();
-            foreach ($this->tokens as $key => $val) {
-                if (in_array($val[0], $rules)) {
-                    $result[$key] = $val;
-                }
-            }
-            return $result;
-        }
-    }
-
-    function addToken($rule, $options = array(), $id_only = false)
+    
+    return (( defined('ENANO_DEBUG') && isset($_GET['parserdebug']) ) ? '<pre>' . htmlspecialchars($text) . '</pre>' : $text) . "\n\n";
+  }
+  
+  /**
+   * Performs a step in the rendering process.
+   * @param string Text to render
+   * @param string Rule to execute
+   * @param object Parser instance
+   * @param object Renderer instance
+   * @return string
+   * @access private
+   */
+  
+  private function perform_render_step($text, $rule, $parser, $renderer)
+  {
+    // First look for a direct function
+    if ( function_exists("parser_{$this->parser}_{$this->renderer}_{$rule}") )
     {
-                                static $id;
-        if (! isset($id)) {
-            $id = 0;
-        } else {
-            $id ++;
-        }
-
-                settype($options, 'array');
-
-                $this->tokens[$id] = array(
-            0 => $rule,
-            1 => $options
-        );
-        if (!isset($this->_countRulesTokens[$rule])) {
-            $this->_countRulesTokens[$rule] = 1;
-        } else {
-            ++$this->_countRulesTokens[$rule];
-        }
-
-                if ($id_only) {
-                        return $id;
-        } else {
-                        return $this->delim . $id . $this->delim;
-        }
+      return call_user_func("parser_{$this->parser}_{$this->renderer}_{$rule}", $text, $this->flags);
     }
-
-    function setToken($id, $rule, $options = array())
+    
+    // We don't have that, so start looking for other ways or means of doing this
+    if ( method_exists($parser, $rule) && method_exists($renderer, $rule) )
+    {
+      // Both the parser and render have callbacks they want to use.
+      $pieces = $parser->$rule($text);
+      $text = call_user_func(array($renderer, $rule), $text, $pieces);
+    }
+    else if ( method_exists($parser, $rule) && !method_exists($renderer, $rule) && isset($renderer->rules[$rule]) )
     {
-        $oldRule = $this->tokens[$id][0];
-                $this->tokens[$id] = array(
-            0 => $rule,
-            1 => $options
-        );
-        if ($rule != $oldRule) {
-            if (!($this->_countRulesTokens[$oldRule]--)) {
-                unset($this->_countRulesTokens[$oldRule]);
-            }
-            if (!isset($this->_countRulesTokens[$rule])) {
-                $this->_countRulesTokens[$rule] = 1;
-            } else {
-                ++$this->_countRulesTokens[$rule];
-            }
-        }
+      // The parser has a callback, but the renderer does not
+      $pieces = $parser->$rule($text);
+      $text = $this->generic_render($text, $pieces, $renderer->rules[$rule]);
     }
-
-    function loadParseObj($rule)
+    else if ( !method_exists($parser, $rule) && isset($parser->rules[$rule]) && method_exists($renderer, $rule) )
     {
-        $rule = ucwords(strtolower($rule));
-        $file = $rule . '.php';
-        $class = "Text_Wiki_Parse_$rule";
-
-        if (! class_exists($class)) {
-            $loc = $this->findFile('parse', $file);
-            if ($loc) {
-                                include_once $loc;
-            } else {
-                                $this->parseObj[$rule] = null;
-                                return $this->error(
-                    "Parse rule '$rule' not found"
-                );
-            }
-        }
-
-        $this->parseObj[$rule] = new $class($this);
-
+      // The parser has no callback, but the renderer does
+      $text = preg_replace_callback($parser->rules[$rule], array($renderer, $rule), $text);
+    }
+    else if ( isset($parser->rules[$rule]) && isset($renderer->rules[$rule]) )
+    {
+      // This is a straight-up regex only rule
+      $text = preg_replace($parser->rules[$rule], $renderer->rules[$rule], $text);
+    }
+    else
+    {
+      // Either the renderer or parser does not support this rule, ignore it
     }
-
-    function loadRenderObj($format, $rule)
-    {
-        $format = ucwords(strtolower($format));
-        $rule = ucwords(strtolower($rule));
-        $file = "$format/$rule.php";
-        $class = "Text_Wiki_Render_$format" . "_$rule";
-
-        if (! class_exists($class)) {
-                        $loc = $this->findFile('render', $file);
-            if ($loc) {
-                                include_once $loc;
-            } else {
-                return $this->error(
-                    "Render rule '$rule' in format '$format' not found"
-                );
-            }
-        }
-
-        $this->renderObj[$rule] = new $class($this);
-    }
-
-    function loadFormatObj($format)
-    {
-        $format = ucwords(strtolower($format));
-        $file = $format . '.php';
-        $class = "Text_Wiki_Render_$format";
-
-        if (! class_exists($class)) {
-            $loc = $this->findFile('render', $file);
-            if ($loc) {
-                include_once $loc;
-            } else {
-                return $this->error(
-                    "Rendering format class '$class' not found"
-                );
-            }
-        }
-
-        $this->formatObj[$format] = new $class($this);
-    }
-
-    function addPath($type, $dir)
+    
+    return $text;
+  }
+  
+  /**
+   * Generic renderer
+   * @access protected
+   */
+  
+  protected function generic_render($text, $pieces, $rule)
+  {
+    foreach ( $pieces as $i => $piece )
     {
-        $dir = $this->fixPath($dir);
-        if (! isset($this->path[$type])) {
-            $this->path[$type] = array($dir);
-        } else {
-            array_unshift($this->path[$type], $dir);
+      $replacement = $rule;
+      
+      // if the piece is an array, replace $1, $2, etc. in the rule with each value in the piece
+      if ( is_array($piece) )
+      {
+        $j = 0;
+        foreach ( $piece as $part )
+        {
+          $j++;
+          $replacement = str_replace(array("\\$j", "\${$j}"), $part, $replacement);
         }
+      }
+      // else, just replace \\1 or $1 in the rule with the piece
+      else
+      {
+        $replacement = str_replace(array("\\1", "\$1"), $piece, $replacement);
+      }
+      
+      $text = str_replace(self::generate_token($i), $replacement, $text);
     }
-
-    function getPath($type = null)
-    {
-        if (is_null($type)) {
-            return $this->path;
-        } elseif (! isset($this->path[$type])) {
-            return array();
-        } else {
-            return $this->path[$type];
-        }
-    }
-
-    function findFile($type, $file)
+    
+    return $text;
+  }
+  
+  /**
+   * Add a hook into the parser.
+   * @param callback Function to call
+   * @param int PO_* constant
+   * @param string If PO_{BEFORE,AFTER} used, rule
+   */
+  
+  public function hook($callback, $when, $rule = false)
+  {
+    if ( !is_int($when) )
+      return null;
+    if ( ($when == PO_BEFORE || $when == PO_AFTER) && !is_string($rule) )
+      return null;
+    if ( ( is_string($callback) && !function_exists($callback) ) || ( is_array($callback) && !method_exists($callback[0], $callback[1]) ) || ( !is_string($callback) && !is_array($callback) ) )
     {
-      $set = $this->getPath($type);
-
-      foreach ($set as $path) {
-            $fullname = $path . $file;
-            if (file_exists($fullname) && is_readable($fullname)) {
-                return $fullname;
-            }
-        }
-
-      return false;
+      trigger_error("Attempt to hook with undefined function/method " . print_r($callback, true), E_USER_ERROR);
+      return null;
     }
-
-    function fixPath($path)
+    
+    $this->hooks[] = array(
+        'callback' => $callback,
+        'when'     => $when,
+        'rule'     => $rule
+      );
+  }
+  
+  /**
+   * Generate a token
+   * @param int Token index
+   * @return string
+   * @static
+   */
+  
+  public static function generate_token($i)
+  {
+    return self::PARSER_TOKEN . $i . self::PARSER_TOKEN;
+  }
+  
+  /**
+   * Tokenize string
+   * @param string
+   * @param array Matches
+   * @return string
+   * @static
+   */
+  
+  public static function tokenize($text, $matches)
+  {
+    $matches = array_values($matches);
+    foreach ( $matches as $i => $match )
     {
-        $len = strlen($this->_dirSep);
-
-        if (! empty($path) &&
-            substr($path, -1 * $len, $len) != $this->_dirSep)    {
-            return $path . $this->_dirSep;
-        } else {
-            return $path;
-        }
+      $text = str_replace_once($match, self::generate_token($i), $text);
     }
-
-    function &error($message)
-    {
-        die($message);
-    }
-
-    function isError(&$obj)
-    {
-        return ( @get_class($obj) == 'PEAR_Error' );
-    }
+    
+    return $text;
+  }
 }
 
-?>