Location: PHPKode > projects > SolarPHP > solar-system-1.1.1/solar/source/solar/Solar/Markdown/Extra/Table.php
<?php
/**
 * 
 * Block class to form tables from Markdown syntax.
 * 
 * Syntax is ...
 * 
 *     |  Header 1  |  Header 2  |  Header N 
 *     | ---------- | ---------- | ----------
 *     | data cell  | data cell  | data cell 
 *     | data cell  | data cell  | data cell 
 *     | data cell  | data cell  | data cell 
 *     | data cell  | data cell  | data cell 
 * 
 * You can force columns alignment by putting a colon in the header-
 * underline row.
 * 
 *     | Left-Aligned |  No Align | Right-Aligned 
 *     | :----------- | --------- | -------------:
 *     | data cell    | data cell | data cell      
 *     | data cell    | data cell | data cell      
 *     | data cell    | data cell | data cell      
 *     | data cell    | data cell | data cell      
 * 
 * @category Solar
 * 
 * @package Solar_Markdown_Extra
 * 
 * @author Michel Fortin <http://www.michelf.com/projects/php-markdown/>
 * 
 * @author Paul M. Jones <hide@address.com>
 * 
 * @license http://opensource.org/licenses/bsd-license.php BSD
 * 
 * @version $Id: Table.php 3153 2008-05-05 23:14:16Z pmjones $
 * 
 */
class Solar_Markdown_Extra_Table extends Solar_Markdown_Plugin
{
    /**
     * 
     * This is a block plugin.
     * 
     * @var bool
     * 
     */
    protected $_is_block = true;
    
    /**
     * 
     * Uses these chars for parsing.
     * 
     * @var string
     * 
     */
    protected $_chars = '|';
    
    /**
     * 
     * Transforms Markdown syntax to XHTML tables.
     * 
     * @param string $text The source text.
     * 
     * @return string The transformed XHTML.
     * 
     */
    public function parse($text)
    {
        $less_than_tab = $this->_getTabWidth() - 1;
        
        // Find tables with leading pipe.
        //
        //    | Header 1 | Header 2
        //    | -------- | --------
        //    | Cell 1   | Cell 2
        //    | Cell 3   | Cell 4
        // 
        $text = preg_replace_callback('
            {
                ^                               # Start of a line
                [ ]{0,'.$less_than_tab.'}       # Allowed whitespace.
                [|]                             # Optional leading pipe (present)
                (.+) \n                         # $1: Header row (at least one pipe)
                                            
                [ ]{0,'.$less_than_tab.'}       # Allowed whitespace.
                [|] ([ ]*[-:]+[-| :]*) \n       # $2: Header underline
                                            
                (                               # $3: Cells
                    (?:                     
                        [ ]*                    # Allowed whitespace.
                        [|] .* \n               # Row content.
                    )*                      
                )                           
                (?=\n|\Z)                       # Stop at final double newline.
            }xm',
            array($this, '_parsePipe'),
            $text
        );
    
        //
        // Find tables without leading pipe.
        //
        //    Header 1 | Header 2
        //    -------- | --------
        //    Cell 1   | Cell 2
        //    Cell 3   | Cell 4
        //
        $text = preg_replace_callback('
            {
                ^                               # Start of a line
                [ ]{0,'.$less_than_tab.'}       # Allowed whitespace.
                (\S.*[|].*) \n                  # $1: Header row (at least one pipe)
                                                
                [ ]{0,'.$less_than_tab.'}       # Allowed whitespace.
                ([-:]+[ ]*[|][-| :]*) \n        # $2: Header underline
                                                
                (                               # $3: Cells
                    (?:                         
                        .* [|] .* \n            # Row content
                    )*                          
                )                               
                (?=\n|\Z)                       # Stop at final double newline.
            }xm',
            array($this, '_parsePlain'),
            $text
        );
        
        return $text;
    }
    
    /**
     * 
     * Support callback for leading-pipe syntax.
     * 
     * @param array $matches Matches from preg_replace_callback().
     * 
     * @return string The replacement text.
     * 
     */
    protected function _parsePipe($matches)
    {
        // Remove leading pipe for each row.
        $matches[3]    = preg_replace('/^ *[|]/m', '', $matches[3]);
        return $this->_parsePlain($matches);
    }
    
    /**
     * 
     * Support callback for table conversion.
     * 
     * @param array $matches Matches from preg_replace_callback().
     * 
     * @return string The replacement text.
     * 
     */
    protected function _parsePlain($matches)
    {
        $head       = $matches[1];
        $underline  = $matches[2];
        $content    = $matches[3];
        
        // Remove any tailing pipes for each line.
        $head       = preg_replace('/[|] *$/m', '', $head);
        $underline  = preg_replace('/[|] *$/m', '', $underline);
        $content    = preg_replace('/[|] *$/m', '', $content);
    
        // Reading alignment from header underline.
        $separators = preg_split('/ *[|] */', $underline);
        $attr = array();
        foreach ($separators as $n => $s) {
            if (preg_match('/^ *-+: *$/', $s)) {
                $attr[$n] = ' align="right"';
            } elseif (preg_match('/^ *:-+: *$/', $s)) {
                $attr[$n] = ' align="center"';
            } elseif (preg_match('/^ *:-+ *$/', $s)) {
                $attr[$n] = ' align="left"';
            } else {
                $attr[$n] = '';
            }
        }
    
        // handle all spans at once, not just code spans
        $head      = $this->_processSpans($head);
        $headers   = preg_split('/ *[|] */', $head);
        $col_count = count($headers);
    
        // Write column headers.
        $text = "\n<table>\n";
        $text .= "    <thead>\n";
        $text .= "        <tr>\n";
        foreach ($headers as $n => $header) {
            $text .= "            <th$attr[$n]>". trim($header) ."</th>\n";
        }
        $text .= "        </tr>\n";
        $text .= "    </thead>\n";
    
        // Split content by row.
        $rows = explode("\n", trim($content, "\n"));
    
        $text .= "    <tbody>\n";
        foreach ($rows as $row) {
            // handle all spans at once, not just code spans
            $row = $this->_processSpans($row);
        
            // Split row by cell.
            $row_cells = preg_split('/ *[|] */', $row, $col_count);
            $row_cells = array_pad($row_cells, $col_count, '');
        
            $text .= "        <tr>\n";
            foreach ($row_cells as $n => $cell) {
                $text .= "            <td$attr[$n]>". trim($cell) ."</td>\n";
            }
            $text .= "        </tr>\n";
        }
        $text .= "    </tbody>\n";
        $text .= "</table>\n";
    
        return $this->_toHtmlToken($text) . "\n";
    }
}
Return current item: SolarPHP