1
|
|
|
<?php |
2
|
|
|
/* |
3
|
|
|
* This plugin extends DokuWiki's list markup syntax to allow definition lists |
4
|
|
|
* and list items with multiple paragraphs. The complete syntax is as follows: |
5
|
|
|
* |
6
|
|
|
* |
7
|
|
|
* - ordered list item [<ol><li>] <!-- as standard syntax --> |
8
|
|
|
* * unordered list item [<ul><li>] <!-- as standard syntax --> |
9
|
|
|
* ? definition list term [<dl><dt>] |
10
|
|
|
* : definition list definition [<dl><dd>] |
11
|
|
|
* |
12
|
|
|
* -- ordered list item w/ multiple paragraphs |
13
|
|
|
* ** unordered list item w/ multiple paragraphs |
14
|
|
|
* :: definition list definition w/multiple paragraphs |
15
|
|
|
* .. new paragraph in --, **, or :: |
16
|
|
|
* |
17
|
|
|
* |
18
|
|
|
* Lists can be nested within lists, just as in the standard DokuWiki syntax. |
19
|
|
|
* |
20
|
|
|
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html) |
21
|
|
|
* @author Ben Slusky <[email protected]> |
22
|
|
|
* |
23
|
|
|
*/ |
24
|
|
|
class syntax_plugin_yalist extends DokuWiki_Syntax_Plugin { |
25
|
|
|
private $stack = array(); |
26
|
|
|
private static $odt_table_stack = array(); |
27
|
|
|
private static $odt_table_stack_index = 0; |
28
|
|
|
|
29
|
|
|
public function getType() { |
30
|
|
|
return 'container'; |
31
|
|
|
} |
32
|
|
|
|
33
|
|
|
public function getSort() { |
34
|
|
|
// just before listblock (10) |
35
|
|
|
return 9; |
36
|
|
|
} |
37
|
|
|
|
38
|
|
|
public function getPType() { |
39
|
|
|
return 'block'; |
40
|
|
|
} |
41
|
|
|
|
42
|
|
|
public function getAllowedTypes() { |
43
|
|
|
return array('substition', 'protected', 'disabled', 'formatting'); |
44
|
|
|
} |
45
|
|
|
|
46
|
|
|
public function connectTo($mode) { |
47
|
|
|
$this->Lexer->addEntryPattern('\n {2,}(?:--?|\*\*?|\?|::?)', $mode, 'plugin_yalist'); |
48
|
|
|
$this->Lexer->addEntryPattern('\n\t{1,}(?:--?|\*\*?|\?|::?)', $mode, 'plugin_yalist'); |
49
|
|
|
$this->Lexer->addPattern('\n {2,}(?:--?|\*\*?|\?|::?|\.\.)', 'plugin_yalist'); |
50
|
|
|
$this->Lexer->addPattern('\n\t{1,}(?:--?|\*\*?|\?|::?|\.\.)', 'plugin_yalist'); |
51
|
|
|
} |
52
|
|
|
|
53
|
|
|
public function postConnect() { |
54
|
|
|
$this->Lexer->addExitPattern('\n', 'plugin_yalist'); |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
public function handle($match, $state, $pos, Doku_Handler $handler) { |
58
|
|
|
$output = array(); |
59
|
|
|
$level = 0; |
60
|
|
|
switch ($state) { |
61
|
|
|
case DOKU_LEXER_ENTER: |
62
|
|
|
$frame = $this->interpretMatch($match); |
63
|
|
|
$level = $frame['level'] = 1; |
64
|
|
|
array_push($output, |
65
|
|
|
"${frame['list']}_open", |
66
|
|
|
"${frame['item']}_open", |
67
|
|
|
"${frame['item']}_content_open"); |
68
|
|
|
if ($frame['paras']) { |
69
|
|
|
array_push($output, 'p_open'); |
70
|
|
|
} |
71
|
|
|
array_push($this->stack, $frame); |
72
|
|
|
break; |
73
|
|
|
case DOKU_LEXER_EXIT: |
74
|
|
|
$close_content = true; |
75
|
|
|
while ($frame = array_pop($this->stack)) { |
76
|
|
|
// for the first frame we pop off the stack, we'll need to |
77
|
|
|
// close the content tag; for the rest it will have been |
78
|
|
|
// closed already |
79
|
|
|
if ($close_content) { |
80
|
|
|
if ($frame['paras']) { |
81
|
|
|
array_push($output, 'p_close'); |
82
|
|
|
} |
83
|
|
|
array_push($output, "${frame['item']}_content_close"); |
84
|
|
|
$close_content = false; |
85
|
|
|
} |
86
|
|
|
array_push($output, |
87
|
|
|
"${frame['item']}_close", |
88
|
|
|
"${frame['list']}_close"); |
89
|
|
|
} |
90
|
|
|
break; |
91
|
|
|
case DOKU_LEXER_MATCHED: |
92
|
|
|
$last_frame = end($this->stack); |
93
|
|
|
if (substr($match, -2) == '..') { |
94
|
|
|
// new paragraphs cannot be deeper than the current depth, |
95
|
|
|
// but they may be shallower |
96
|
|
|
$para_depth = count(explode(' ', str_replace("\t", ' ', $match))); |
97
|
|
|
$close_content = true; |
98
|
|
View Code Duplication |
while ($para_depth < $last_frame['depth'] && count($this->stack) > 1) { |
|
|
|
|
99
|
|
|
if ($close_content) { |
100
|
|
|
if ($last_frame['paras']) { |
101
|
|
|
array_push($output, 'p_close'); |
102
|
|
|
} |
103
|
|
|
array_push($output, "${last_frame['item']}_content_close"); |
104
|
|
|
$close_content = false; |
105
|
|
|
} |
106
|
|
|
array_push($output, |
107
|
|
|
"${last_frame['item']}_close", |
108
|
|
|
"${last_frame['list']}_close"); |
109
|
|
|
array_pop($this->stack); |
110
|
|
|
$last_frame = end($this->stack); |
111
|
|
|
} |
112
|
|
|
if ($last_frame['paras']) { |
113
|
|
|
if ($close_content) { |
114
|
|
|
// depth did not change |
115
|
|
|
array_push($output, 'p_close', 'p_open'); |
116
|
|
|
} else { |
117
|
|
|
array_push($output, |
118
|
|
|
"${last_frame['item']}_content_open", |
119
|
|
|
'p_open'); |
120
|
|
|
} |
121
|
|
|
} else { |
122
|
|
|
// let's just pretend we didn't match... |
123
|
|
|
$state = DOKU_LEXER_UNMATCHED; |
124
|
|
|
$output = $match; |
125
|
|
|
} |
126
|
|
|
break; |
127
|
|
|
} |
128
|
|
|
$curr_frame = $this->interpretMatch($match); |
129
|
|
|
if ($curr_frame['depth'] > $last_frame['depth']) { |
130
|
|
|
// going one level deeper |
131
|
|
|
$level = $last_frame['level'] + 1; |
132
|
|
|
if ($last_frame['paras']) { |
133
|
|
|
array_push($output, 'p_close'); |
134
|
|
|
} |
135
|
|
|
array_push($output, |
136
|
|
|
"${last_frame['item']}_content_close", |
137
|
|
|
"${curr_frame['list']}_open"); |
138
|
|
|
} else { |
139
|
|
|
// same depth, or getting shallower |
140
|
|
|
$close_content = true; |
141
|
|
|
// keep popping frames off the stack until we find a frame |
142
|
|
|
// that's at least as deep as this one, or until only the |
143
|
|
|
// bottom frame (i.e. the initial list markup) remains |
144
|
|
View Code Duplication |
while ($curr_frame['depth'] < $last_frame['depth'] && |
|
|
|
|
145
|
|
|
count($this->stack) > 1) |
146
|
|
|
{ |
147
|
|
|
// again, we need to close the content tag only for |
148
|
|
|
// the first frame popped off the stack |
149
|
|
|
if ($close_content) { |
150
|
|
|
if ($last_frame['paras']) { |
151
|
|
|
array_push($output, 'p_close'); |
152
|
|
|
} |
153
|
|
|
array_push($output, "${last_frame['item']}_content_close"); |
154
|
|
|
$close_content = false; |
155
|
|
|
} |
156
|
|
|
array_push($output, |
157
|
|
|
"${last_frame['item']}_close", |
158
|
|
|
"${last_frame['list']}_close"); |
159
|
|
|
array_pop($this->stack); |
160
|
|
|
$last_frame = end($this->stack); |
161
|
|
|
} |
162
|
|
|
// pull the last frame off the stack; |
163
|
|
|
// it will be replaced by the current frame |
164
|
|
|
array_pop($this->stack); |
165
|
|
|
$level = $last_frame['level']; |
166
|
|
|
if ($close_content) { |
167
|
|
|
if ($last_frame['paras']) { |
168
|
|
|
array_push($output, 'p_close'); |
169
|
|
|
} |
170
|
|
|
array_push($output, "${last_frame['item']}_content_close"); |
171
|
|
|
$close_content = false; |
|
|
|
|
172
|
|
|
} |
173
|
|
|
array_push($output, "${last_frame['item']}_close"); |
174
|
|
|
if ($curr_frame['list'] != $last_frame['list']) { |
175
|
|
|
// change list types |
176
|
|
|
array_push($output, |
177
|
|
|
"${last_frame['list']}_close", |
178
|
|
|
"${curr_frame['list']}_open"); |
179
|
|
|
} |
180
|
|
|
} |
181
|
|
|
// and finally, open tags for the new list item |
182
|
|
|
array_push($output, |
183
|
|
|
"${curr_frame['item']}_open", |
184
|
|
|
"${curr_frame['item']}_content_open"); |
185
|
|
|
if ($curr_frame['paras']) { |
186
|
|
|
array_push($output, 'p_open'); |
187
|
|
|
} |
188
|
|
|
$curr_frame['level'] = $level; |
189
|
|
|
array_push($this->stack, $curr_frame); |
190
|
|
|
break; |
191
|
|
|
case DOKU_LEXER_UNMATCHED: |
192
|
|
|
$output = $match; |
193
|
|
|
break; |
194
|
|
|
} |
195
|
|
|
return array('state' => $state, 'output' => $output, 'level' => $level); |
196
|
|
|
} |
197
|
|
|
|
198
|
|
|
private function interpretMatch($match) { |
199
|
|
|
$tag_table = array( |
200
|
|
|
'*' => 'u_li', |
201
|
|
|
'-' => 'o_li', |
202
|
|
|
'?' => 'dt', |
203
|
|
|
':' => 'dd', |
204
|
|
|
); |
205
|
|
|
$tag = $tag_table[substr($match, -1)]; |
206
|
|
|
return array( |
207
|
|
|
'depth' => count(explode(' ', str_replace("\t", ' ', $match))), |
208
|
|
|
'list' => substr($tag, 0, 1) . 'l', |
209
|
|
|
'item' => substr($tag, -2), |
210
|
|
|
'paras' => (substr($match, -1) == substr($match, -2, 1)), |
211
|
|
|
); |
212
|
|
|
} |
213
|
|
|
|
214
|
|
|
public function render($mode, Doku_Renderer $renderer, $data) { |
215
|
|
|
if ($mode != 'xhtml' && $mode != 'latex' && $mode != 'odt') { |
216
|
|
|
return false; |
217
|
|
|
} |
218
|
|
|
if ($data['state'] == DOKU_LEXER_UNMATCHED) { |
219
|
|
|
if ($mode != 'odt') { |
220
|
|
|
$renderer->doc .= $renderer->_xmlEntities($data['output']); |
221
|
|
|
} else { |
222
|
|
|
$renderer->cdata($data['output']); |
223
|
|
|
} |
224
|
|
|
return true; |
225
|
|
|
} |
226
|
|
|
foreach ($data['output'] as $i) { |
227
|
|
|
switch ($mode) { |
228
|
|
|
case 'xhtml': |
229
|
|
|
$this->renderXhtmlItem($renderer, $i, $data); |
230
|
|
|
break; |
231
|
|
|
case 'latex': |
232
|
|
|
$this->renderLatexItem($renderer, $i, $data); |
233
|
|
|
break; |
234
|
|
|
case 'odt': |
235
|
|
|
$this->renderOdtItem($renderer, $i, $data); |
236
|
|
|
break; |
237
|
|
|
} |
238
|
|
|
} |
239
|
|
|
if ($data['state'] == DOKU_LEXER_EXIT) { |
240
|
|
|
if ($mode != 'odt') { |
241
|
|
|
$renderer->doc .= "\n"; |
242
|
|
|
} else { |
243
|
|
|
$renderer->linebreak(); |
244
|
|
|
} |
245
|
|
|
} |
246
|
|
|
return true; |
247
|
|
|
} |
248
|
|
|
|
249
|
|
|
private function renderXhtmlItem(Doku_Renderer $renderer, $item, $data) { |
250
|
|
|
$markup = ''; |
251
|
|
|
switch ($item) { |
252
|
|
|
case 'ol_open': |
253
|
|
|
$markup = "<ol>\n"; |
254
|
|
|
break; |
255
|
|
|
case 'ol_close': |
256
|
|
|
$markup = "</ol>\n"; |
257
|
|
|
break; |
258
|
|
|
case 'ul_open': |
259
|
|
|
$markup = "<ul>\n"; |
260
|
|
|
break; |
261
|
|
|
case 'ul_close': |
262
|
|
|
$markup = "</ul>\n"; |
263
|
|
|
break; |
264
|
|
|
case 'dl_open': |
265
|
|
|
$markup = "<dl>\n"; |
266
|
|
|
break; |
267
|
|
|
case 'dl_close': |
268
|
|
|
$markup = "</dl>\n"; |
269
|
|
|
break; |
270
|
|
|
case 'li_open': |
271
|
|
|
$markup = "<li class=\"level${data['level']}\">"; |
272
|
|
|
break; |
273
|
|
|
case 'li_content_open': |
274
|
|
|
$markup = "<div class=\"li\">\n"; |
275
|
|
|
break; |
276
|
|
|
case 'li_content_close': |
277
|
|
|
$markup = "\n</div>"; |
278
|
|
|
break; |
279
|
|
|
case 'li_close': |
280
|
|
|
$markup = "</li>\n"; |
281
|
|
|
break; |
282
|
|
|
case 'dt_open': |
283
|
|
|
$markup = "<dt class=\"level${data['level']}\">"; |
284
|
|
|
break; |
285
|
|
|
case 'dt_content_open': |
286
|
|
|
$markup = "<span class=\"dt\">"; |
287
|
|
|
break; |
288
|
|
|
case 'dt_content_close': |
289
|
|
|
$markup = "</span>"; |
290
|
|
|
break; |
291
|
|
|
case 'dt_close': |
292
|
|
|
$markup = "</dt>\n"; |
293
|
|
|
break; |
294
|
|
|
case 'dd_open': |
295
|
|
|
$markup = "<dd class=\"level${data['level']}\">"; |
296
|
|
|
break; |
297
|
|
|
case 'dd_content_open': |
298
|
|
|
$markup = "<div class=\"dd\">\n"; |
299
|
|
|
break; |
300
|
|
|
case 'dd_content_close': |
301
|
|
|
$markup = "\n</div>"; |
302
|
|
|
break; |
303
|
|
|
case 'dd_close': |
304
|
|
|
$markup = "</dd>\n"; |
305
|
|
|
break; |
306
|
|
|
case 'p_open': |
307
|
|
|
$markup = "<p>\n"; |
308
|
|
|
break; |
309
|
|
|
case 'p_close': |
310
|
|
|
$markup = "\n</p>"; |
311
|
|
|
break; |
312
|
|
|
} |
313
|
|
|
$renderer->doc .= $markup; |
314
|
|
|
} |
315
|
|
|
|
316
|
|
|
private function renderLatexItem(Doku_Renderer $renderer, $item) { |
317
|
|
|
$markup = ''; |
318
|
|
|
switch ($item) { |
319
|
|
|
case 'ol_open': |
320
|
|
|
$markup = "\\begin{enumerate}\n"; |
321
|
|
|
break; |
322
|
|
|
case 'ol_close': |
323
|
|
|
$markup = "\\end{enumerate}\n"; |
324
|
|
|
break; |
325
|
|
|
case 'ul_open': |
326
|
|
|
$markup = "\\begin{itemize}\n"; |
327
|
|
|
break; |
328
|
|
|
case 'ul_close': |
329
|
|
|
$markup = "\\end{itemize}\n"; |
330
|
|
|
break; |
331
|
|
|
case 'dl_open': |
332
|
|
|
$markup = "\\begin{description}\n"; |
333
|
|
|
break; |
334
|
|
|
case 'dl_close': |
335
|
|
|
$markup = "\\end{description}\n"; |
336
|
|
|
break; |
337
|
|
|
case 'li_open': |
338
|
|
|
$markup = "\item "; |
339
|
|
|
break; |
340
|
|
|
case 'li_content_open': |
341
|
|
|
break; |
342
|
|
|
case 'li_content_close': |
343
|
|
|
break; |
344
|
|
|
case 'li_close': |
345
|
|
|
$markup = "\n"; |
346
|
|
|
break; |
347
|
|
|
case 'dt_open': |
348
|
|
|
$markup = "\item["; |
349
|
|
|
break; |
350
|
|
|
case 'dt_content_open': |
351
|
|
|
break; |
352
|
|
|
case 'dt_content_close': |
353
|
|
|
break; |
354
|
|
|
case 'dt_close': |
355
|
|
|
$markup = "] "; |
356
|
|
|
break; |
357
|
|
|
case 'dd_open': |
358
|
|
|
break; |
359
|
|
|
case 'dd_content_open': |
360
|
|
|
break; |
361
|
|
|
case 'dd_content_close': |
362
|
|
|
break; |
363
|
|
|
case 'dd_close': |
364
|
|
|
$markup = "\n"; |
365
|
|
|
break; |
366
|
|
|
case 'p_open': |
367
|
|
|
$markup = "\n"; |
368
|
|
|
break; |
369
|
|
|
case 'p_close': |
370
|
|
|
$markup = "\n"; |
371
|
|
|
break; |
372
|
|
|
} |
373
|
|
|
$renderer->doc .= $markup; |
374
|
|
|
} |
375
|
|
|
|
376
|
|
|
/** |
377
|
|
|
* Render yalist items for ODT format |
378
|
|
|
* |
379
|
|
|
* @param Doku_Renderer $renderer The current renderer object |
380
|
|
|
* @param string $item The item to render |
381
|
|
|
* |
382
|
|
|
* @author LarsDW223 |
383
|
|
|
*/ |
384
|
|
|
private function renderOdtItem(Doku_Renderer $renderer, $item) { |
385
|
|
|
switch ($item) { |
386
|
|
|
case 'ol_open': |
387
|
|
|
$renderer->listo_open(); |
388
|
|
|
break; |
389
|
|
|
case 'ul_open': |
390
|
|
|
$renderer->listu_open(); |
391
|
|
|
break; |
392
|
|
|
case 'dl_open': |
393
|
|
|
if ($this->getConf('def_list_odt_export') != 'table') { |
394
|
|
|
$renderer->listu_open(); |
395
|
|
|
} else { |
396
|
|
|
$renderer->table_open(2); |
397
|
|
|
} |
398
|
|
|
self::$odt_table_stack [self::$odt_table_stack_index] = array(); |
399
|
|
|
self::$odt_table_stack [self::$odt_table_stack_index]['itemOpen'] = false; |
400
|
|
|
self::$odt_table_stack [self::$odt_table_stack_index]['dtState'] = 0; |
401
|
|
|
self::$odt_table_stack [self::$odt_table_stack_index]['ddState'] = 0; |
402
|
|
|
self::$odt_table_stack_index++; |
403
|
|
|
break; |
404
|
|
|
case 'ol_close': |
405
|
|
|
case 'ul_close': |
406
|
|
|
$renderer->list_close(); |
407
|
|
|
break; |
408
|
|
|
case 'dl_close': |
409
|
|
|
$config = $this->getConf('def_list_odt_export'); |
410
|
|
|
if ($config != 'table') { |
411
|
|
|
if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['ddState'] != 2) { |
412
|
|
|
if ($config == 'listheader' && method_exists($renderer, 'listheader_close')) { |
413
|
|
|
$renderer->listheader_close(); |
414
|
|
|
} else { |
415
|
|
|
$renderer->listitem_close(); |
416
|
|
|
} |
417
|
|
|
} |
418
|
|
|
self::$odt_table_stack [self::$odt_table_stack_index - 1]['ddState'] = 0; |
419
|
|
|
$renderer->list_close(); |
420
|
|
|
} else { |
421
|
|
View Code Duplication |
if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['ddState'] == 0) { |
|
|
|
|
422
|
|
|
$properties = array(); |
423
|
|
|
$properties ['border'] = 'none'; |
424
|
|
|
$renderer->_odtTableCellOpenUseProperties($properties); |
425
|
|
|
$renderer->tablecell_close(); |
426
|
|
|
} |
427
|
|
|
self::$odt_table_stack [self::$odt_table_stack_index - 1]['ddState'] = 0; |
428
|
|
|
if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] === true) { |
429
|
|
|
$renderer->tablerow_close(1); |
430
|
|
|
self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] = false; |
431
|
|
|
} |
432
|
|
|
$renderer->table_close(); |
433
|
|
|
} |
434
|
|
|
if (self::$odt_table_stack_index > 0) { |
435
|
|
|
self::$odt_table_stack_index--; |
436
|
|
|
unset(self::$odt_table_stack [self::$odt_table_stack_index]); |
437
|
|
|
} |
438
|
|
|
break; |
439
|
|
|
|
440
|
|
|
case 'li_open': |
441
|
|
|
$renderer->listitem_open(1); |
442
|
|
|
break; |
443
|
|
|
case 'li_content_open': |
444
|
|
|
$renderer->listcontent_open(); |
445
|
|
|
break; |
446
|
|
|
case 'li_content_close': |
447
|
|
|
$renderer->listcontent_close(); |
448
|
|
|
break; |
449
|
|
|
case 'li_close': |
450
|
|
|
$renderer->listitem_close(); |
451
|
|
|
break; |
452
|
|
|
|
453
|
|
|
case 'dt_open': // unconditional: DT tags can't contain paragraphs. That would not be legal XHTML. |
454
|
|
|
switch ($this->getConf('def_list_odt_export')) { |
455
|
|
|
case 'listheader': |
456
|
|
|
if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] === true) { |
457
|
|
|
if (method_exists($renderer, 'listheader_close')) { |
458
|
|
|
$renderer->listheader_close(); |
459
|
|
|
} else { |
460
|
|
|
$renderer->listitem_close(); |
461
|
|
|
} |
462
|
|
|
self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] = false; |
463
|
|
|
} |
464
|
|
|
if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] === false) { |
465
|
|
|
if (method_exists($renderer, 'listheader_open')) { |
466
|
|
|
$renderer->listheader_open(1); |
467
|
|
|
} else { |
468
|
|
|
$renderer->listitem_open(1); |
469
|
|
|
} |
470
|
|
|
self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] = true; |
471
|
|
|
} |
472
|
|
|
break; |
473
|
|
|
case 'table': |
474
|
|
View Code Duplication |
if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['ddState'] == 0) { |
|
|
|
|
475
|
|
|
$properties = array(); |
476
|
|
|
$properties ['border'] = 'none'; |
477
|
|
|
$renderer->_odtTableCellOpenUseProperties($properties); |
478
|
|
|
$renderer->tablecell_close(); |
479
|
|
|
} |
480
|
|
|
|
481
|
|
|
if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] === true) { |
482
|
|
|
$renderer->tablerow_close(); |
483
|
|
|
self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] = false; |
484
|
|
|
} |
485
|
|
|
if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] === false) { |
486
|
|
|
$renderer->tablerow_open(1); |
487
|
|
|
self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] = true; |
488
|
|
|
} |
489
|
|
|
$properties = array(); |
490
|
|
|
$properties ['border'] = 'none'; |
491
|
|
|
$renderer->_odtTableCellOpenUseProperties($properties); |
492
|
|
|
break; |
493
|
|
|
default: |
494
|
|
|
if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] === true) { |
495
|
|
|
$renderer->listitem_close(); |
496
|
|
|
self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] = false; |
497
|
|
|
} |
498
|
|
|
if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] === false) { |
499
|
|
|
$renderer->listitem_open(1); |
500
|
|
|
self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] = true; |
501
|
|
|
} |
502
|
|
|
break; |
503
|
|
|
} |
504
|
|
|
self::$odt_table_stack [self::$odt_table_stack_index - 1]['dtState'] = 1; |
505
|
|
|
self::$odt_table_stack [self::$odt_table_stack_index - 1]['ddState'] = 0; |
506
|
|
|
break; |
507
|
|
|
case 'dd_open': |
508
|
|
|
switch ($this->getConf('def_list_odt_export')) { |
509
|
|
View Code Duplication |
case 'listheader': |
|
|
|
|
510
|
|
|
if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] === false) { |
511
|
|
|
if (method_exists($renderer, 'listheader_open')) { |
512
|
|
|
$renderer->listheader_open(1); |
513
|
|
|
} else { |
514
|
|
|
$renderer->listitem_open(1); |
515
|
|
|
} |
516
|
|
|
self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] = true; |
517
|
|
|
} |
518
|
|
|
break; |
519
|
|
|
case 'table': |
520
|
|
|
if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] === false) { |
521
|
|
|
$renderer->tablerow_open(1); |
522
|
|
|
self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] = true; |
523
|
|
|
} |
524
|
|
|
if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['dtState'] == 1) { |
525
|
|
|
$renderer->tablecell_close(); |
526
|
|
|
} |
527
|
|
View Code Duplication |
if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['dtState'] == 0) { |
|
|
|
|
528
|
|
|
$properties = array(); |
529
|
|
|
$properties ['border'] = 'none'; |
530
|
|
|
$renderer->_odtTableCellOpenUseProperties($properties); |
531
|
|
|
$renderer->tablecell_close(); |
532
|
|
|
} |
533
|
|
|
|
534
|
|
|
$properties = array(); |
535
|
|
|
$properties ['border'] = 'none'; |
536
|
|
|
$renderer->_odtTableCellOpenUseProperties($properties); |
537
|
|
|
break; |
538
|
|
View Code Duplication |
default: |
|
|
|
|
539
|
|
|
if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] === false) { |
540
|
|
|
$renderer->listitem_open(1); |
541
|
|
|
self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] = true; |
542
|
|
|
} |
543
|
|
|
break; |
544
|
|
|
} |
545
|
|
|
self::$odt_table_stack [self::$odt_table_stack_index - 1]['dtState'] = 0; |
546
|
|
|
self::$odt_table_stack [self::$odt_table_stack_index - 1]['ddState'] = 1; |
547
|
|
|
break; |
548
|
|
|
case 'dt_content_open': |
549
|
|
|
switch ($this->getConf('def_list_odt_export')) { |
550
|
|
|
case 'table': |
551
|
|
|
$renderer->p_open(); |
552
|
|
|
break; |
553
|
|
|
default: |
554
|
|
|
$renderer->listcontent_open(); |
555
|
|
|
break; |
556
|
|
|
} |
557
|
|
|
$this->renderODTOpenSpan($renderer); |
558
|
|
|
break; |
559
|
|
|
case 'dd_content_open': |
560
|
|
|
switch ($this->getConf('def_list_odt_export')) { |
561
|
|
|
case 'table': |
562
|
|
|
$renderer->p_open(); |
563
|
|
|
break; |
564
|
|
|
default: |
565
|
|
|
$renderer->listcontent_open(); |
566
|
|
|
break; |
567
|
|
|
} |
568
|
|
|
break; |
569
|
|
|
case 'dt_content_close': |
570
|
|
|
$this->renderODTCloseSpan($renderer); |
571
|
|
|
switch ($this->getConf('def_list_odt_export')) { |
572
|
|
|
case 'table': |
573
|
|
|
$renderer->p_close(); |
574
|
|
|
break; |
575
|
|
|
default: |
576
|
|
|
$renderer->listcontent_close(); |
577
|
|
|
break; |
578
|
|
|
} |
579
|
|
|
break; |
580
|
|
|
case 'dd_content_close': |
581
|
|
|
switch ($this->getConf('def_list_odt_export')) { |
582
|
|
|
case 'table': |
583
|
|
|
$renderer->p_close(); |
584
|
|
|
break; |
585
|
|
|
default: |
586
|
|
|
$renderer->listcontent_close(); |
587
|
|
|
break; |
588
|
|
|
} |
589
|
|
|
break; |
590
|
|
|
case 'dt_close': |
591
|
|
|
switch ($this->getConf('def_list_odt_export')) { |
592
|
|
|
case 'listheader': |
593
|
|
|
$renderer->linebreak(); |
594
|
|
|
break; |
595
|
|
|
case 'table': |
596
|
|
|
$renderer->tablecell_close(); |
597
|
|
|
self::$odt_table_stack [self::$odt_table_stack_index - 1]['dtState'] = 2; |
598
|
|
|
break; |
599
|
|
|
default: |
600
|
|
|
$renderer->linebreak(); |
601
|
|
|
break; |
602
|
|
|
} |
603
|
|
|
break; |
604
|
|
|
|
605
|
|
|
case 'dd_close': |
606
|
|
|
switch ($this->getConf('def_list_odt_export')) { |
607
|
|
View Code Duplication |
case 'listheader': |
|
|
|
|
608
|
|
|
if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] === true) { |
609
|
|
|
if (method_exists($renderer, 'listheader_close')) { |
610
|
|
|
$renderer->listheader_close(); |
611
|
|
|
} else { |
612
|
|
|
$renderer->listitem_close(); |
613
|
|
|
} |
614
|
|
|
self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] = false; |
615
|
|
|
} |
616
|
|
|
break; |
617
|
|
|
case 'table': |
618
|
|
|
$renderer->tablecell_close(); |
619
|
|
|
if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] === true) { |
620
|
|
|
$renderer->tablerow_close(1); |
621
|
|
|
self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] = false; |
622
|
|
|
} |
623
|
|
|
break; |
624
|
|
View Code Duplication |
default: |
|
|
|
|
625
|
|
|
if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] === true) { |
626
|
|
|
$renderer->listitem_close(1); |
627
|
|
|
self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] = false; |
628
|
|
|
} |
629
|
|
|
break; |
630
|
|
|
} |
631
|
|
|
self::$odt_table_stack [self::$odt_table_stack_index - 1]['dtState'] = 0; |
632
|
|
|
self::$odt_table_stack [self::$odt_table_stack_index - 1]['ddState'] = 2; |
633
|
|
|
break; |
634
|
|
|
|
635
|
|
|
case 'p_open': |
636
|
|
|
$renderer->p_open(); |
637
|
|
|
break; |
638
|
|
|
case 'p_close': |
639
|
|
|
$renderer->p_close(); |
640
|
|
|
break; |
641
|
|
|
} |
642
|
|
|
} |
643
|
|
|
|
644
|
|
|
/** |
645
|
|
|
* Open ODT span for rendering of dt-content |
646
|
|
|
* |
647
|
|
|
* @param Doku_Renderer $renderer The current renderer object |
648
|
|
|
* |
649
|
|
|
* @author LarsDW223 |
650
|
|
|
*/ |
651
|
|
|
private function renderODTOpenSpan($renderer) { |
652
|
|
|
$properties = array(); |
653
|
|
|
|
654
|
|
|
// Get CSS properties for ODT export. |
655
|
|
|
$renderer->getODTProperties($properties, 'div', 'dokuwiki dt', NULL); |
656
|
|
|
|
657
|
|
|
$renderer->_odtSpanOpenUseProperties($properties); |
658
|
|
|
} |
659
|
|
|
|
660
|
|
|
/** |
661
|
|
|
* Close ODT span for rendering of dt-content |
662
|
|
|
* |
663
|
|
|
* @param Doku_Renderer $renderer The current renderer object |
664
|
|
|
* |
665
|
|
|
* @author LarsDW223 |
666
|
|
|
*/ |
667
|
|
|
private function renderODTCloseSpan($renderer) { |
668
|
|
|
if (method_exists($renderer, '_odtSpanClose') === false) { |
669
|
|
|
// Function is not supported by installed ODT plugin version, return. |
670
|
|
|
return; |
671
|
|
|
} |
672
|
|
|
$renderer->_odtSpanClose(); |
673
|
|
|
} |
674
|
|
|
} |
675
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.