@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
at recaptime-dev/main 96 lines 2.6 kB view raw
1<?php 2 3final 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}