home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / Text / Highlighter / Renderer / Html.php < prev    next >
Encoding:
PHP Script  |  2008-07-02  |  13.6 KB  |  463 lines

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3. /**
  4.  * HTML renderer
  5.  *
  6.  * PHP versions 4 and 5
  7.  *
  8.  * LICENSE: This source file is subject to version 3.0 of the PHP license
  9.  * that is available through the world-wide-web at the following URI:
  10.  * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
  11.  * the PHP License and are unable to obtain it through the web, please
  12.  * send a note to license@php.net so we can mail you a copy immediately.
  13.  *
  14.  * @category   Text
  15.  * @package    Text_Highlighter
  16.  * @author     Andrey Demenev <demenev@gmail.com>
  17.  * @copyright  2004-2006 Andrey Demenev
  18.  * @license    http://www.php.net/license/3_0.txt  PHP License
  19.  * @version    CVS: $Id: Html.php,v 1.2 2007/06/29 06:56:34 ssttoo Exp $
  20.  * @link       http://pear.php.net/package/Text_Highlighter
  21.  */
  22.  
  23. /**
  24.  * @ignore
  25.  */
  26.  
  27. require_once 'Text/Highlighter/Renderer.php';
  28. require_once 'Text/Highlighter/Renderer/Array.php';
  29.  
  30. // BC trick : only define constants if Text/Highlighter.php
  31. // is not yet included
  32. if (!defined('HL_NUMBERS_LI')) {
  33.     /**#@+
  34.      * Constant for use with $options['numbers']
  35.      */
  36.     /**
  37.      * use numbered list, deprecated, use HL_NUMBERS_OL instaed
  38.      * @deprecated
  39.      */
  40.     define ('HL_NUMBERS_LI'    ,    1);
  41.     /**
  42.      * Use 2-column table with line numbers in left column and code in  right column.
  43.      */
  44.     define ('HL_NUMBERS_TABLE'    , 2);
  45.     /**#@-*/
  46. }
  47.  
  48.  
  49. /**#@+
  50.  * Constant for use with $options['numbers']
  51.  */
  52. /**
  53.  * Use numbered list
  54.  */
  55. define ('HL_NUMBERS_OL',    1);
  56. /**
  57.  * Use non-numbered list
  58.  */
  59. define ('HL_NUMBERS_UL',    3);
  60. /**#@-*/
  61.  
  62.  
  63. /**
  64.  * HTML renderer
  65.  *
  66.  * Elements of $options argument of constructor (each being optional):
  67.  *
  68.  * - 'numbers' - Line numbering style 0 or {@link HL_NUMBERS_TABLE}
  69.  *               or {@link HL_NUMBERS_UL} or {@link HL_NUMBERS_OL}
  70.  * - 'numbers_start' - starting number for numbered lines
  71.  * - 'tabsize' - Tab size
  72.  * - 'style_map' - Mapping of keywords to formatting rules using inline styles
  73.  * - 'class_map' - Mapping of keywords to formatting rules using class names
  74.  * - 'doclinks' - array that has keys "url", "target" and "elements", used for
  75.  *                generating links to online documentation
  76.  * - 'use_language' - class names will be prefixed with language, like "php-reserved" or "css-code"
  77.  *
  78.  * Example of setting documentation links:
  79.  * $options['doclinks'] = array(
  80.  *   'url' => 'http://php.net/%s',
  81.  *   'target' => '_blank',
  82.  *   'elements' => array('reserved', 'identifier')
  83.  * );
  84.  *
  85.  * Example of setting class names map:
  86.  * $options['class_map'] = array(
  87.  *       'main'       => 'my-main',
  88.  *       'table'      => 'my-table',
  89.  *       'gutter'     => 'my-gutter',
  90.  *       'brackets'   => 'my-brackets',
  91.  *       'builtin'    => 'my-builtin',
  92.  *       'code'       => 'my-code',
  93.  *       'comment'    => 'my-comment',
  94.  *       'default'    => 'my-default',
  95.  *       'identifier' => 'my-identifier',
  96.  *       'inlinedoc'  => 'my-inlinedoc',
  97.  *       'inlinetags' => 'my-inlinetags',
  98.  *       'mlcomment'  => 'my-mlcomment',
  99.  *       'number'     => 'my-number',
  100.  *       'quotes'     => 'my-quotes',
  101.  *       'reserved'   => 'my-reserved',
  102.  *       'special'    => 'my-special',
  103.  *       'string'     => 'my-string',
  104.  *       'url'        => 'my-url',
  105.  *       'var'        => 'my-var',
  106.  * );
  107.  *
  108.  * Example of setting styles mapping:
  109.  * $options['style_map'] = array(
  110.  *       'main'       => 'color: black',
  111.  *       'table'      => 'border: 1px solid black',
  112.  *       'gutter'     => 'background-color: yellow',
  113.  *       'brackets'   => 'color: blue',
  114.  *       'builtin'    => 'color: red',
  115.  *       'code'       => 'color: green',
  116.  *       'comment'    => 'color: orange',
  117.  *       // ....
  118.  * );
  119.  *
  120.  *
  121.  * @author Andrey Demenev <demenev@gmail.com>
  122.  * @category   Text
  123.  * @package    Text_Highlighter
  124.  * @copyright  2004-2006 Andrey Demenev
  125.  * @license    http://www.php.net/license/3_0.txt  PHP License
  126.  * @version    Release: 0.7.1
  127.  * @link       http://pear.php.net/package/Text_Highlighter
  128.  */
  129.  
  130. class Text_Highlighter_Renderer_Html extends Text_Highlighter_Renderer_Array
  131. {
  132.  
  133.     /**#@+
  134.      * @access private
  135.      */
  136.  
  137.     /**
  138.      * Line numbering style
  139.      *
  140.      * @var integer
  141.      */
  142.     var $_numbers = 0;
  143.  
  144.     /**
  145.      * For numberered lines - where to start
  146.      *
  147.      * @var integer
  148.      */
  149.     var $_numbers_start = 0;
  150.  
  151.     /**
  152.      * Tab size
  153.      *
  154.      * @var integer
  155.      */
  156.     var $_tabsize = 4;
  157.  
  158.     /**
  159.      * Highlighted code
  160.      *
  161.      * @var string
  162.      */
  163.     var $_output = '';
  164.  
  165.     /**
  166.      * Mapping of keywords to formatting rules using inline styles
  167.      *
  168.      * @var array
  169.      */
  170.     var $_style_map = array();
  171.  
  172.     /**
  173.      * Mapping of keywords to formatting rules using class names
  174.      *
  175.      * @var array
  176.      */
  177.     var $_class_map = array(
  178.         'main'       => 'hl-main',
  179.         'table'      => 'hl-table',
  180.         'gutter'     => 'hl-gutter',
  181.         'brackets'   => 'hl-brackets',
  182.         'builtin'    => 'hl-builtin',
  183.         'code'       => 'hl-code',
  184.         'comment'    => 'hl-comment',
  185.         'default'    => 'hl-default',
  186.         'identifier' => 'hl-identifier',
  187.         'inlinedoc'  => 'hl-inlinedoc',
  188.         'inlinetags' => 'hl-inlinetags',
  189.         'mlcomment'  => 'hl-mlcomment',
  190.         'number'     => 'hl-number',
  191.         'quotes'     => 'hl-quotes',
  192.         'reserved'   => 'hl-reserved',
  193.         'special'    => 'hl-special',
  194.         'string'     => 'hl-string',
  195.         'url'        => 'hl-url',
  196.         'var'        => 'hl-var',
  197.     );
  198.  
  199.     /**
  200.      * Setup for links to online documentation
  201.      *
  202.      * This is an array with keys:
  203.      * - url, ex. http://php.net/%s
  204.      * - target, ex. _blank, default - no target
  205.      * - elements, default is <code>array('reserved', 'identifier')</code>
  206.      *
  207.      * @var array
  208.      */
  209.     var $_doclinks = array();
  210.  
  211.     /**#@-*/
  212.  
  213.  
  214.     /**
  215.      * Resets renderer state
  216.      *
  217.      * @access protected
  218.      *
  219.      *
  220.      * Descendents of Text_Highlighter call this method from the constructor,
  221.      * passing $options they get as parameter.
  222.      */
  223.     function reset()
  224.     {
  225.         $this->_output = '';
  226.         if (isset($this->_options['numbers'])) {
  227.             $this->_numbers = (int)$this->_options['numbers'];
  228.             if ($this->_numbers != HL_NUMBERS_LI
  229.              && $this->_numbers != HL_NUMBERS_UL
  230.              && $this->_numbers != HL_NUMBERS_OL
  231.              && $this->_numbers != HL_NUMBERS_TABLE
  232.              ) {
  233.                 $this->_numbers = 0;
  234.             }
  235.         }
  236.         if (isset($this->_options['tabsize'])) {
  237.             $this->_tabsize = $this->_options['tabsize'];
  238.         }
  239.         if (isset($this->_options['numbers_start'])) {
  240.             $this->_numbers_start = intval($this->_options['numbers_start']);
  241.         }
  242.         if (isset($this->_options['doclinks']) &&
  243.             is_array($this->_options['doclinks']) &&
  244.             !empty($this->_options['doclinks']['url'])
  245.         ) {
  246.  
  247.             $this->_doclinks = $this->_options['doclinks']; // keys: url, target, elements array
  248.  
  249.             if (empty($this->_options['doclinks']['elements'])) {
  250.                 $this->_doclinks['elements'] = array('reserved', 'identifier');
  251.             }
  252.         }
  253.         if (isset($this->_options['style_map'])) {
  254.             $this->_style_map = $this->_options['style_map'];
  255.         }
  256.         if (isset($this->_options['class_map'])) {
  257.             $this->_class_map = array_merge($this->_class_map, $this->_options['class_map']);
  258.         }
  259.         $this->_htmlspecialchars = true;
  260.  
  261.     }
  262.  
  263.  
  264.     /**
  265.      * Given a CSS class name, returns the class name
  266.      * with language name prepended, if necessary
  267.      *
  268.      * @access private
  269.      *
  270.      * @param  string $class   Token class
  271.      */
  272.     function _getFullClassName($class)
  273.     {
  274.         if (!empty($this->_options['use_language'])) {
  275.             $the_class = $this->_language . '-' . $class;
  276.         } else {
  277.             $the_class = $class;
  278.         }
  279.         return $the_class;
  280.     }
  281.  
  282.     /**
  283.      * Signals that no more tokens are available
  284.      *
  285.      * @access public
  286.      */
  287.     function finalize()
  288.     {
  289.  
  290.         // get parent's output
  291.         parent::finalize();
  292.         $output = parent::getOutput();
  293.  
  294.         $html_output = '';
  295.  
  296.         $numbers_li = false;
  297.  
  298.         if (
  299.             $this->_numbers == HL_NUMBERS_LI ||
  300.             $this->_numbers == HL_NUMBERS_UL ||
  301.             $this->_numbers == HL_NUMBERS_OL
  302.            )
  303.         {
  304.             $numbers_li = true;
  305.         }
  306.  
  307.         // loop through each class=>content pair
  308.         foreach ($output AS $token) {
  309.  
  310.             if ($this->_enumerated) {
  311.                 $key = false;
  312.                 $the_class = $token[0];
  313.                 $content = $token[1];
  314.             } else {
  315.                 $key = key($token);
  316.                 $the_class = $key;
  317.                 $content = $token[$key];
  318.             }
  319.  
  320.             $span = $this->_getStyling($the_class);
  321.             $decorated_output = $this->_decorate($content, $key);
  322.  
  323.  
  324.             if ($numbers_li == true) {
  325.                 // end span tags before end of li, and re-open on next line
  326.                 $lastSpanTag = str_replace("%s</span>", "", $span);
  327.                 $span = sprintf($span, $decorated_output);
  328.                 $span = str_replace("\n", "</span></li>\n<li>$lastSpanTag ", $span);
  329.                 $html_output .= $span;
  330.             } else {
  331.                 $html_output .= sprintf($span, $decorated_output);
  332.             }
  333.  
  334.  
  335.         }
  336.  
  337.         // format lists
  338.         if (!empty($this->_numbers) && $numbers_li == true) {
  339.  
  340.  
  341.             // additional whitespace for browsers that do not display
  342.             // empty list items correctly
  343.             $this->_output = '<li> ' . $html_output . '</li>';
  344.  
  345.             $start = '';
  346.             if ($this->_numbers == HL_NUMBERS_OL && intval($this->_numbers_start) > 0)  {
  347.                 $start = ' start="' . $this->_numbers_start . '"';
  348.             }
  349.  
  350.             $list_tag = 'ol';
  351.             if ($this->_numbers == HL_NUMBERS_UL)  {
  352.                 $list_tag = 'ul';
  353.             }
  354.  
  355.  
  356.             $this->_output = '<' . $list_tag . $start
  357.                              . ' ' . $this->_getStyling('main', false) . '>'
  358.                              . $this->_output . '</'. $list_tag .'>';
  359.  
  360.         // render a table
  361.         } else if ($this->_numbers == HL_NUMBERS_TABLE) {
  362.  
  363.  
  364.             $start_number = 0;
  365.             if (intval($this->_numbers_start)) {
  366.                 $start_number = $this->_numbers_start - 1;
  367.             }
  368.  
  369.             $numbers = '';
  370.  
  371.             $nlines = substr_count($html_output,"\n")+1;
  372.             for ($i=1; $i <= $nlines; $i++) {
  373.                 $numbers .= ($start_number + $i) . "\n";
  374.             }
  375.             $this->_output = '<table ' . $this->_getStyling('table', false) . ' width="100%"><tr>' .
  376.                              '<td '. $this->_getStyling('gutter', false) .' align="right" valign="top">' .
  377.                              '<pre>' . $numbers . '</pre></td><td '. $this->_getStyling('main', false) .
  378.                              ' valign="top"><pre>' .
  379.                              $html_output . '</pre></td></tr></table>';
  380.         }
  381.         if (!$this->_numbers) {
  382.             $this->_output = '<pre>' . $html_output . '</pre>';
  383.         }
  384.         $this->_output = '<div ' . $this->_getStyling('main', false) . '>' . $this->_output . '</div>';
  385.     }
  386.  
  387.  
  388.     /**
  389.      * Provides additional formatting to a keyword
  390.      *
  391.      * @param string $content Keyword
  392.      * @return string Keyword with additional formatting
  393.      * @access public
  394.      *
  395.      */
  396.     function _decorate($content, $key = false)
  397.     {
  398.         // links to online documentation
  399.         if (!empty($this->_doclinks) &&
  400.             !empty($this->_doclinks['url']) &&
  401.             in_array($key, $this->_doclinks['elements'])
  402.         ) {
  403.  
  404.             $link = '<a href="'. sprintf($this->_doclinks['url'], $content) . '"';
  405.             if (!empty($this->_doclinks['target'])) {
  406.                 $link.= ' target="' . $this->_doclinks['target'] . '"';
  407.             }
  408.             $link .= '>';
  409.             $link.= $content;
  410.             $link.= '</a>';
  411.  
  412.             $content = $link;
  413.  
  414.         }
  415.  
  416.         return $content;
  417.     }
  418.  
  419.     /**
  420.      * Returns <code>class</code> and/or <code>style</code> attribute,
  421.      * optionally enclosed in a <code>span</code> tag
  422.      *
  423.      * @param string $class Class name
  424.      * @paran boolean $span_tag Whether or not to return styling attributes in a <code>>span<</code> tag
  425.      * @return string <code>span</code> tag or just a <code>class</code> and/or <code>style</code> attributes
  426.      * @access private
  427.      */
  428.     function _getStyling($class, $span_tag = true)
  429.     {
  430.         $attrib = '';
  431.         if (!empty($this->_style_map) &&
  432.             !empty($this->_style_map[$class])
  433.         ) {
  434.             $attrib = 'style="'. $this->_style_map[$class] .'"';
  435.         }
  436.         if (!empty($this->_class_map) &&
  437.             !empty($this->_class_map[$class])
  438.         ) {
  439.             if ($attrib) {
  440.                 $attrib .= ' ';
  441.             }
  442.             $attrib .= 'class="'. $this->_getFullClassName($this->_class_map[$class]) .'"';
  443.         }
  444.  
  445.         if ($span_tag) {
  446.             $span = '<span ' . $attrib . '>%s</span>';
  447.             return $span;
  448.         } else {
  449.             return $attrib;
  450.         }
  451.  
  452.     }
  453. }
  454.  
  455. /*
  456.  * Local variables:
  457.  * tab-width: 4
  458.  * c-basic-offset: 4
  459.  * c-hanging-comment-ender-p: nil
  460.  * End:
  461.  */
  462.  
  463. ?>