Completed
Push — master ( d363ff...b6b576 )
by Carsten
01:16
created

TableTrait   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 110
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 96.92%

Importance

Changes 0
Metric Value
wmc 30
lcom 1
cbo 0
dl 0
loc 110
ccs 63
cts 65
cp 0.9692
rs 10
c 0
b 0
f 0

6 Methods

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