'error', 'msg' => $this->getLang($code))); } else { return $this->getLang($code); } } static function line_nr($pos, $file_path, $start_line = 0) { $line_nr = 0; if (!is_array(self::$line_nr_c[$file_path] ?? null)) { self::$line_nr_c[$file_path] = array(); $start_pos = 0; $line_nr = 0; } else { $start_pos = count(self::$line_nr_c[$file_path]) - 1; $line_nr = self::$line_nr_c[$file_path][count(self::$line_nr_c[$file_path]) - 1]; } if ($start_line > 0) { //find last pos on current line if (($find = array_search($start_line, self::$line_nr_c[$file_path] ?? [])) !== false) { //the new line charter from last line -> it's nessesery in order to corect work of my handler $start_pos = $find; $pos += $find; } else { if (self::$file_cont == NULL) self::$file_cont = io_readFile($file_path); for($i = $start_pos; $i < strlen(self::$file_cont) && $line_nr < $start_line; $i++) { self::$line_nr_c[$file_path][$i] = $line_nr; if(self::$file_cont[$i] == "\n") $line_nr++; } self::$line_nr_c[$file_path][$i] = $line_nr; $pos += $i; $start_pos = $i; } $line_nr = $start_line; } if ($start_pos >= $pos) { /*dbglog("TYRANOZAUR"); dbglog(self::$line_nr_c);*/ return self::$line_nr_c[$file_path][$pos]; } else { if (self::$file_cont == NULL) self::$file_cont = io_readFile($file_path); for($i=$start_pos;$i <= $pos; $i++) { self::$line_nr_c[$file_path][$i] = $line_nr; if(self::$file_cont[$i] == "\n") $line_nr++; } return self::$line_nr_c[$file_path][$pos]; } } function rows($row, $page_id, $start_line) { $Parser = new Doku_Parser(); $Parser->Handler = new helper_plugin_dtable_handler($page_id, $start_line); //add modes to parser $modes = p_get_parsermodes(); foreach($modes as $mode) { $Parser->addMode($mode['mode'], $mode['obj']); } return $Parser->parse($row); } function get_spans($start_line, $page_lines, $page_id) { $table = ''; for ($i = $start_line; trim($page_lines[$i]) != '' && $i < count($page_lines); $i++) { $table .= $page_lines[$i]."\n"; } $spans = array(); $rows = self::rows($table, $page_id, $start_line); for ($i = 0; $i < count($rows); $i++) { for ($j = 0; $j < count($rows[$i][0]); $j++) { $spans[$i][$j][0] = $rows[$i][0][$j][0]; $spans[$i][$j][1] = $rows[$i][0][$j][1]; } } return $spans; } function format_row($array_line) { $line = ''; foreach ($array_line as $cell) { if ($cell[0] == 'tableheader_open') { $line .= '^'.$cell[1]; } else { $line .= '|'.$cell[1]; } } if ($array_line[count($array_line) - 1][0] == 'tableheader_open') { $line .= '^'; } else { $line .= '|'; } $line = str_replace("\n", '\\\\ ', $line); return $line; } function parse_line($line, $page_id) { $line = preg_replace('/\s*:::\s*\|/', '', $line); $info = array(); $html = p_render('xhtml',p_get_instructions($line),$info); $maches = array(); preg_match('/(.*?)<\/tr>/si', $html, $maches); return trim($maches[1]); } } class helper_plugin_dtable_handler { public $calls = NULL; public $row = 0; public $cell = 0; public $type; public $file_path; public $start_line; public function __construct($page_id, $start_line) { $this->file_path = wikiFN($page_id); $this->start_line = $start_line; } function table($match, $state, $pos) { switch ( $state ) { case DOKU_LEXER_ENTER: $type = trim($match); $this->calls = array(); $line = helper_plugin_dtable::line_nr($pos, $this->file_path, $this->start_line); $this->calls[$this->row][0][$this->cell] = array(1, 1, $type, ''); $this->calls[$this->row][1][0] = $line; break; case DOKU_LEXER_EXIT: $line = helper_plugin_dtable::line_nr($pos, $this->file_path, $this->start_line); $this->calls[$this->row][1][1] = $line - 1; break; case DOKU_LEXER_UNMATCHED: if (is_array($this->calls)) { $this->calls[$this->row][0][$this->cell][3] .= $match; } break; case DOKU_LEXER_MATCHED: if ( preg_match('/:::/',$match) ) { $this->calls[$this->row][0][$this->cell][3] .= $match; } else if ( trim($match) == '' ){ $this->calls[$this->row][0][$this->cell][3] .= $match; } else { $row = $this->row; while (preg_match('/^\s*:::\s*$/', $this->calls[$row][0][$this->cell][3]) && $row > 0) { $row--; } if ($row != $this->row) $this->calls[$row][0][$this->cell][1]++; if ( $match[0] == "\n") { $line = helper_plugin_dtable::line_nr($pos, $this->file_path, $this->start_line); $this->calls[$this->row][1][1] = $line - 1; //remove last cell and -- the celsapn it doesn't exist array_pop($this->calls[$this->row][0]); $this->row++; $this->calls[$this->row] = array(array(), array()); $this->cell = 0; $type = $match[1]; $this->calls[$this->row][1][0] = $line; $this->calls[$this->row][0][$this->cell] = array(1, 1, $type, ''); } else { if ($this->calls[$this->row][0][$this->cell][3] == '' && $this->cell > 0) { $this->calls[$this->row][0][$this->cell - 1][0]++; array_pop($this->calls[$this->row][0]); } else { $this->cell++; } $type = $match[0]; $this->calls[$this->row][0][$this->cell] = array(1, 1, $type, ''); } } break; } return true; } /** Change // into \n during editing in textbox, can be turn off if not needed. */ public function linebreak($match, $state, $pos) { $this->calls[$this->row][0][$this->cell][3] .= "\n"; return true; } /** * Catchall handler for the remaining syntax * * @param string $name Function name that was called * @param array $params Original parameters * @return bool If parsing should be continue */ public function __call($name, $params) { if($this->calls === null) $this->calls = []; if(!isset($this->calls[$this->row][0][$this->cell][3])) { $this->calls[$this->row][0][$this->cell][3] = ''; } $this->calls[$this->row][0][$this->cell][3] .= $params[0]; return true; } public function _finalize() { //remove last cell and -- the celsapn it doesn't exist array_pop($this->calls[$this->row][0]); $this->row = 0; $this->cell = 0; } }