/**
  * Generate javascript highlighted source for HTML files. 
  *
  * @param string $fileName      The filename where source should be highlighted
  * @param arry   $errors        The error list for this files as highlight base
  * @param string $projectSource Path to project source directory
  * 
  * @return string
  * @see cbFDHandler::loadFile
  */
 public function getHighlightedSource($fileName, $errors, $projectSource)
 {
     ob_start();
     $code = $this->_cbFDHandler->loadFile($projectSource . DIRECTORY_SEPARATOR . $fileName);
     ini_set('highlight.comment', 'comment');
     ini_set('highlight.default', 'default');
     ini_set('highlight.keyword', 'keyword');
     ini_set('highlight.string', 'string');
     ini_set('highlight.html', 'html');
     $code = highlight_string($code, true);
     $code = str_replace(array('&nbsp;', '&amp;', '<br />', '<span style="color: '), array(' ', '&#38;', "\n", '<span class="'), substr($code, 33, -15));
     $code = trim($code);
     $code = str_replace("\r", "", $code);
     $lines = explode("\n", $code);
     $previous = false;
     $openTag = 0;
     // Output Listing
     echo " <ol class=\"code\">\n";
     foreach ($lines as $key => $line) {
         if (substr($line, 0, 7) == '</span>') {
             $previous = false;
             $line = substr($line, 7);
         }
         if (empty($line)) {
             $line = '&#160;';
         }
         if ($previous) {
             $line = "<span class=\"{$previous}\">" . $line;
         }
         // Set Previous Style
         if (strpos($line, '<span') !== false) {
             switch (substr($line, strrpos($line, '<span') + 13, 1)) {
                 case 'c':
                     $previous = 'comment';
                     break;
                 case 'd':
                     $previous = 'default';
                     break;
                 case 'k':
                     $previous = 'keyword';
                     break;
                 case 's':
                     $previous = 'string';
                     break;
             }
         }
         // Unset Previous Style Unless Span Continues
         if (substr($line, -7) == '</span>') {
             $previous = false;
         } elseif ($previous) {
             $line .= '</span>';
         }
         $num = $key + 1;
         $classname = 'white';
         $classnameEven = 'even';
         $prefix = '';
         $suffix = '';
         $max = 0;
         $min = count($lines);
         $amountOfErr = 0;
         foreach ($errors as $error) {
             if ($error['line'] <= $num && $error['to-line'] >= $num) {
                 if ($max <= (int) $error['to-line']) {
                     $max = (int) $error['to-line'];
                 }
                 if ($min >= (int) $error['line']) {
                     $min = (int) $error['line'];
                 }
                 $classnameEven = 'transparent';
                 $classname = 'transparent';
                 if ((int) $error['line'] == (int) $num) {
                     $prefix = sprintf('<li id="line-%s-%s" class="%s" ><ul>', $error['line'], $error['to-line'], $openTag > 0 ? 'transparent' : ($prefix != '' ? 'moreErrors' : $error['source']));
                 }
                 if ((int) $error['to-line'] == (int) $num) {
                     if ($min != $max && $suffix != '') {
                         $amountOfErr++;
                     }
                     $suffix = "</ul></li>";
                 }
             }
         }
         if ($prefix != '') {
             $openTag++;
         }
         if ($num < $max && $min == $num || $openTag == 0) {
             $suffix = '';
         }
         if ($suffix != '' && $openTag > 0) {
             $openTag--;
         }
         if ($amountOfErr > 0 && $suffix != '' && $openTag > 0) {
             $openTag--;
             $suffix .= '</ul></li>';
         }
         echo sprintf('%s<li id="line-%d" class="%s"><a name="line-%d"></a><code>%s</code></li>%s' . "\n", $prefix, $num, $key % 2 ? $classnameEven : $classname, $num, $line, $suffix);
     }
     echo "</ol>\n";
     $contents = ob_get_contents();
     ob_end_clean();
     return $contents;
 }
 /**
  * Main execute function for PHP_CodeBrowser.
  *
  * Following steps are resolved:
  * 1. Clean-up output directory
  * 2. Merge xml log files
  * 3. Generate cbXML file via errorlist from plugins
  * 4. Save the cbErrorList as XML file
  * 5. Generate HTML output from cbXML
  * 6. Copy ressources (css, js, images) from template directory to output
  *
  * @return void
  */
 public function run()
 {
     // init needed classes
     $cbFDHandler = new CbFDHandler();
     $cbXMLHandler = new CbXMLHandler($cbFDHandler);
     $cbJSGenerator = new CbJSGenerator($cbFDHandler);
     $cbErrorHandler = new CbErrorHandler($cbXMLHandler, $this->_projectSourceDir);
     // clear and create output directory
     $cbFDHandler->deleteDirectory($this->_htmlOutputDir);
     $cbFDHandler->createDirectory($this->_htmlOutputDir);
     // merge xml files
     $cbXMLHandler->addDirectory($this->_logDir);
     $mergedDOMDoc = $cbXMLHandler->mergeFiles();
     // conversion of XML file cc to cb format
     $list = array();
     foreach ($this->_registeredErrorPlugins as $className) {
         $plugin = new $className($this->_projectSourceDir, $cbXMLHandler);
         $plugin->setXML($mergedDOMDoc);
         $list = array_merge_recursive($list, $plugin->parseXMLError());
     }
     // construct the error list
     $cbXMLGenerator = new CbXMLGenerator($cbFDHandler);
     $cbXMLGenerator->setXMLName($this->_xmlFile);
     $cbXMLGenerator->saveCbXML($cbXMLGenerator->generateXMLFromErrors($list));
     // get cb error list, filter common source path
     $errors = $cbErrorHandler->getFilesWithErrors($this->_xmlFile);
     $errors = $cbErrorHandler->replaceCommonSourcePath($errors);
     // parse source directory
     $errors = $cbErrorHandler->parseSourceDirectory($errors);
     sort($errors);
     // set project source dir from error list
     if (!isset($this->_projectSourceDir)) {
         $this->setProjectSourceDir($cbErrorHandler->getCommonSourcePath($errors));
     }
     $html = new CbHTMLGenerator($cbFDHandler, $cbErrorHandler, $cbJSGenerator);
     $html->setTemplateDir(PHPCB_TEMPLATE_DIR);
     $html->setOutputDir($this->_htmlOutputDir);
     if (!empty($errors)) {
         $html->generateViewFlat($errors);
         $html->generateViewTree($errors);
         $html->generateViewReview($errors, $this->_xmlFile, $this->_projectSourceDir);
     }
     // copy needed resources like css, js, images
     $html->copyRessourceFolders(!empty($errors));
 }