1<?php
2/**
3 * Plugin SketchCanvas: SketchCanvas Document Embedding.
4 *
5 * @license    ???
6//GPL 2 (http://www.gnu.org/licenses/gpl.html)
7 * @author     Masahiro Sakuta <masahiro.sakuta@gmail.com>
8 */
9
10// must be run within DokuWiki
11if(!defined('DOKU_INC')) die();
12
13if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
14require_once(DOKU_PLUGIN.'syntax.php');
15
16/**
17 * All DokuWiki plugins to extend the parser/rendering mechanism
18 * need to inherit from this class
19 */
20class syntax_plugin_sketchcanvas extends DokuWiki_Syntax_Plugin {
21
22    function getType(){ return 'formatting'; }
23    function getAllowedTypes() { return array(); }
24    function getSort(){ return 159; }
25    function connectTo($mode) { $this->Lexer->addEntryPattern('<skcanvas.*?>(?=.*?</skcanvas>)',$mode,'plugin_sketchcanvas'); }
26    function postConnect() { $this->Lexer->addExitPattern('</skcanvas>','plugin_sketchcanvas'); }
27
28    /// Generator for canvas ids
29    var $generator = 1;
30
31    /**
32     * Handle the match
33     */
34    function handle($match, $state, $pos, Doku_Handler $handler){
35        switch ($state) {
36          case DOKU_LEXER_ENTER :
37                return array($state, array(true, $this->generator, 'bytepos_start' => $pos + strlen($match)));
38
39          case DOKU_LEXER_UNMATCHED : return array($state, $match);
40          case DOKU_LEXER_EXIT :       return array($state, array(false, $this->generator++, 'bytepos_end' => $pos));
41        }
42        return array();
43    }
44
45    /**
46     * Create output
47     */
48    function render($mode, Doku_Renderer $renderer, $data) {
49        if($mode == 'xhtml'){
50            list($state, $match) = $data;
51            switch ($state) {
52              case DOKU_LEXER_ENTER :
53                list($active, $num) = $match;
54                $class = '';
55                if(method_exists($renderer, 'startSectionEdit')){
56                  $sectionEditData = ['target' => 'plugin_sketchcanvas'];
57                  if (!defined('SEC_EDIT_PATTERN')) {
58                      // backwards-compatibility for Frusterick Manners (2017-02-19)
59                      $sectionEditData = 'plugin_sketchcanvas';
60                  }
61
62                  $class = $renderer->startSectionEdit($match['bytepos_start'], $sectionEditData);
63                }
64                $canvasId = '__sketchcanvas' . $num;
65              // To make dw2pdf work with SketchCanvas, we need to convert the canvas content
66              // to some image.  Now that the server is capable of rendering one, we can
67              // generate an image link with SketchCanvas source as parameter to the renderer.
68              if(is_a($renderer, 'renderer_plugin_dw2pdf')){
69                $renderer->doc .= '<img src="dokuwiki/lib/plugins/' . $this->getPluginName()
70                  . '/phplib/image.php?drawdata=';
71              }
72              else{
73                // Otherwise, just embed the source into the HTML so that JavaScript can process
74                // them later to load them into the canvases.
75                $renderer->doc .= <<<EOT
76<div class="$class">
77<canvas id="$canvasId" width="1024" height="640"></canvas>
78<div id="__sketchcanvas_text$num" style="display: none">
79EOT;
80              }
81              break;
82
83              case DOKU_LEXER_UNMATCHED :
84                   list($active) = $match;
85                   if($active){
86                      // When rendering for dw2pdf, the data must be encoded in the URL.
87                      // Otherwise, it will be just ordinaly HTML text.
88                      if(is_a($renderer, 'renderer_plugin_dw2pdf'))
89                        $renderer->doc .= urlencode($match);
90                      else
91                        $renderer->doc .= $renderer->_xmlEntities($match);
92                   }
93                   else
94                       $renderer->doc .= $renderer->_xmlEntities($match);
95                   break;
96              case DOKU_LEXER_EXIT :
97                  list($active, $num) = $match;
98
99                  if(is_a($renderer, 'renderer_plugin_dw2pdf'))
100                    $renderer->doc .= '">'; // Closing img tag
101                  else
102                    $renderer->doc .= <<<EOT
103</div>
104</div>
105EOT;
106                if(method_exists($renderer, 'finishSectionEdit'))
107                  $renderer->finishSectionEdit($match['bytepos_end']);
108                break;
109            }
110            return true;
111        }
112        return false;
113    }
114}
115?>
116