[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/inc/Parsing/ParserMode/ -> Footnote.php (source)

   1  <?php
   2  
   3  namespace dokuwiki\Parsing\ParserMode;
   4  
   5  use dokuwiki\Parsing\Handler;
   6  use dokuwiki\Parsing\Handler\Nest;
   7  use dokuwiki\Parsing\ModeRegistry;
   8  
   9  class Footnote extends AbstractMode
  10  {
  11      /** @inheritdoc */
  12      protected function allowedCategories(): array
  13      {
  14          return [
  15              ModeRegistry::CATEGORY_CONTAINER,
  16              ModeRegistry::CATEGORY_FORMATTING,
  17              ModeRegistry::CATEGORY_SUBSTITUTION,
  18              ModeRegistry::CATEGORY_PROTECTED,
  19              ModeRegistry::CATEGORY_DISABLED,
  20          ];
  21      }
  22  
  23      /**
  24       * Footnotes cannot nest, so footnote is excluded from its own content.
  25       *
  26       * @inheritdoc
  27       */
  28      protected function filterAllowedModes(array $modes): array
  29      {
  30          return array_values(array_filter($modes, static fn($m) => $m !== 'footnote'));
  31      }
  32  
  33      /** @inheritdoc */
  34      public function getSort()
  35      {
  36          return 150;
  37      }
  38  
  39      /** @inheritdoc */
  40      public function connectTo($mode)
  41      {
  42          $this->Lexer->addEntryPattern('\x28\x28', $mode, 'footnote');
  43      }
  44  
  45      /** @inheritdoc */
  46      public function postConnect()
  47      {
  48          $this->Lexer->addExitPattern('\x29\x29', 'footnote');
  49          $this->Lexer->addCloserPattern('\x29\x29', 'footnote');
  50      }
  51  
  52      /** @inheritdoc */
  53      public function handle($match, $state, $pos, Handler $handler)
  54      {
  55          switch ($state) {
  56              case DOKU_LEXER_ENTER:
  57                  // footnotes can not be nested - however due to limitations in lexer it can't be prevented
  58                  // we will still enter a new footnote mode, we just do nothing
  59                  if ($handler->getStatus('footnote')) {
  60                      $handler->addCall('cdata', [$match], $pos);
  61                      break;
  62                  }
  63                  $handler->setStatus('footnote', true);
  64  
  65                  $handler->setCallWriter(new Nest($handler->getCallWriter(), 'footnote_close'));
  66                  $handler->addCall('footnote_open', [], $pos);
  67                  break;
  68              case DOKU_LEXER_EXIT:
  69                  // check whether we have already exited the footnote mode, can happen if the modes were nested
  70                  if (!$handler->getStatus('footnote')) {
  71                      $handler->addCall('cdata', [$match], $pos);
  72                      break;
  73                  }
  74  
  75                  $handler->setStatus('footnote', false);
  76                  $handler->addCall('footnote_close', [], $pos);
  77  
  78                  /** @var Nest $reWriter */
  79                  $reWriter = $handler->getCallWriter();
  80                  $handler->setCallWriter($reWriter->process());
  81                  break;
  82              case DOKU_LEXER_UNMATCHED:
  83                  $handler->addCall('cdata', [$match], $pos);
  84                  break;
  85          }
  86          return true;
  87      }
  88  }