1070bd191SMark Prins<?php 2f0f4f9f3SMark Prins 3*bb527396Sgithub-actions[bot]use dokuwiki\Parsing\Handler; 4036867b5Sgithub-actions[bot]use dokuwiki\Extension\SyntaxPlugin; 5036867b5Sgithub-actions[bot] 6070bd191SMark Prins/* 7070bd191SMark Prins * This plugin extends DokuWiki's list markup syntax to allow definition lists 8070bd191SMark Prins * and list items with multiple paragraphs. The complete syntax is as follows: 9070bd191SMark Prins * 10070bd191SMark Prins * 11070bd191SMark Prins * - ordered list item [<ol><li>] <!-- as standard syntax --> 12070bd191SMark Prins * * unordered list item [<ul><li>] <!-- as standard syntax --> 13070bd191SMark Prins * ? definition list term [<dl><dt>] 14070bd191SMark Prins * : definition list definition [<dl><dd>] 15070bd191SMark Prins * 16070bd191SMark Prins * -- ordered list item w/ multiple paragraphs 17070bd191SMark Prins * ** unordered list item w/ multiple paragraphs 18070bd191SMark Prins * :: definition list definition w/multiple paragraphs 19070bd191SMark Prins * .. new paragraph in --, **, or :: 20070bd191SMark Prins * 21070bd191SMark Prins * 22070bd191SMark Prins * Lists can be nested within lists, just as in the standard DokuWiki syntax. 23070bd191SMark Prins * 24070bd191SMark Prins * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 25070bd191SMark Prins * @author Ben Slusky <sluskyb@paranoiacs.org> 26070bd191SMark Prins * 27393d524aSMark Prins * @phpcs:disable Squiz.Classes.ValidClassName.NotPascalCase 28070bd191SMark Prins */ 29036867b5Sgithub-actions[bot]class syntax_plugin_yalist extends SyntaxPlugin 30036867b5Sgithub-actions[bot]{ 31393d524aSMark Prins private static array $odt_table_stack = []; 32393d524aSMark Prins private static int $odt_table_stack_index = 0; 33393d524aSMark Prins private array $stack = []; 34249fbbd1SLarsDW223 35036867b5Sgithub-actions[bot] public function getType() 36036867b5Sgithub-actions[bot] { 37070bd191SMark Prins return 'container'; 38070bd191SMark Prins } 390ec8e935SMark Prins 40036867b5Sgithub-actions[bot] public function getSort() 41036867b5Sgithub-actions[bot] { 42070bd191SMark Prins // just before listblock (10) 43070bd191SMark Prins return 9; 44070bd191SMark Prins } 450ec8e935SMark Prins 46036867b5Sgithub-actions[bot] public function getPType() 47036867b5Sgithub-actions[bot] { 48070bd191SMark Prins return 'block'; 49070bd191SMark Prins } 500ec8e935SMark Prins 51036867b5Sgithub-actions[bot] public function getAllowedTypes() 52036867b5Sgithub-actions[bot] { 53036867b5Sgithub-actions[bot] return ['substition', 'protected', 'disabled', 'formatting']; 54070bd191SMark Prins } 550ec8e935SMark Prins 56036867b5Sgithub-actions[bot] public function connectTo($mode) 57036867b5Sgithub-actions[bot] { 58070bd191SMark Prins $this->Lexer->addEntryPattern('\n {2,}(?:--?|\*\*?|\?|::?)', $mode, 'plugin_yalist'); 59070bd191SMark Prins $this->Lexer->addEntryPattern('\n\t{1,}(?:--?|\*\*?|\?|::?)', $mode, 'plugin_yalist'); 60070bd191SMark Prins $this->Lexer->addPattern('\n {2,}(?:--?|\*\*?|\?|::?|\.\.)', 'plugin_yalist'); 61070bd191SMark Prins $this->Lexer->addPattern('\n\t{1,}(?:--?|\*\*?|\?|::?|\.\.)', 'plugin_yalist'); 62070bd191SMark Prins } 630ec8e935SMark Prins 64036867b5Sgithub-actions[bot] public function postConnect() 65036867b5Sgithub-actions[bot] { 66070bd191SMark Prins $this->Lexer->addExitPattern('\n', 'plugin_yalist'); 67070bd191SMark Prins } 680ec8e935SMark Prins 69*bb527396Sgithub-actions[bot] public function handle($match, $state, $pos, Handler $handler) 70036867b5Sgithub-actions[bot] { 71036867b5Sgithub-actions[bot] $output = []; 72070bd191SMark Prins $level = 0; 73070bd191SMark Prins switch ($state) { 74070bd191SMark Prins case DOKU_LEXER_ENTER: 750ec8e935SMark Prins $frame = $this->interpretMatch($match); 76070bd191SMark Prins $level = $frame['level'] = 1; 77393d524aSMark Prins $output[] = "{$frame['list']}_open"; 78393d524aSMark Prins $output[] = "{$frame['item']}_open"; 79393d524aSMark Prins $output[] = "{$frame['item']}_content_open"; 806a2cc237SScrutinizer Auto-Fixer if ($frame['paras']) { 81036867b5Sgithub-actions[bot] $output[] = 'p_open'; 826a2cc237SScrutinizer Auto-Fixer } 83036867b5Sgithub-actions[bot] $this->stack[] = $frame; 84070bd191SMark Prins break; 85070bd191SMark Prins case DOKU_LEXER_EXIT: 86070bd191SMark Prins $close_content = true; 87070bd191SMark Prins while ($frame = array_pop($this->stack)) { 88070bd191SMark Prins // for the first frame we pop off the stack, we'll need to 89070bd191SMark Prins // close the content tag; for the rest it will have been 90070bd191SMark Prins // closed already 91070bd191SMark Prins if ($close_content) { 92665315f8SScrutinizer Auto-Fixer if ($frame['paras']) { 93036867b5Sgithub-actions[bot] $output[] = 'p_close'; 94665315f8SScrutinizer Auto-Fixer } 95393d524aSMark Prins $output[] = "{$frame['item']}_content_close"; 96070bd191SMark Prins $close_content = false; 97070bd191SMark Prins } 98393d524aSMark Prins $output[] = "{$frame['item']}_close"; 99393d524aSMark Prins $output[] = "{$frame['list']}_close"; 100070bd191SMark Prins } 101070bd191SMark Prins break; 102070bd191SMark Prins case DOKU_LEXER_MATCHED: 103070bd191SMark Prins $last_frame = end($this->stack); 104393d524aSMark Prins if (str_ends_with($match, '..')) { 105070bd191SMark Prins // new paragraphs cannot be deeper than the current depth, 106070bd191SMark Prins // but they may be shallower 107070bd191SMark Prins $para_depth = count(explode(' ', str_replace("\t", ' ', $match))); 108070bd191SMark Prins $close_content = true; 109db15290dSMark Prins while ($para_depth < $last_frame['depth'] && count($this->stack) > 1) { 110070bd191SMark Prins if ($close_content) { 111665315f8SScrutinizer Auto-Fixer if ($last_frame['paras']) { 112036867b5Sgithub-actions[bot] $output[] = 'p_close'; 113665315f8SScrutinizer Auto-Fixer } 114393d524aSMark Prins $output[] = "{$last_frame['item']}_content_close"; 115070bd191SMark Prins $close_content = false; 116070bd191SMark Prins } 117393d524aSMark Prins $output[] = "{$last_frame['item']}_close"; 118393d524aSMark Prins $output[] = "{$last_frame['list']}_close"; 119070bd191SMark Prins array_pop($this->stack); 120070bd191SMark Prins $last_frame = end($this->stack); 121070bd191SMark Prins } 122070bd191SMark Prins if ($last_frame['paras']) { 1236a2cc237SScrutinizer Auto-Fixer if ($close_content) { 124070bd191SMark Prins // depth did not change 125036867b5Sgithub-actions[bot] $output[] = 'p_close'; 126036867b5Sgithub-actions[bot] $output[] = 'p_open'; 1276a2cc237SScrutinizer Auto-Fixer } else { 128393d524aSMark Prins $output[] = "{$last_frame['item']}_content_open"; 129036867b5Sgithub-actions[bot] $output[] = 'p_open'; 1306a2cc237SScrutinizer Auto-Fixer } 131070bd191SMark Prins } else { 132070bd191SMark Prins // let's just pretend we didn't match... 133070bd191SMark Prins $state = DOKU_LEXER_UNMATCHED; 134070bd191SMark Prins $output = $match; 135070bd191SMark Prins } 136070bd191SMark Prins break; 137070bd191SMark Prins } 1380ec8e935SMark Prins $curr_frame = $this->interpretMatch($match); 139070bd191SMark Prins if ($curr_frame['depth'] > $last_frame['depth']) { 140070bd191SMark Prins // going one level deeper 141070bd191SMark Prins $level = $last_frame['level'] + 1; 142665315f8SScrutinizer Auto-Fixer if ($last_frame['paras']) { 143036867b5Sgithub-actions[bot] $output[] = 'p_close'; 144665315f8SScrutinizer Auto-Fixer } 145393d524aSMark Prins $output[] = "{$last_frame['item']}_content_close"; 146393d524aSMark Prins $output[] = "{$curr_frame['list']}_open"; 147070bd191SMark Prins } else { 148070bd191SMark Prins // same depth, or getting shallower 149070bd191SMark Prins $close_content = true; 150070bd191SMark Prins // keep popping frames off the stack until we find a frame 151070bd191SMark Prins // that's at least as deep as this one, or until only the 152070bd191SMark Prins // bottom frame (i.e. the initial list markup) remains 153036867b5Sgithub-actions[bot] while ( 154036867b5Sgithub-actions[bot] $curr_frame['depth'] < $last_frame['depth'] && 155036867b5Sgithub-actions[bot] count($this->stack) > 1 156036867b5Sgithub-actions[bot] ) { 157070bd191SMark Prins // again, we need to close the content tag only for 158070bd191SMark Prins // the first frame popped off the stack 159070bd191SMark Prins if ($close_content) { 160665315f8SScrutinizer Auto-Fixer if ($last_frame['paras']) { 161036867b5Sgithub-actions[bot] $output[] = 'p_close'; 162665315f8SScrutinizer Auto-Fixer } 163393d524aSMark Prins $output[] = "{$last_frame['item']}_content_close"; 164070bd191SMark Prins $close_content = false; 165070bd191SMark Prins } 166393d524aSMark Prins $output[] = "{$last_frame['item']}_close"; 167393d524aSMark Prins $output[] = "{$last_frame['list']}_close"; 168070bd191SMark Prins array_pop($this->stack); 169070bd191SMark Prins $last_frame = end($this->stack); 170070bd191SMark Prins } 171070bd191SMark Prins // pull the last frame off the stack; 172070bd191SMark Prins // it will be replaced by the current frame 173070bd191SMark Prins array_pop($this->stack); 174070bd191SMark Prins $level = $last_frame['level']; 175070bd191SMark Prins if ($close_content) { 176665315f8SScrutinizer Auto-Fixer if ($last_frame['paras']) { 177036867b5Sgithub-actions[bot] $output[] = 'p_close'; 178665315f8SScrutinizer Auto-Fixer } 179393d524aSMark Prins $output[] = "{$last_frame['item']}_content_close"; 180070bd191SMark Prins } 181393d524aSMark Prins $output[] = "{$last_frame['item']}_close"; 182070bd191SMark Prins if ($curr_frame['list'] != $last_frame['list']) { 183070bd191SMark Prins // change list types 184393d524aSMark Prins $output[] = "{$last_frame['list']}_close"; 185393d524aSMark Prins $output[] = "{$curr_frame['list']}_open"; 186070bd191SMark Prins } 187070bd191SMark Prins } 188070bd191SMark Prins // and finally, open tags for the new list item 189393d524aSMark Prins $output[] = "{$curr_frame['item']}_open"; 190393d524aSMark Prins $output[] = "{$curr_frame['item']}_content_open"; 1916a2cc237SScrutinizer Auto-Fixer if ($curr_frame['paras']) { 192036867b5Sgithub-actions[bot] $output[] = 'p_open'; 1936a2cc237SScrutinizer Auto-Fixer } 194070bd191SMark Prins $curr_frame['level'] = $level; 195036867b5Sgithub-actions[bot] $this->stack[] = $curr_frame; 196070bd191SMark Prins break; 197070bd191SMark Prins case DOKU_LEXER_UNMATCHED: 198070bd191SMark Prins $output = $match; 199070bd191SMark Prins break; 200070bd191SMark Prins } 201036867b5Sgithub-actions[bot] return ['state' => $state, 'output' => $output, 'level' => $level]; 202070bd191SMark Prins } 2030ec8e935SMark Prins 204036867b5Sgithub-actions[bot] private function interpretMatch($match) 205036867b5Sgithub-actions[bot] { 206036867b5Sgithub-actions[bot] $tag_table = ['*' => 'u_li', '-' => 'o_li', '?' => 'dt', ':' => 'dd']; 207070bd191SMark Prins $tag = $tag_table[substr($match, -1)]; 208393d524aSMark Prins return ['depth' => count(explode(' ', str_replace("\t", ' ', $match))), 209393d524aSMark Prins 'list' => substr($tag, 0, 1) . 'l', 'item' => substr($tag, -2), 210393d524aSMark Prins 'paras' => (substr($match, -1) === substr($match, -2, 1))]; 211070bd191SMark Prins } 212249fbbd1SLarsDW223 213036867b5Sgithub-actions[bot] public function render($format, Doku_Renderer $renderer, $data) 214036867b5Sgithub-actions[bot] { 215*bb527396Sgithub-actions[bot] if (!in_array($format, ['xhtml', 'latex', 'odt'])) { 216070bd191SMark Prins return false; 217665315f8SScrutinizer Auto-Fixer } 218070bd191SMark Prins if ($data['state'] == DOKU_LEXER_UNMATCHED) { 219f05e8f4cSMark Prins if ($format != 'odt') { 220070bd191SMark Prins $renderer->doc .= $renderer->_xmlEntities($data['output']); 221249fbbd1SLarsDW223 } else { 222249fbbd1SLarsDW223 $renderer->cdata($data['output']); 223249fbbd1SLarsDW223 } 224070bd191SMark Prins return true; 225070bd191SMark Prins } 226070bd191SMark Prins foreach ($data['output'] as $i) { 227f05e8f4cSMark Prins switch ($format) { 228249fbbd1SLarsDW223 case 'xhtml': 2290ec8e935SMark Prins $this->renderXhtmlItem($renderer, $i, $data); 230249fbbd1SLarsDW223 break; 231249fbbd1SLarsDW223 case 'latex': 2320ec8e935SMark Prins $this->renderLatexItem($renderer, $i, $data); 233249fbbd1SLarsDW223 break; 234249fbbd1SLarsDW223 case 'odt': 2350ec8e935SMark Prins $this->renderOdtItem($renderer, $i, $data); 236249fbbd1SLarsDW223 break; 237249fbbd1SLarsDW223 } 238249fbbd1SLarsDW223 } 239249fbbd1SLarsDW223 if ($data['state'] == DOKU_LEXER_EXIT) { 240f05e8f4cSMark Prins if ($format != 'odt') { 241249fbbd1SLarsDW223 $renderer->doc .= "\n"; 242249fbbd1SLarsDW223 } else { 243249fbbd1SLarsDW223 $renderer->linebreak(); 244249fbbd1SLarsDW223 } 245249fbbd1SLarsDW223 } 246249fbbd1SLarsDW223 return true; 247249fbbd1SLarsDW223 } 248249fbbd1SLarsDW223 249036867b5Sgithub-actions[bot] private function renderXhtmlItem(Doku_Renderer $renderer, $item, $data) 250036867b5Sgithub-actions[bot] { 251070bd191SMark Prins $markup = ''; 252249fbbd1SLarsDW223 switch ($item) { 253070bd191SMark Prins case 'ol_open': 254070bd191SMark Prins $markup = "<ol>\n"; 255070bd191SMark Prins break; 256070bd191SMark Prins case 'ol_close': 257070bd191SMark Prins $markup = "</ol>\n"; 258070bd191SMark Prins break; 259070bd191SMark Prins case 'ul_open': 260070bd191SMark Prins $markup = "<ul>\n"; 261070bd191SMark Prins break; 262070bd191SMark Prins case 'ul_close': 263070bd191SMark Prins $markup = "</ul>\n"; 264070bd191SMark Prins break; 265070bd191SMark Prins case 'dl_open': 266070bd191SMark Prins $markup = "<dl>\n"; 267070bd191SMark Prins break; 268070bd191SMark Prins case 'dl_close': 269070bd191SMark Prins $markup = "</dl>\n"; 270070bd191SMark Prins break; 271070bd191SMark Prins case 'li_open': 272393d524aSMark Prins $markup = "<li class=\"level{$data['level']}\">"; 273070bd191SMark Prins break; 274070bd191SMark Prins case 'li_content_open': 275070bd191SMark Prins $markup = "<div class=\"li\">\n"; 276070bd191SMark Prins break; 277070bd191SMark Prins case 'li_content_close': 278f0f4f9f3SMark Prins case 'dd_content_close': 279070bd191SMark Prins $markup = "\n</div>"; 280070bd191SMark Prins break; 281070bd191SMark Prins case 'li_close': 282070bd191SMark Prins $markup = "</li>\n"; 283070bd191SMark Prins break; 284070bd191SMark Prins case 'dt_open': 285393d524aSMark Prins $markup = "<dt class=\"level{$data['level']}\">"; 286070bd191SMark Prins break; 287070bd191SMark Prins case 'dt_content_open': 288070bd191SMark Prins $markup = "<span class=\"dt\">"; 289070bd191SMark Prins break; 290070bd191SMark Prins case 'dt_content_close': 291070bd191SMark Prins $markup = "</span>"; 292070bd191SMark Prins break; 293070bd191SMark Prins case 'dt_close': 294070bd191SMark Prins $markup = "</dt>\n"; 295070bd191SMark Prins break; 296070bd191SMark Prins case 'dd_open': 297393d524aSMark Prins $markup = "<dd class=\"level{$data['level']}\">"; 298070bd191SMark Prins break; 299070bd191SMark Prins case 'dd_content_open': 300070bd191SMark Prins $markup = "<div class=\"dd\">\n"; 301070bd191SMark Prins break; 302070bd191SMark Prins case 'dd_close': 303070bd191SMark Prins $markup = "</dd>\n"; 304070bd191SMark Prins break; 305db15290dSMark Prins case 'p_open': 306db15290dSMark Prins $markup = "<p>\n"; 307db15290dSMark Prins break; 308db15290dSMark Prins case 'p_close': 309db15290dSMark Prins $markup = "\n</p>"; 310db15290dSMark Prins break; 311070bd191SMark Prins } 312249fbbd1SLarsDW223 $renderer->doc .= $markup; 313249fbbd1SLarsDW223 } 314249fbbd1SLarsDW223 315036867b5Sgithub-actions[bot] private function renderLatexItem(Doku_Renderer $renderer, $item) 316036867b5Sgithub-actions[bot] { 317249fbbd1SLarsDW223 $markup = ''; 3186c7e837fSMark Prins switch ($item) { 319070bd191SMark Prins case 'ol_open': 320070bd191SMark Prins $markup = "\\begin{enumerate}\n"; 321070bd191SMark Prins break; 322070bd191SMark Prins case 'ol_close': 323070bd191SMark Prins $markup = "\\end{enumerate}\n"; 324070bd191SMark Prins break; 325070bd191SMark Prins case 'ul_open': 326070bd191SMark Prins $markup = "\\begin{itemize}\n"; 327070bd191SMark Prins break; 328070bd191SMark Prins case 'ul_close': 329070bd191SMark Prins $markup = "\\end{itemize}\n"; 330070bd191SMark Prins break; 331070bd191SMark Prins case 'dl_open': 332070bd191SMark Prins $markup = "\\begin{description}\n"; 333070bd191SMark Prins break; 334070bd191SMark Prins case 'dl_close': 335070bd191SMark Prins $markup = "\\end{description}\n"; 336070bd191SMark Prins break; 337070bd191SMark Prins case 'li_open': 338070bd191SMark Prins $markup = "\item "; 339070bd191SMark Prins break; 340070bd191SMark Prins case 'li_content_open': 341070bd191SMark Prins case 'li_content_close': 3425a75fb21Sgithub-actions[bot] case 'dt_content_close': 3435a75fb21Sgithub-actions[bot] case 'dd_content_close': 344070bd191SMark Prins break; 345070bd191SMark Prins case 'li_close': 3465a75fb21Sgithub-actions[bot] case 'p_close': 347070bd191SMark Prins $markup = "\n"; 348070bd191SMark Prins break; 349070bd191SMark Prins case 'dt_open': 350070bd191SMark Prins $markup = "\item["; 351070bd191SMark Prins break; 352070bd191SMark Prins case 'dt_content_open': 353070bd191SMark Prins case 'dt_close': 354070bd191SMark Prins $markup = "] "; 355070bd191SMark Prins break; 356070bd191SMark Prins case 'dd_open': 357070bd191SMark Prins case 'dd_content_open': 358070bd191SMark Prins case 'dd_close': 359070bd191SMark Prins case 'p_open': 360070bd191SMark Prins } 361070bd191SMark Prins $renderer->doc .= $markup; 362070bd191SMark Prins } 363249fbbd1SLarsDW223 364249fbbd1SLarsDW223 /** 365249fbbd1SLarsDW223 * Render yalist items for ODT format 366249fbbd1SLarsDW223 * 367249fbbd1SLarsDW223 * @param Doku_Renderer $renderer The current renderer object 368249fbbd1SLarsDW223 * @param string $item The item to render 369249fbbd1SLarsDW223 * 370249fbbd1SLarsDW223 * @author LarsDW223 371249fbbd1SLarsDW223 */ 372036867b5Sgithub-actions[bot] private function renderOdtItem(Doku_Renderer $renderer, $item) 373036867b5Sgithub-actions[bot] { 374249fbbd1SLarsDW223 switch ($item) { 375249fbbd1SLarsDW223 case 'ol_open': 376249fbbd1SLarsDW223 $renderer->listo_open(); 377249fbbd1SLarsDW223 break; 378249fbbd1SLarsDW223 case 'ul_open': 379249fbbd1SLarsDW223 $renderer->listu_open(); 380249fbbd1SLarsDW223 break; 381249fbbd1SLarsDW223 case 'dl_open': 382249fbbd1SLarsDW223 if ($this->getConf('def_list_odt_export') != 'table') { 383249fbbd1SLarsDW223 $renderer->listu_open(); 384249fbbd1SLarsDW223 } else { 385249fbbd1SLarsDW223 $renderer->table_open(2); 386249fbbd1SLarsDW223 } 387036867b5Sgithub-actions[bot] self::$odt_table_stack [self::$odt_table_stack_index] = []; 388249fbbd1SLarsDW223 self::$odt_table_stack [self::$odt_table_stack_index]['itemOpen'] = false; 389249fbbd1SLarsDW223 self::$odt_table_stack [self::$odt_table_stack_index]['dtState'] = 0; 390249fbbd1SLarsDW223 self::$odt_table_stack [self::$odt_table_stack_index]['ddState'] = 0; 391249fbbd1SLarsDW223 self::$odt_table_stack_index++; 392249fbbd1SLarsDW223 break; 393249fbbd1SLarsDW223 case 'ol_close': 394249fbbd1SLarsDW223 case 'ul_close': 395249fbbd1SLarsDW223 $renderer->list_close(); 396249fbbd1SLarsDW223 break; 397249fbbd1SLarsDW223 case 'dl_close': 398249fbbd1SLarsDW223 $config = $this->getConf('def_list_odt_export'); 399249fbbd1SLarsDW223 if ($config != 'table') { 400249fbbd1SLarsDW223 if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['ddState'] != 2) { 401249fbbd1SLarsDW223 if ($config == 'listheader' && method_exists($renderer, 'listheader_close')) { 402249fbbd1SLarsDW223 $renderer->listheader_close(); 403249fbbd1SLarsDW223 } else { 404249fbbd1SLarsDW223 $renderer->listitem_close(); 405249fbbd1SLarsDW223 } 406249fbbd1SLarsDW223 } 407249fbbd1SLarsDW223 self::$odt_table_stack [self::$odt_table_stack_index - 1]['ddState'] = 0; 408249fbbd1SLarsDW223 $renderer->list_close(); 409249fbbd1SLarsDW223 } else { 410249fbbd1SLarsDW223 if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['ddState'] == 0) { 411036867b5Sgithub-actions[bot] $properties = []; 412249fbbd1SLarsDW223 $properties ['border'] = 'none'; 413249fbbd1SLarsDW223 $renderer->_odtTableCellOpenUseProperties($properties); 414249fbbd1SLarsDW223 $renderer->tablecell_close(); 415249fbbd1SLarsDW223 } 416249fbbd1SLarsDW223 self::$odt_table_stack [self::$odt_table_stack_index - 1]['ddState'] = 0; 417249fbbd1SLarsDW223 if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] === true) { 418249fbbd1SLarsDW223 $renderer->tablerow_close(1); 419249fbbd1SLarsDW223 self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] = false; 420249fbbd1SLarsDW223 } 421249fbbd1SLarsDW223 $renderer->table_close(); 422249fbbd1SLarsDW223 } 423249fbbd1SLarsDW223 if (self::$odt_table_stack_index > 0) { 424249fbbd1SLarsDW223 self::$odt_table_stack_index--; 425249fbbd1SLarsDW223 unset(self::$odt_table_stack [self::$odt_table_stack_index]); 426249fbbd1SLarsDW223 } 427249fbbd1SLarsDW223 break; 428249fbbd1SLarsDW223 429249fbbd1SLarsDW223 case 'li_open': 430249fbbd1SLarsDW223 $renderer->listitem_open(1); 431249fbbd1SLarsDW223 break; 432249fbbd1SLarsDW223 case 'li_content_open': 433249fbbd1SLarsDW223 $renderer->listcontent_open(); 434249fbbd1SLarsDW223 break; 435249fbbd1SLarsDW223 case 'li_content_close': 436249fbbd1SLarsDW223 $renderer->listcontent_close(); 437249fbbd1SLarsDW223 break; 438249fbbd1SLarsDW223 case 'li_close': 439249fbbd1SLarsDW223 $renderer->listitem_close(); 440249fbbd1SLarsDW223 break; 441249fbbd1SLarsDW223 442249fbbd1SLarsDW223 case 'dt_open': // unconditional: DT tags can't contain paragraphs. That would not be legal XHTML. 443249fbbd1SLarsDW223 switch ($this->getConf('def_list_odt_export')) { 444249fbbd1SLarsDW223 case 'listheader': 445249fbbd1SLarsDW223 if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] === true) { 446249fbbd1SLarsDW223 if (method_exists($renderer, 'listheader_close')) { 447249fbbd1SLarsDW223 $renderer->listheader_close(); 448249fbbd1SLarsDW223 } else { 449249fbbd1SLarsDW223 $renderer->listitem_close(); 450249fbbd1SLarsDW223 } 451249fbbd1SLarsDW223 self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] = false; 452249fbbd1SLarsDW223 } 453249fbbd1SLarsDW223 if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] === false) { 454249fbbd1SLarsDW223 if (method_exists($renderer, 'listheader_open')) { 455249fbbd1SLarsDW223 $renderer->listheader_open(1); 456249fbbd1SLarsDW223 } else { 457249fbbd1SLarsDW223 $renderer->listitem_open(1); 458249fbbd1SLarsDW223 } 459249fbbd1SLarsDW223 self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] = true; 460249fbbd1SLarsDW223 } 461249fbbd1SLarsDW223 break; 462249fbbd1SLarsDW223 case 'table': 463249fbbd1SLarsDW223 if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['ddState'] == 0) { 464036867b5Sgithub-actions[bot] $properties = []; 465249fbbd1SLarsDW223 $properties ['border'] = 'none'; 466249fbbd1SLarsDW223 $renderer->_odtTableCellOpenUseProperties($properties); 467249fbbd1SLarsDW223 $renderer->tablecell_close(); 468249fbbd1SLarsDW223 } 469249fbbd1SLarsDW223 470249fbbd1SLarsDW223 if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] === true) { 471249fbbd1SLarsDW223 $renderer->tablerow_close(); 472249fbbd1SLarsDW223 self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] = false; 473249fbbd1SLarsDW223 } 474249fbbd1SLarsDW223 if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] === false) { 475249fbbd1SLarsDW223 $renderer->tablerow_open(1); 476249fbbd1SLarsDW223 self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] = true; 477249fbbd1SLarsDW223 } 478036867b5Sgithub-actions[bot] $properties = []; 479249fbbd1SLarsDW223 $properties ['border'] = 'none'; 480249fbbd1SLarsDW223 $renderer->_odtTableCellOpenUseProperties($properties); 481249fbbd1SLarsDW223 break; 482249fbbd1SLarsDW223 default: 483249fbbd1SLarsDW223 if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] === true) { 484249fbbd1SLarsDW223 $renderer->listitem_close(); 485249fbbd1SLarsDW223 self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] = false; 486249fbbd1SLarsDW223 } 487249fbbd1SLarsDW223 if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] === false) { 488249fbbd1SLarsDW223 $renderer->listitem_open(1); 489249fbbd1SLarsDW223 self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] = true; 490249fbbd1SLarsDW223 } 491249fbbd1SLarsDW223 break; 492249fbbd1SLarsDW223 } 493249fbbd1SLarsDW223 self::$odt_table_stack [self::$odt_table_stack_index - 1]['dtState'] = 1; 494249fbbd1SLarsDW223 self::$odt_table_stack [self::$odt_table_stack_index - 1]['ddState'] = 0; 495249fbbd1SLarsDW223 break; 496249fbbd1SLarsDW223 case 'dd_open': 497249fbbd1SLarsDW223 switch ($this->getConf('def_list_odt_export')) { 498249fbbd1SLarsDW223 case 'listheader': 499249fbbd1SLarsDW223 if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] === false) { 500249fbbd1SLarsDW223 if (method_exists($renderer, 'listheader_open')) { 501249fbbd1SLarsDW223 $renderer->listheader_open(1); 502249fbbd1SLarsDW223 } else { 503249fbbd1SLarsDW223 $renderer->listitem_open(1); 504249fbbd1SLarsDW223 } 505249fbbd1SLarsDW223 self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] = true; 506249fbbd1SLarsDW223 } 507249fbbd1SLarsDW223 break; 508249fbbd1SLarsDW223 case 'table': 509249fbbd1SLarsDW223 if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] === false) { 510249fbbd1SLarsDW223 $renderer->tablerow_open(1); 511249fbbd1SLarsDW223 self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] = true; 512249fbbd1SLarsDW223 } 513249fbbd1SLarsDW223 if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['dtState'] == 1) { 514249fbbd1SLarsDW223 $renderer->tablecell_close(); 515249fbbd1SLarsDW223 } 516249fbbd1SLarsDW223 if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['dtState'] == 0) { 517036867b5Sgithub-actions[bot] $properties = []; 518249fbbd1SLarsDW223 $properties ['border'] = 'none'; 519249fbbd1SLarsDW223 $renderer->_odtTableCellOpenUseProperties($properties); 520249fbbd1SLarsDW223 $renderer->tablecell_close(); 521249fbbd1SLarsDW223 } 522249fbbd1SLarsDW223 523036867b5Sgithub-actions[bot] $properties = []; 524249fbbd1SLarsDW223 $properties ['border'] = 'none'; 525249fbbd1SLarsDW223 $renderer->_odtTableCellOpenUseProperties($properties); 526249fbbd1SLarsDW223 break; 527249fbbd1SLarsDW223 default: 528249fbbd1SLarsDW223 if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] === false) { 529249fbbd1SLarsDW223 $renderer->listitem_open(1); 530249fbbd1SLarsDW223 self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] = true; 531249fbbd1SLarsDW223 } 532249fbbd1SLarsDW223 break; 533249fbbd1SLarsDW223 } 534249fbbd1SLarsDW223 self::$odt_table_stack [self::$odt_table_stack_index - 1]['dtState'] = 0; 535249fbbd1SLarsDW223 self::$odt_table_stack [self::$odt_table_stack_index - 1]['ddState'] = 1; 536249fbbd1SLarsDW223 break; 537249fbbd1SLarsDW223 case 'dt_content_open': 538*bb527396Sgithub-actions[bot] match ($this->getConf('def_list_odt_export')) { 539*bb527396Sgithub-actions[bot] 'table' => $renderer->p_open(), 540*bb527396Sgithub-actions[bot] default => $renderer->listcontent_open(), 541*bb527396Sgithub-actions[bot] }; 542249fbbd1SLarsDW223 $this->renderODTOpenSpan($renderer); 543249fbbd1SLarsDW223 break; 544249fbbd1SLarsDW223 case 'dd_content_open': 545*bb527396Sgithub-actions[bot] match ($this->getConf('def_list_odt_export')) { 546*bb527396Sgithub-actions[bot] 'table' => $renderer->p_open(), 547*bb527396Sgithub-actions[bot] default => $renderer->listcontent_open(), 548*bb527396Sgithub-actions[bot] }; 549249fbbd1SLarsDW223 break; 550249fbbd1SLarsDW223 case 'dt_content_close': 551249fbbd1SLarsDW223 $this->renderODTCloseSpan($renderer); 552*bb527396Sgithub-actions[bot] match ($this->getConf('def_list_odt_export')) { 553*bb527396Sgithub-actions[bot] 'table' => $renderer->p_close(), 554*bb527396Sgithub-actions[bot] default => $renderer->listcontent_close(), 555*bb527396Sgithub-actions[bot] }; 556249fbbd1SLarsDW223 break; 557249fbbd1SLarsDW223 case 'dd_content_close': 558*bb527396Sgithub-actions[bot] match ($this->getConf('def_list_odt_export')) { 559*bb527396Sgithub-actions[bot] 'table' => $renderer->p_close(), 560*bb527396Sgithub-actions[bot] default => $renderer->listcontent_close(), 561*bb527396Sgithub-actions[bot] }; 562249fbbd1SLarsDW223 break; 563249fbbd1SLarsDW223 case 'dt_close': 564249fbbd1SLarsDW223 switch ($this->getConf('def_list_odt_export')) { 565249fbbd1SLarsDW223 case 'listheader': 5665a75fb21Sgithub-actions[bot] default: 567249fbbd1SLarsDW223 $renderer->linebreak(); 568249fbbd1SLarsDW223 break; 569249fbbd1SLarsDW223 case 'table': 570249fbbd1SLarsDW223 $renderer->tablecell_close(); 571249fbbd1SLarsDW223 self::$odt_table_stack [self::$odt_table_stack_index - 1]['dtState'] = 2; 572249fbbd1SLarsDW223 break; 573249fbbd1SLarsDW223 } 574249fbbd1SLarsDW223 break; 575249fbbd1SLarsDW223 576249fbbd1SLarsDW223 case 'dd_close': 577249fbbd1SLarsDW223 switch ($this->getConf('def_list_odt_export')) { 578249fbbd1SLarsDW223 case 'listheader': 579249fbbd1SLarsDW223 if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] === true) { 580249fbbd1SLarsDW223 if (method_exists($renderer, 'listheader_close')) { 581249fbbd1SLarsDW223 $renderer->listheader_close(); 582249fbbd1SLarsDW223 } else { 583249fbbd1SLarsDW223 $renderer->listitem_close(); 584249fbbd1SLarsDW223 } 585249fbbd1SLarsDW223 self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] = false; 586249fbbd1SLarsDW223 } 587249fbbd1SLarsDW223 break; 588249fbbd1SLarsDW223 case 'table': 589249fbbd1SLarsDW223 $renderer->tablecell_close(); 590249fbbd1SLarsDW223 if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] === true) { 591249fbbd1SLarsDW223 $renderer->tablerow_close(1); 592249fbbd1SLarsDW223 self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] = false; 593249fbbd1SLarsDW223 } 594249fbbd1SLarsDW223 break; 595249fbbd1SLarsDW223 default: 596249fbbd1SLarsDW223 if (self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] === true) { 597249fbbd1SLarsDW223 $renderer->listitem_close(1); 598249fbbd1SLarsDW223 self::$odt_table_stack [self::$odt_table_stack_index - 1]['itemOpen'] = false; 599249fbbd1SLarsDW223 } 600249fbbd1SLarsDW223 break; 601249fbbd1SLarsDW223 } 602249fbbd1SLarsDW223 self::$odt_table_stack [self::$odt_table_stack_index - 1]['dtState'] = 0; 603249fbbd1SLarsDW223 self::$odt_table_stack [self::$odt_table_stack_index - 1]['ddState'] = 2; 604249fbbd1SLarsDW223 break; 605249fbbd1SLarsDW223 606249fbbd1SLarsDW223 case 'p_open': 607249fbbd1SLarsDW223 $renderer->p_open(); 608249fbbd1SLarsDW223 break; 609249fbbd1SLarsDW223 case 'p_close': 610249fbbd1SLarsDW223 $renderer->p_close(); 611249fbbd1SLarsDW223 break; 612249fbbd1SLarsDW223 } 613249fbbd1SLarsDW223 } 614249fbbd1SLarsDW223 615249fbbd1SLarsDW223 /** 616249fbbd1SLarsDW223 * Open ODT span for rendering of dt-content 617249fbbd1SLarsDW223 * 618249fbbd1SLarsDW223 * @param Doku_Renderer $renderer The current renderer object 619249fbbd1SLarsDW223 * 620249fbbd1SLarsDW223 * @author LarsDW223 621249fbbd1SLarsDW223 */ 622036867b5Sgithub-actions[bot] private function renderODTOpenSpan($renderer) 623036867b5Sgithub-actions[bot] { 624036867b5Sgithub-actions[bot] $properties = []; 625249fbbd1SLarsDW223 626249fbbd1SLarsDW223 // Get CSS properties for ODT export. 627f0f4f9f3SMark Prins $renderer->getODTProperties($properties, 'div', 'dokuwiki dt', null); 628249fbbd1SLarsDW223 629249fbbd1SLarsDW223 $renderer->_odtSpanOpenUseProperties($properties); 630249fbbd1SLarsDW223 } 631249fbbd1SLarsDW223 632249fbbd1SLarsDW223 /** 633249fbbd1SLarsDW223 * Close ODT span for rendering of dt-content 634249fbbd1SLarsDW223 * 635249fbbd1SLarsDW223 * @param Doku_Renderer $renderer The current renderer object 636249fbbd1SLarsDW223 * 637249fbbd1SLarsDW223 * @author LarsDW223 638249fbbd1SLarsDW223 */ 639036867b5Sgithub-actions[bot] private function renderODTCloseSpan($renderer) 640036867b5Sgithub-actions[bot] { 641249fbbd1SLarsDW223 if (method_exists($renderer, '_odtSpanClose') === false) { 642249fbbd1SLarsDW223 // Function is not supported by installed ODT plugin version, return. 643249fbbd1SLarsDW223 return; 644249fbbd1SLarsDW223 } 645249fbbd1SLarsDW223 $renderer->_odtSpanClose(); 646070bd191SMark Prins } 647070bd191SMark Prins} 648