Инструменты пользователя

Инструменты сайта


wiki:xref:dokuwiki:inc:parsing:handler:lists.php
Lists.php
  1. <?php
  2.  
  3. namespace dokuwiki\Parsing\Handler;
  4.  
  5. class Lists extends AbstractRewriter
  6. {
  7. protected $listCalls = array();
  8. protected $listStack = array();
  9.  
  10. protected $initialDepth = 0;
  11.  
  12. const NODE = 1;
  13.  
  14. /** @inheritdoc */
  15. public function finalise()
  16. {
  17. $last_call = end($this->calls);
  18. $this->writeCall(array('list_close',array(), $last_call[2]));
  19.  
  20. $this->process();
  21. $this->callWriter->finalise();
  22. unset($this->callWriter);
  23. }
  24.  
  25. /** @inheritdoc */
  26. public function process()
  27. {
  28.  
  29. foreach ($this->calls as $call) {
  30. switch ($call[0]) {
  31. case 'list_item':
  32. $this->listOpen($call);
  33. break;
  34. case 'list_open':
  35. $this->listStart($call);
  36. break;
  37. case 'list_close':
  38. $this->listEnd($call);
  39. break;
  40. default:
  41. $this->listContent($call);
  42. break;
  43. }
  44. }
  45.  
  46. $this->callWriter->writeCalls($this->listCalls);
  47. return $this->callWriter;
  48. }
  49.  
  50. protected function listStart($call)
  51. {
  52. $depth = $this->interpretSyntax($call[1][0], $listType);
  53.  
  54. $this->initialDepth = $depth;
  55. // array(list type, current depth, index of current listitem_open)
  56. $this->listStack[] = array($listType, $depth, 1);
  57.  
  58. $this->listCalls[] = array('list'.$listType.'_open',array(),$call[2]);
  59. $this->listCalls[] = array('listitem_open',array(1),$call[2]);
  60. $this->listCalls[] = array('listcontent_open',array(),$call[2]);
  61. }
  62.  
  63.  
  64. protected function listEnd($call)
  65. {
  66. $closeContent = true;
  67.  
  68. while ($list = array_pop($this->listStack)) {
  69. if ($closeContent) {
  70. $this->listCalls[] = array('listcontent_close',array(),$call[2]);
  71. $closeContent = false;
  72. }
  73. $this->listCalls[] = array('listitem_close',array(),$call[2]);
  74. $this->listCalls[] = array('list'.$list[0].'_close', array(), $call[2]);
  75. }
  76. }
  77.  
  78. protected function listOpen($call)
  79. {
  80. $depth = $this->interpretSyntax($call[1][0], $listType);
  81. $end = end($this->listStack);
  82. $key = key($this->listStack);
  83.  
  84. // Not allowed to be shallower than initialDepth
  85. if ($depth < $this->initialDepth) {
  86. $depth = $this->initialDepth;
  87. }
  88.  
  89. if ($depth == $end[1]) {
  90. // Just another item in the list...
  91. if ($listType == $end[0]) {
  92. $this->listCalls[] = array('listcontent_close',array(),$call[2]);
  93. $this->listCalls[] = array('listitem_close',array(),$call[2]);
  94. $this->listCalls[] = array('listitem_open',array($depth-1),$call[2]);
  95. $this->listCalls[] = array('listcontent_open',array(),$call[2]);
  96.  
  97. // new list item, update list stack's index into current listitem_open
  98. $this->listStack[$key][2] = count($this->listCalls) - 2;
  99.  
  100. // Switched list type...
  101. } else {
  102. $this->listCalls[] = array('listcontent_close',array(),$call[2]);
  103. $this->listCalls[] = array('listitem_close',array(),$call[2]);
  104. $this->listCalls[] = array('list'.$end[0].'_close', array(), $call[2]);
  105. $this->listCalls[] = array('list'.$listType.'_open', array(), $call[2]);
  106. $this->listCalls[] = array('listitem_open', array($depth-1), $call[2]);
  107. $this->listCalls[] = array('listcontent_open',array(),$call[2]);
  108.  
  109. array_pop($this->listStack);
  110. $this->listStack[] = array($listType, $depth, count($this->listCalls) - 2);
  111. }
  112. } elseif ($depth > $end[1]) { // Getting deeper...
  113. $this->listCalls[] = array('listcontent_close',array(),$call[2]);
  114. $this->listCalls[] = array('list'.$listType.'_open', array(), $call[2]);
  115. $this->listCalls[] = array('listitem_open', array($depth-1), $call[2]);
  116. $this->listCalls[] = array('listcontent_open',array(),$call[2]);
  117.  
  118. // set the node/leaf state of this item's parent listitem_open to NODE
  119. $this->listCalls[$this->listStack[$key][2]][1][1] = self::NODE;
  120.  
  121. $this->listStack[] = array($listType, $depth, count($this->listCalls) - 2);
  122. } else { // Getting shallower ( $depth < $end[1] )
  123. $this->listCalls[] = array('listcontent_close',array(),$call[2]);
  124. $this->listCalls[] = array('listitem_close',array(),$call[2]);
  125. $this->listCalls[] = array('list'.$end[0].'_close',array(),$call[2]);
  126.  
  127. // Throw away the end - done
  128. array_pop($this->listStack);
  129.  
  130. while (1) {
  131. $end = end($this->listStack);
  132. $key = key($this->listStack);
  133.  
  134. if ($end[1] <= $depth) {
  135. // Normalize depths
  136. $depth = $end[1];
  137.  
  138. $this->listCalls[] = array('listitem_close',array(),$call[2]);
  139.  
  140. if ($end[0] == $listType) {
  141. $this->listCalls[] = array('listitem_open',array($depth-1),$call[2]);
  142. $this->listCalls[] = array('listcontent_open',array(),$call[2]);
  143.  
  144. // new list item, update list stack's index into current listitem_open
  145. $this->listStack[$key][2] = count($this->listCalls) - 2;
  146. } else {
  147. // Switching list type...
  148. $this->listCalls[] = array('list'.$end[0].'_close', array(), $call[2]);
  149. $this->listCalls[] = array('list'.$listType.'_open', array(), $call[2]);
  150. $this->listCalls[] = array('listitem_open', array($depth-1), $call[2]);
  151. $this->listCalls[] = array('listcontent_open',array(),$call[2]);
  152.  
  153. array_pop($this->listStack);
  154. $this->listStack[] = array($listType, $depth, count($this->listCalls) - 2);
  155. }
  156.  
  157. break;
  158.  
  159. // Haven't dropped down far enough yet.... ( $end[1] > $depth )
  160. } else {
  161. $this->listCalls[] = array('listitem_close',array(),$call[2]);
  162. $this->listCalls[] = array('list'.$end[0].'_close',array(),$call[2]);
  163.  
  164. array_pop($this->listStack);
  165. }
  166. }
  167. }
  168. }
  169.  
  170. protected function listContent($call)
  171. {
  172. $this->listCalls[] = $call;
  173. }
  174.  
  175. protected function interpretSyntax($match, & $type)
  176. {
  177. if (substr($match, -1) == '*') {
  178. $type = 'u';
  179. } else {
  180. $type = 'o';
  181. }
  182. // Is the +1 needed? It used to be count(explode(...))
  183. // but I don't think the number is seen outside this handler
  184. return substr_count(str_replace("\t", ' ', $match), ' ') + 1;
  185. }
  186. }
Только авторизованные участники могут оставлять комментарии.
wiki/xref/dokuwiki/inc/parsing/handler/lists.php.txt · Последнее изменение: 127.0.0.1