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