1<?php 2 3// must be run within Dokuwiki 4if(!defined('DOKU_INC')) die(); 5 6require_once DOKU_PLUGIN . 'latexport/implementation/decorator.php'; 7 8class CellSize { 9 10 public $colspan; 11 12 public $rowspan; 13 14 static function makeRow($maxcols) { 15 $row = []; 16 for ($n = 0; $n < $maxcols; $n++) { 17 $row[] = new CellSize(); 18 } 19 return $row; 20 } 21 22 public function __construct($colspan = 1, $rowspan = 0) { 23 $this->colspan = $colspan; 24 $this->rowspan = $rowspan; 25 } 26 27 public function setSize($colspan, $rowspan) { 28 $this->colspan = $colspan; 29 $this->rowspan = $rowspan; 30 } 31 32 public function getCols() { 33 return $this->colspan; 34 } 35 36 public function getRows() { 37 return $this->rowspan; 38 } 39 40 41 public function nextCellSize() { 42 if ($this->rowspan > 0) { 43 return new CellSize($this->colspan, $this->rowspan - 1); 44 } else { 45 return new CellSize(); 46 } 47 } 48 49 public function __toString() { 50 return "<c=$this->colspan,r=$this->rowspan>"; 51 } 52} 53 54/** 55 * Adapts the tables to latex. 56 * 57 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 58 * @author Jean-Michel Gonet <jmgonet@yahoo.com> 59 */ 60class DecoratorTables extends Decorator { 61 62 private $row; 63 64 private $column; 65 66 private $inTable; 67 68 /** 69 * Open a paragraph. 70 */ 71 function p_open() { 72 if ($this->inTable) { 73 // No paragraphs allowed in tables 74 } else { 75 $this->decorator->p_open(); 76 } 77 } 78 79 /** 80 * Close a paragraph. 81 */ 82 function p_close() { 83 if ($this->inTable) { 84 $this->decorator->linebreak(); 85 } else { 86 $this->decorator->p_close(); 87 } 88 } 89 90 /** 91 * Verbatim is not supported inside makecell (it should go inside 92 * a mini page), so best next option is not to output verbatim, 93 * and hope for the best. 94 * 95 * @param string $text 96 */ 97 function unformatted($text) { 98 if ($this->inTable) { 99 $this->decorator->cdata($text); 100 } else { 101 $this->decorator->unformatted($text); 102 } 103 } 104 105 /** 106 * Start a table 107 * 108 * @param int $maxcols maximum number of columns 109 * @param int $numrows NOT IMPLEMENTED 110 * @param int $pos byte position in the original source 111 */ 112 function table_open($maxcols = null, $numrows = null, $pos = null) { 113 $this->row = CellSize::makeRow($maxcols); 114 $this->decorator->table_open($maxcols, $numrows, $pos); 115 $this->inTable = true; 116 } 117 118 function table_close($pos = null) { 119 $this->decorator->table_close($pos); 120 $this->inTable = false; 121 } 122 123 /** 124 * Open a table row 125 */ 126 function tablerow_open() { 127 $this->column = 0; 128 $this->decorator->tablerow_open(); 129 } 130 131 /** 132 * Close a table row 133 */ 134 function tablerow_close() { 135 $this->decorator->tablerow_close(); 136 $this->computeCline(); 137 $this->computeNextLine(); 138 } 139 140 141 /** 142 * Open a table header cell 143 * 144 * @param int $colspan 145 * @param string $align left|center|right 146 * @param int $rowspan 147 */ 148 function tableheader_open($colspan = 1, $align = null, $rowspan = 1) { 149 $numberOfPlaceholders = $this->computePlaceholders($colspan, $rowspan); 150 for ($n = 0; $n < $numberOfPlaceholders; $n++) { 151 $this->decorator->tableheader_open(1, null, 1); 152 $this->decorator->tableheader_close(1, null, 1); 153 } 154 $this->decorator->tableheader_open($colspan, $align, $rowspan); 155 } 156 157 /** 158 * Open a table cell 159 * 160 * @param int $colspan 161 * @param string $align left|center|right 162 * @param int $rowspan 163 */ 164 function tablecell_open($colspan = 1, $align = center, $rowspan = 1) { 165 $numberOfPlaceholders = $this->computePlaceholders($colspan, $rowspan); 166 for ($n = 0; $n < $numberOfPlaceholders; $n++) { 167 $this->decorator->tablecell_open(1, null, 1); 168 $this->decorator->tablecell_close(1, null, 1); 169 } 170 $this->decorator->tablecell_open($colspan, $align, $rowspan); 171 } 172 173 function computePlaceholders($colspan, $rowspan) { 174 $totalNumberOfPlaceholders = 0; 175 do { 176 $cell = $this->row[$this->column]; 177 if ($cell->getRows() > 0) { 178 $numberOfPlaceholders = $cell->getCols(); 179 } else { 180 $numberOfPlaceholders = 0; 181 } 182 $this->column += $numberOfPlaceholders; 183 $totalNumberOfPlaceholders += $numberOfPlaceholders; 184 } while ($numberOfPlaceholders > 0); 185 $this->row[$this->column]->setSize($colspan, $rowspan); 186 $this->column += $colspan; 187 return $totalNumberOfPlaceholders; 188 } 189 190 function computeCLine() { 191 $lineIsPresent = false; 192 $column = 0; 193 194 do { 195 $cell = $this->row[$column]; 196 197 if ($cell->getRows() == 1 && !$lineIsPresent) { 198 $starts = $column + 1; 199 $lineIsPresent = true; 200 } 201 202 if ($cell->getRows() > 1 && $lineIsPresent) { 203 $this->decorator->table_cline($starts, $column); 204 $lineIsPresent = false; 205 } 206 207 $column += $cell->getCols(); 208 } while($column < sizeof($this->row)); 209 210 if ($lineIsPresent) { 211 $this->decorator->table_cline($starts, $column); 212 } 213 } 214 215 function computeNextLine() { 216 $row = []; 217 218 foreach($this->row as $cell) { 219 $nextCell = $cell->nextCellSize(); 220 $row[] = $nextCell; 221 } 222 223 $this->row = $row; 224 $this->column = 0; 225 } 226 227} 228