Blame view

vendor/cebe/markdown/block/TableTrait.php 3.18 KB
3cf42f5c   Mihail   init commit - bas...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
  <?php
  /**
   * @copyright Copyright (c) 2014 Carsten Brandt
   * @license https://github.com/cebe/markdown/blob/master/LICENSE
   * @link https://github.com/cebe/markdown#readme
   */
  
  namespace cebe\markdown\block;
  
  /**
   * Adds the table blocks
   */
  trait TableTrait
  {
  	private $_tableCellTag = 'td';
  	private $_tableCellCount = 0;
  	private $_tableCellAlign = [];
  
  	/**
  	 * identify a line as the beginning of a table block.
  	 */
  	protected function identifyTable($line, $lines, $current)
  	{
  		return strpos($line, '|') !== false && isset($lines[$current + 1])
  			&& preg_match('~^\\s*\\|?(\\s*:?-[\\-\\s]*:?\\s*\\|\\s*:?-[\\-\\s]*:?\\s*)+\\|?\\s*$~', $lines[$current + 1]);
  	}
  
  	/**
  	 * Consume lines for a table
  	 */
  	protected function consumeTable($lines, $current)
  	{
  		// consume until newline
  
  		$block = [
  			'table',
  			'cols' => [],
  			'rows' => [],
  		];
  		$beginsWithPipe = $lines[$current][0] === '|';
  		for ($i = $current, $count = count($lines); $i < $count; $i++) {
  			$line = rtrim($lines[$i]);
  
  			// extract alignment from second line
  			if ($i == $current+1) {
  				$cols = explode('|', trim($line, ' |'));
  				foreach($cols as $col) {
  					$col = trim($col);
  					if (empty($col)) {
  						$block['cols'][] = '';
  						continue;
  					}
  					$l = ($col[0] === ':');
  					$r = (substr($col, -1, 1) === ':');
  					if ($l && $r) {
  						$block['cols'][] = 'center';
  					} elseif ($l) {
  						$block['cols'][] = 'left';
  					} elseif ($r) {
  						$block['cols'][] = 'right';
  					} else {
  						$block['cols'][] = '';
  					}
  				}
  
  				continue;
  			}
  			if ($line === '' || $beginsWithPipe && $line[0] !== '|') {
  				break;
  			}
  			if ($line[0] === '|') {
  				$line = substr($line, 1);
  			}
  			if (substr($line, -1, 1) === '|' && (substr($line, -2, 2) !== '\\|' || substr($line, -3, 3) === '\\\\|')) {
  				$line = substr($line, 0, -1);
  			}
  			$block['rows'][] = $line;
  		}
  
  		return [$block, --$i];
  	}
  
  	/**
  	 * render a table block
  	 */
  	protected function renderTable($block)
  	{
  		$content = '';
  		$this->_tableCellAlign = $block['cols'];
  		$content .= "<thead>\n";
  		$first = true;
  		foreach($block['rows'] as $row) {
  			$this->_tableCellTag = $first ? 'th' : 'td';
  			$align = empty($this->_tableCellAlign[$this->_tableCellCount]) ? '' : ' align="' . $this->_tableCellAlign[$this->_tableCellCount++] . '"';
  			$tds = "<$this->_tableCellTag$align>" . trim($this->renderAbsy($this->parseInline($row))) . "</$this->_tableCellTag>"; // TODO move this to the consume step
  			$content .= "<tr>$tds</tr>\n";
  			if ($first) {
  				$content .= "</thead>\n<tbody>\n";
  			}
  			$first = false;
  			$this->_tableCellCount = 0;
  		}
  		return "<table>\n$content</tbody>\n</table>\n";
  	}
  
  	/**
  	 * @marker |
  	 */
  	protected function parseTd($markdown)
  	{
  		if (isset($this->context[1]) && $this->context[1] === 'table') {
  			$align = empty($this->_tableCellAlign[$this->_tableCellCount]) ? '' : ' align="' . $this->_tableCellAlign[$this->_tableCellCount++] . '"';
  			return [['text', "</$this->_tableCellTag><$this->_tableCellTag$align>"], isset($markdown[1]) && $markdown[1] === ' ' ? 2 : 1]; // TODO make a absy node
  		}
  		return [['text', $markdown[0]], 1];
  	}
  
  	abstract protected function parseInline($text);
  	abstract protected function renderAbsy($absy);
  }