Completed
Push — master ( 9ffe58...cd3227 )
by Carsten
03:21 queued 01:21
created

TableTrait   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 111
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 96.97%

Importance

Changes 0
Metric Value
wmc 32
lcom 1
cbo 0
dl 0
loc 111
ccs 64
cts 66
cp 0.9697
rs 9.6
c 0
b 0
f 0

6 Methods

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