Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/infrastructure/markup/blockrule/PhutilRemarkupSimpleTableBlockRule.php
12241 views
1
<?php
2
3
final class PhutilRemarkupSimpleTableBlockRule extends PhutilRemarkupBlockRule {
4
5
public function getMatchingLineCount(array $lines, $cursor) {
6
$num_lines = 0;
7
while (isset($lines[$cursor])) {
8
if (preg_match('/^(\s*\|.*+\n?)+$/', $lines[$cursor])) {
9
$num_lines++;
10
$cursor++;
11
} else {
12
break;
13
}
14
}
15
16
return $num_lines;
17
}
18
19
public function markupText($text, $children) {
20
$matches = array();
21
22
$rows = array();
23
foreach (explode("\n", $text) as $line) {
24
// Ignore ending delimiters.
25
$line = rtrim($line, '|');
26
27
// NOTE: The complexity in this regular expression allows us to match
28
// a table like "| a | [[ href | b ]] | c |".
29
30
preg_match_all(
31
'/\|'.
32
'('.
33
'(?:'.
34
'(?:\\[\\[.*?\\]\\])'. // [[ ... | ... ]], a link
35
'|'.
36
'(?:[^|[]+)'. // Anything but "|" or "[".
37
'|'.
38
'(?:\\[[^\\|[])'. // "[" followed by anything but "[" or "|"
39
')*'.
40
')/', $line, $matches);
41
42
$any_header = false;
43
$any_content = false;
44
45
$cells = array();
46
foreach ($matches[1] as $cell) {
47
$cell = trim($cell);
48
49
// If this row only has empty cells and "--" cells, and it has at
50
// least one "--" cell, it's marking the rows above as <th> cells
51
// instead of <td> cells.
52
53
// If it has other types of cells, it's always a content row.
54
55
// If it has only empty cells, it's an empty row.
56
57
if (strlen($cell)) {
58
if (preg_match('/^--+\z/', $cell)) {
59
$any_header = true;
60
} else {
61
$any_content = true;
62
}
63
}
64
65
$cells[] = array('type' => 'td', 'content' => $this->applyRules($cell));
66
}
67
68
$is_header = ($any_header && !$any_content);
69
70
if (!$is_header) {
71
$rows[] = array('type' => 'tr', 'content' => $cells);
72
} else if ($rows) {
73
// Mark previous row with headings.
74
foreach ($cells as $i => $cell) {
75
if ($cell['content']) {
76
$last_key = last_key($rows);
77
if (!isset($rows[$last_key]['content'][$i])) {
78
// If this row has more cells than the previous row, there may
79
// not be a cell above this one to turn into a <th />.
80
continue;
81
}
82
83
$rows[$last_key]['content'][$i]['type'] = 'th';
84
}
85
}
86
}
87
}
88
89
if (!$rows) {
90
return $this->applyRules($text);
91
}
92
93
return $this->renderRemarkupTable($rows);
94
}
95
96
}
97
98