TableTrait::renderTable()   B
last analyzed

Complexity

Conditions 8
Paths 28

Size

Total Lines 31

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 8

Importance

Changes 0
Metric Value
dl 0
loc 31
ccs 21
cts 21
cp 1
rs 8.1795
c 0
b 0
f 0
cc 8
nc 28
nop 1
crap 8
1
<?php
2
/**
3
 * @copyright Copyright (c) 2015 Nobuo Kihara
4
 * @license https://github.com/softark/creole/blob/master/LICENSE
5
 * @link https://github.com/softark/creole#readme
6
 */
7
8
namespace softark\creole\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 22
    protected function identifyTable($line)
19
    {
20 22
        return strpos($line, '|') !== false && preg_match('/^\s*\|.*/', $line);
21
    }
22
23
    /**
24
     * Consume lines for a table
25
     */
26 3
    protected function consumeTable($lines, $current)
27
    {
28
        $pattern = <<< REGEXP
29 3
/(?<=\|)(
30
    ([^\|]*?{{{.*?}}}[^\|]*?)+|
31
    ([^\|]*~\|[^\|]*?)+|
32
    [^\|]*
33
)(?=\|)/x
34
REGEXP;
35
        // regexp pattern should be in the order of from specific/long/complicated to general/short/simple.
36
37
        $block = [
38 3
            'table',
39
            'rows' => [],
40
        ];
41 3
        for ($i = $current, $count = count($lines); $i < $count; $i++) {
42 3
            $line = trim($lines[$i]);
43 3
            if ($line === '' || $line[0] !== '|') {
44 3
                break;
45
            }
46 3
            $header = $i === $current;
47 3
            preg_match_all($pattern, '|' . trim($line, '| ') . '|', $matches);
48 3
            $row = [];
49 3
            foreach ($matches[0] as $text) {
50 3
                $cell = [];
51 3
                if (isset($text[0]) && $text[0] === '=') {
52 3
                    $cell['tag'] = 'th';
53 3
                    $cell['text'] = $this->parseInline(trim(substr($text, 1)));
54
                } else {
55 3
                    $cell['tag'] = 'td';
56 3
                    $cell['text'] = $this->parseInline(trim($text));
57 3
                    $header = false;
58
                }
59 3
                $row['cells'][] = $cell;
60
            }
61 3
            $row['header'] = $header;
62 3
            $block['rows'][] = $row;
63
        }
64
65 3
        return [$block, --$i];
66
    }
67
68
    /**
69
     * render a table block
70
     */
71 3
    protected function renderTable($block)
72
    {
73 3
        $content = "";
74 3
        $first = true;
75 3
        foreach ($block['rows'] as $row) {
76 3
            if ($first) {
77 3
                if ($row['header']) {
78 3
                    $content .= "<thead>\n";
79
                } else {
80 1
                    $content .= "<tbody>\n";
81
                }
82
            }
83 3
            $content .= "<tr>\n";
84 3
            foreach ($row['cells'] as $cell) {
85 3
                $tag = $cell['tag'];
86 3
                $cellText = $this->renderAbsy($cell['text']);
87 3
                if (empty($cellText)) {
88 1
                    $cellText = '&nbsp;';
89
                }
90 3
                $content .= "<$tag>$cellText</$tag>\n";
91
            }
92 3
            $content .= "</tr>\n";
93 3
            if ($first) {
94 3
                if ($row['header']) {
95 3
                    $content .= "</thead>\n<tbody>\n";
96
                }
97 3
                $first = false;
98
            }
99
        }
100 3
        return "<table>\n$content</tbody>\n</table>\n";
101
    }
102
103
    abstract protected function parseInline($text);
104
105
    abstract protected function renderAbsy($absy);
106
}
107