Completed
Push — master ( 8a11c4...7edaef )
by Carsten
04:24
created

TableTrait::identifyTable()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 7
ccs 5
cts 5
cp 1
rs 8.8571
c 0
b 0
f 0
cc 6
eloc 5
nc 6
nop 3
crap 6
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
	/**
16
	 * identify a line as the beginning of a table block.
17
	 */
18 131
	protected function identifyTable($line, $lines, $current)
19
	{
20 131
		return strpos($line, '|') !== false && isset($lines[$current + 1])
21 131
			&& preg_match('~^\\s*\\|?(\\s*:?-[\\-\\s]*:?\\s*\\|?)*\\s*$~', $lines[$current + 1])
22 131
			&& strpos($lines[$current + 1], '|') !== false
23 131
			&& isset($lines[$current + 2]) && trim($lines[$current + 1]) !== '';
24
	}
25
26
	/**
27
	 * Consume lines for a table
28
	 */
29 2
	protected function consumeTable($lines, $current)
30
	{
31
		// consume until newline
32
33
		$block = [
34 2
			'table',
35
			'cols' => [],
36
			'rows' => [],
37
		];
38 2
		for ($i = $current, $count = count($lines); $i < $count; $i++) {
39 2
			$line = trim($lines[$i]);
40
41
			// extract alignment from second line
42 2
			if ($i == $current+1) {
43 2
				$cols = explode('|', trim($line, ' |'));
44 2
				foreach($cols as $col) {
45 2
					$col = trim($col);
46 2
					if (empty($col)) {
47
						$block['cols'][] = '';
48
						continue;
49
					}
50 2
					$l = ($col[0] === ':');
51 2
					$r = (substr($col, -1, 1) === ':');
52 2
					if ($l && $r) {
53 2
						$block['cols'][] = 'center';
54 2
					} elseif ($l) {
55 2
						$block['cols'][] = 'left';
56 2
					} elseif ($r) {
57 2
						$block['cols'][] = 'right';
58
					} else {
59 2
						$block['cols'][] = '';
60
					}
61
				}
62
63 2
				continue;
64
			}
65 2
			if ($line === '' || substr($lines[$i], 0, 4) === '    ') {
66 2
				break;
67
			}
68 2
			if ($line[0] === '|') {
69 2
				$line = substr($line, 1);
70
			}
71 2
			if (substr($line, -1, 1) === '|' && (substr($line, -2, 2) !== '\\|' || substr($line, -3, 3) === '\\\\|')) {
72 2
				$line = substr($line, 0, -1);
73
			}
74
75 2
			array_unshift($this->context, 'table');
0 ignored issues
show
Bug introduced by
The property context does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
76 2
			$row = $this->parseInline($line);
77 2
			array_shift($this->context);
78
79 2
			$r = count($block['rows']);
80 2
			$c = 0;
81 2
			$block['rows'][] = [];
82 2
			foreach ($row as $absy) {
83 2
				if (!isset($block['rows'][$r][$c])) {
84 2
					$block['rows'][$r][] = [];
85
				}
86 2
				if ($absy[0] === 'tableBoundary') {
87 2
					$c++;
88
				} else {
89 2
					$block['rows'][$r][$c][] = $absy;
90
				}
91
			}
92
		}
93
94 2
		return [$block, --$i];
95
	}
96
97
	/**
98
	 * render a table block
99
	 */
100 2
	protected function renderTable($block)
101
	{
102 2
		$head = '';
103 2
		$body = '';
104 2
		$cols = $block['cols'];
105 2
		$first = true;
106 2
		foreach($block['rows'] as $row) {
107 2
			$cellTag = $first ? 'th' : 'td';
108 2
			$tds = '';
109 2
			foreach ($row as $c => $cell) {
110 2
				$align = empty($cols[$c]) ? '' : ' align="' . $cols[$c] . '"';
111 2
				$tds .= "<$cellTag$align>" . trim($this->renderAbsy($cell)) . "</$cellTag>";
112
			}
113 2
			if ($first) {
114 2
				$head .= "<tr>$tds</tr>\n";
115
			} else {
116 2
				$body .= "<tr>$tds</tr>\n";
117
			}
118 2
			$first = false;
119
		}
120 2
		return $this->composeTable($head, $body);
121
	}
122
123
	/**
124
	 * This method composes a table from parsed body and head HTML.
125
	 *
126
	 * You may override this method to customize the table rendering, for example by
127
	 * adding a `class` to the table tag:
128
	 *
129
	 * ```php
130
	 * return "<table class="table table-striped">\n<thead>\n$head</thead>\n<tbody>\n$body</tbody>\n</table>\n"
131
	 * ```
132
	 *
133
	 * @param string $head table head HTML.
134
	 * @param string $body table body HTML.
135
	 * @return string the complete table HTML.
136
	 * @since 1.2.0
137
	 */
138 2
	protected function composeTable($head, $body)
139
	{
140 2
		return "<table>\n<thead>\n$head</thead>\n<tbody>\n$body</tbody>\n</table>\n";
141
	}
142
143
	/**
144
	 * @marker |
145
	 */
146 4
	protected function parseTd($markdown)
147
	{
148 4
		if (isset($this->context[1]) && $this->context[1] === 'table') {
149 2
			return [['tableBoundary'], isset($markdown[1]) && $markdown[1] === ' ' ? 2 : 1];
150
		}
151 4
		return [['text', $markdown[0]], 1];
152
	}
153
154
	abstract protected function parseInline($text);
155
	abstract protected function renderAbsy($absy);
156
}
157