1<?php
2if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../../').'/');
3if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
4require_once(DOKU_PLUGIN.'action.php');
5use dokuwiki\Extension\Event;
6
7/**
8 * @license    GNU GPLv2 version 2 or later (http://www.gnu.org/licenses/gpl.html)
9 *
10 * class       plugin_ckgedit_edit
11 * @author     Myron Turner <turnermm02@shaw.ca>
12 */
13
14class action_plugin_ckgedit_edit extends DokuWiki_Action_Plugin {
15
16    var $fck_location = "ckeditor";
17    var $helper = false;
18    var $ckgedit_bak_file = "";
19    var $debug = false;
20    var $test = false;
21    var $page_from_template;
22    var $draft_found = false;
23    var $draft_text;
24    var $draft_started;
25    var $captcha;
26    /**
27     * Constructor
28     */
29    function __construct()
30    {
31        $this->setupLocale();
32        $this->helper = plugin_load('helper', 'ckgedit');
33        if(!plugin_isdisabled('captcha')) {
34            $this->captcha = plugin_load('helper', 'captcha');
35        }
36        else  $this->captcha  = false;
37
38    }
39
40
41    function register(Doku_Event_Handler $controller)
42    {
43       global $INPUT;
44       $version = explode('.', phpversion());
45       define('PHP_VERSION_NUM', $version[0] * 10+ $version[1]);
46
47         if($this->helper->is_outOfScope()) return;
48
49        global $FCKG_show_preview;
50        $FCKG_show_preview = true;
51
52        if(isset($_REQUEST['mode']) && $_REQUEST['mode'] == 'dwiki') {
53          $FCKG_show_preview = true;
54          return;
55        }
56        elseif(isset($_COOKIE['FCKG_USE'])) {
57             preg_match('/_\w+_/',  $_COOKIE['FCKG_USE'], $matches);
58             if($matches[0] == '_false_') {
59                  $FCKG_show_preview = true;
60                   return;
61             }
62        }
63        $Fck_NmSp = "!!NONSET!!";
64        if(isset($_COOKIE['FCK_NmSp'])) {
65          $Fck_NmSp = $_COOKIE['FCK_NmSp'];
66        }
67        $dwedit_ns = $this->getConf('dwedit_ns');
68        if(isset($dwedit_ns) && $dwedit_ns) {
69            $ns_choices = explode(',',$dwedit_ns);
70            foreach($ns_choices as $ns) {
71              $ns = trim($ns);
72              $id = $INPUT->str('id');
73              if(($id && preg_match("/$ns/",$id)) || ($Fck_NmSp && preg_match("/$ns/",$Fck_NmSp))) {
74                      $FCKG_show_preview = true;
75                       return;
76             }
77            }
78        }
79        $controller->register_hook('COMMON_PAGE_FROMTEMPLATE', 'AFTER', $this, 'pagefromtemplate', array());
80        $controller->register_hook('COMMON_PAGETPL_LOAD', 'AFTER', $this, 'pagefromtemplate', array());
81
82        $controller->register_hook('TPL_ACT_RENDER', 'BEFORE', $this, 'ckgedit_edit');
83        $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'ckgedit_edit_meta');
84    }
85
86   /**
87    * function pagefromtemplate
88    * Capture template text output by Template Event handler instead of pageTemplate()
89	* @author  Myron Turner <turnermm02@shaw.ca>
90    *
91    */
92    function pagefromtemplate(Doku_Event $event) {
93      if($event->data['tpl']) {
94         $this->page_from_template = $event->data['tpl'];
95      }
96    }
97
98    /**
99     * ckgedit_edit_meta
100     *
101     * load fck js
102     * @author Pierre Spring <pierre.spring@liip.ch>
103    * @author Myron Turner <turnermm03@shaw.ca>
104     * @param mixed $event
105     * @access public
106     * @return void
107     */
108    function ckgedit_edit_meta(Doku_Event $event)
109    {
110        global $ACT;
111        // we only change the edit behaviour
112        if ($ACT != 'edit'){
113            return;
114        }
115        global $ID;
116        global $REV;
117        global $INFO;
118        global $conf;
119            $event->data['script'][] =
120                array(
121                    'type'=>'text/javascript',
122                    'charset'=>'utf-8',
123                    '_data'=>'',
124                     'src'=>DOKU_BASE.'lib/plugins/ckgedit/' .$this->fck_location. '/ckeditor.js'
125                )+([ 'defer' => 'defer']);
126
127      if(isset($conf['fnencode']) && $conf['fnencode'] == 'safe') {
128            $event->data['script'][] =
129                array(
130                    'type'=>'text/javascript',
131                    'charset'=>'utf-8',
132                    '_data'=>'',
133                     'src'=>'lib/plugins/ckgedit/scripts/safeFN_cmpr.js'
134                ) + ([ 'defer' => 'defer']);
135      }
136      $ua = strtolower ($_SERVER['HTTP_USER_AGENT']);
137      if(strpos($ua, 'msie') !== false) {
138          echo "\n" . '<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />' ."\n";
139      }
140
141        if($this->test) {
142         $nval = substr(md5(time()), -20);
143         $parse_url = DOKU_URL . 'lib/plugins/ckgedit/scripts/parse_wiki.js.unc';
144        }
145        else $parse_url = DOKU_BASE . 'lib/plugins/ckgedit/scripts/parse_wiki-cmpr.js';
146        $event->data['script'][] =
147            array(
148                'type'=>'text/javascript',
149                'charset'=>'utf-8',
150                '_data'=>'',
151                 'src'=> $parse_url
152            ) + ([ 'defer' => 'defer']);
153
154        return;
155    }
156
157    /**
158     * function    ckgedit_edit
159     * @author     Pierre Spring <pierre.spring@liip.ch>
160     * edit screen using fck
161     *
162     * @param & $event
163     * @access public
164     * @return void
165     */
166    function ckgedit_edit(Doku_Event $event)
167    {
168
169        global $INFO;
170
171        // we only change the edit behaviour
172        if ($event->data != 'edit') {
173            return;
174        }
175        // load xml and acl
176        if (!$this->_preprocess()){
177            return;
178        }
179        // print out the edit screen
180        $this->_print();
181        // prevent Dokuwiki normal processing of $ACT (it would clean the variable and destroy our 'index' value.
182        $event->preventDefault();
183        // index command belongs to us, there is no need to hold up Dokuwiki letting other plugins see if its for them
184        $event->stopPropagation();
185    }
186
187   /**
188    * function _preprocess
189	* @author  Myron Turner <turnermm02@shaw.ca>
190    */
191    function _preprocess($draft_text = "")
192    {
193        global $ID;
194        global $REV;
195        global $DATE;
196        global $RANGE;
197        global $PRE;
198        global $SUF;
199        global $INFO;
200        global $SUM;
201        global $lang;
202        global $conf;
203        global $ckgedit_lang;
204        //set summary default
205        if(!$SUM){
206            if($REV){
207                $SUM = $lang['restored'];
208            }elseif(!$INFO['exists']){
209                $SUM = $lang['created'];
210            }
211        }
212            if(!$draft_text) {
213            if($INFO['exists']){
214                if($RANGE){
215                    list($PRE,$text,$SUF) = rawWikiSlices($RANGE,$ID,$REV);
216                }else{
217                    $text = rawWiki($ID,$REV);
218                }
219            }else{
220                //try to load a pagetemplate
221                 $text = pageTemplate($ID);
222                //Check for text from template event handler
223                 if(!$text && $this->page_from_template) $text = $this->page_from_template;
224            }
225            }
226            else $text = $draft_text;
227
228     $text = str_replace('&notags',  '&amp;amp;notags',$text);
229     $text = preg_replace_callback(
230    '/(~~NOCACHE~~|~~NOTOC~~|\{\{rss>http(s?):\/\/.*?\}\})/ms',
231         function($matches) {
232                $matches[0] = preg_replace("#{{rss>http(s?):\/\/#", "{ { rss>$1Feed:",  $matches[0]);
233                $matches[0] = str_replace("~", "~ ",  $matches[0]);
234                return $matches[0];
235               },$text);
236
237    if($this->getConf('smiley_hack')) {
238        $new_addr = $_SERVER['SERVER_NAME'] . DOKU_BASE;
239        $text=preg_replace("#(?<=http://)(.*?)(?=lib/plugins/ckgedit/ckeditor/plugins/smiley/images)#s", $new_addr,$text);
240     }
241 /*interwiki frasl refactoring*/
242
243/*
244    $text = preg_replace_callback('/\[\[\w+>.*?\]\]/ms',
245    create_function(
246        '$matches',
247        'return str_replace("/", "__IWIKI_FSLASH__" ,$matches[0]);'
248    ), $text);
249    */
250
251      global $useComplexTables;
252      if($this->getConf('complex_tables') || strrpos($text, '~~COMPLEX_TABLES~~') !== false) {
253          $useComplexTables=true;
254      }
255      else {
256         $useComplexTables=false;
257      }
258
259      if(strpos($text, '%%') !== false || strpos($text, '\\\\') !== false || strpos($text, '|') !== false ) {
260      $text = preg_replace('/%%\s*<nowiki>\s*%%/ms', 'PERCNWPERC',$text);
261      $text = preg_replace('/%%\s*<(code|file)>\s*%%/ms', 'PERC' . "$1" . 'PERC',$text);
262        $text = preg_replace_callback(
263            "/<(nowiki|code|file)>(.*?)<\/(nowiki|code|file)/ms",
264            function ($matches) {
265                $matches[0] = str_replace('%%', 'DBLPERCENT',$matches[0]);
266                $matches[0] =  str_replace('\\ ', 'DBLBACKSPLASH',$matches[0]);
267                 $matches[0] =  str_replace('|', 'NWPIPECHARACTER',$matches[0]);
268                return $matches[0];
269            },
270           $text
271        );
272
273        $text = preg_replace_callback(
274            "/(?<!nowiki>)%%(.*?)%%/ms",
275            function($matches) {
276            return '<nowiki>' . $matches[1] . '</nowiki>';
277            },
278            $text
279        );
280
281        $text =  str_replace('DBLPERCENT','%%',$text);
282      }
283
284       $pos = strpos($text, '<');
285
286       if($pos !== false) {
287
288/* skipentity support */
289        $text = preg_replace_callback(
290            '/``(.*?)``/ms',
291            function($matches) {
292                $needles =  array('[',']', '/',  '.', '*', '_','\'','<','>','%', '{', '}', '\\' , '(' );
293                $replacements = array('&#91;','&#93;','&#47;', '&#46;', '&#42;', '&#95;', '&#39;', '&#60;','&#62;','&#37;', '&#123;','&#125;', '&#92;','&#40;');
294                $matches[1] = str_replace($needles, $replacements, $matches[1]);
295               return '&grave;&grave;' .$matches[1] .'&grave;&grave;' ;
296            },
297            $text
298        );
299
300
301           $text = preg_replace_callback(
302            '/(<nowiki>)(.*?)(<\/nowiki>)/ms',
303                function($matches) {
304                 $needles =  array("[","]", "/",  ".", "*", "_","\'","<",">","%", "{", "}", "\\\\","(");
305                  $replacements = array("&#91;","&#93;","&#47;", "&#46;", "&#42;", "&#95;", "&#39;", "&#60;","&#62;","&#37;", "&#123;","&#125;", "&#92;","&#40;");
306                  $matches[2] = str_replace($needles, $replacements, $matches[2]);
307                  return  $matches[1] . $matches[2] . $matches[3];
308                },
309            $text
310          );
311
312           $text = preg_replace_callback(
313            '/<(code|file)(.*?)(>)(.*?)(<\/\1>)/ms',
314              function($matches) {
315                  //file_put_contents("geshi.txt", print_r($matches,true));
316                 if(preg_match("/(^\s*geshi:\s*(\w+)(\s+\w+\.\w+)*\s*)$/m",$matches[0],$gmatch)){
317                      $gmatch[0] = preg_replace("/\s*geshi:\s+/","",$gmatch[0]);
318                      $matches[1] .= " " . trim($gmatch[0]);
319                      //file_put_contents("gmatch.txt", print_r($gmatch,true));
320                      $c=1;
321                      $matches[4] = str_replace($gmatch[1],"",$matches[4],$c);
322                  }
323                 if(preg_match("/\w+/",$matches[2])) {
324                   $matches[4] = str_replace("CHEVRONescC", ">>",$matches[4]);
325                   $matches[4] = str_replace("CHEVRONescO", "<<",$matches[4]);
326                   $matches[4] = preg_replace("/<(?!\s)/ms", "__GESHI_OPEN__", $matches[4]);
327                  }
328                  else {
329                  if( preg_match("/MULTI/",$matches[0])) {
330                     $open = "< ";
331                     $close = " >";
332                  }
333                  else {
334                     $open = "&lt;";
335                     $close = "&gt;";
336                  }
337                  $matches[4] = preg_replace("/<(?!\s)/ms", $open, $matches[4]);
338                  $matches[4] = preg_replace("/(?<!\s)>/ms", $close, $matches[4]);
339                  }
340                  $matches[4] = str_replace("\"", "__GESHI_QUOT__", $matches[4]);
341                  $matches[4] = preg_replace("/\\\\\\\\(\n|\s)/ms","CODE_BLOCK_EOL_MASK$1",$matches[4]);
342                  return "<" . $matches[1] . $matches[2] . $matches[3] . $matches[4] . $matches[5];
343              },
344            $text
345          );
346
347          $text = preg_replace_callback(
348             '/~~START_HTML_BLOCK~~.*?CLOSE_HTML_BLOCK/ms',
349                 function($matches) {
350                     $matches[0] = str_replace("_ckgedit_NPBBR_","",$matches[0]);
351                     return $matches[0];
352                 },$text);
353
354          $text = preg_replace_callback(
355            '/(\|\s*)(<code>|<file>)(.*?)(<\/code>|<\/file>)\n_ckgedit_NPBBR_(?=.*?\|)/ms',
356            function($matches) {
357                  $matches[2] = preg_replace("/<code>/ms", "TPRE_CODE", $matches[2]);
358                  $matches[2] = preg_replace("/<file>/ms", "TPRE_FILE", $matches[2]);
359                  $matches[4] = "TPRE_CLOSE";
360                  $matches[3] = preg_replace("/^\n+/", "TC_NL",$matches[3]);
361                  $matches[3] = preg_replace("/\n/ms", "TC_NL",$matches[3]);
362                  return $matches[1] . $matches[2] .  trim($matches[3]) .   $matches[4];
363            },
364            $text
365          );
366         $text = preg_replace('/TPRE_CLOSE\s+/ms',"TPRE_CLOSE",$text);
367         $text = preg_replace('/<(?!code|file|nowiki|del|sup|sub|\/\/|\s|\/del|\/code|\/nowiki|\/file|\/sup|\/sub)/ms',"&lt;",$text);
368         $text = str_replace(array('<nowiki>','</nowiki>'),array('NWIKISTART<nowiki>','NWIKICLOSE</nowiki>'),$text);
369         $text = str_replace('%%&lt;', '&#37;&#37;&#60;', $text);
370       }
371
372	   if($this->getConf('duplicate_notes')) {
373			$text = preg_replace_callback('/\(\((.*?)\)\)/ms',
374				  function($matches) {
375				   static $count = 0;
376				   $count++;
377				   $ins = "FNoteINSert" . $count;
378                   $needles =  array("[","]", "/",  ".", "*", "_","\'","<",">","%", "{", "}", "\\","(");
379                   $replacements = array("&#91;","&#93;","&#47;", "&#46;", "&#42;", "&#95;", "&#39;", "&#60;","&#62;","&#37;", "&#123;","&#125;", "&#92;","&#40;");
380                   $matches[1] = str_replace($needles, $replacements, $matches[1]);
381              	   return "(($ins" . $matches[1] . "))" ;
382                  }, $text
383			);
384		}
385       $text = preg_replace('/^\>/ms',"_QUOT_",$text);  // dw quotes
386       $text = str_replace('>>','CHEVRONescC',$text);
387       $text = str_replace('<<','CHEVRONescO',$text);
388       $text = preg_replace('/(={3,}.*?)(\{\{.*?\}\})(.*?={3,})/',"$1$3\n$2",$text);
389       $email_regex = '/\/\/\<\/\/(.*?@.*?)>/';
390       $text = preg_replace($email_regex,"<$1>",$text);
391
392       $text = preg_replace('/{{(.*)\.swf(\s*)}}/ms',"__SWF__$1.swf$2__FWS__",$text);
393       $text = preg_replace('/PERCNWPERC/ms', '%%&lt; nowiki &gt;%%',$text);
394       //$text = preg_replace('/%%\s*<(code|file)>\s*%%/ms', 'PERC' . "$1" . 'PERC',$text);
395       $text = preg_replace('/PERCcodePERC/ms','%%&lt;code&gt;%%', $text);
396       $text = preg_replace('/PERCfilePERC/ms','%%&lt;file&gt;%%', $text);
397       $divalign = false;
398       if($this->helper->has_plugin('divalign2')
399		   ||$this->helper->has_plugin('divalign2_center')) {
400           $divalign = true;
401           $text = preg_replace_callback('/\n([;#]{3})/',
402
403                              function ($matches) {
404                               return "divalNLine" . str_replace('#','CGEHASH',$matches[1]);
405                              },   $text
406            );
407       }
408      $text = preg_replace_callback(
409               '|(<code\s+\w+)(\s+\[enable_line_numbers.*?\])\s*>(.*?<\/code>)|ms',
410            function($matches) {
411                $retstr = $matches[1] . ">\n/*" .   $matches[2] . "*/\n" . $matches[3];
412               return $retstr;
413            }, $text
414        );
415
416       $this->xhtml = $this->_render_xhtml($text);
417
418 /*interwiki frasl refactoring*/
419  //   $this->xhtml = str_replace("__IWIKI_FSLASH__", "&frasl;", $this->xhtml);
420	   if($this->getConf('duplicate_notes')) {
421			$this->xhtml = preg_replace("/FNoteINSert\d+/ms", "",$this->xhtml);
422	   }
423      if($divalign) {
424            $this->xhtml = str_replace("CGEHASH", "#", $this->xhtml);
425      }
426       $this->xhtml = str_replace("__GESHI_QUOT__", '&#34;', $this->xhtml);
427       $this->xhtml = str_replace("__GESHI_OPEN__", "&#60; ", $this->xhtml);
428       $this->xhtml = str_replace('CHEVRONescC', '>>',$this->xhtml);
429       $this->xhtml = str_replace('CHEVRONescO', '<<',$this->xhtml);
430       $this->xhtml = preg_replace('/_QUOT_/ms','>',$this->xhtml);  // dw quotes
431       $this->xhtml = preg_replace_callback(
432         "/^(>+)(.*?)$/ms",
433         function($matches) {
434             $matches[2] = str_ireplace('<br/>',"",$matches[2]);
435                return $matches[1] . $matches[2] . "<br />";
436         },
437        $this->xhtml
438       );
439
440       if($pos !== false) {
441       $this->xhtml = preg_replace_callback(
442                '/(TPRE_CODE|TPRE_FILE)(.*?)(TPRE_CLOSE)/ms',
443                function($matches) {
444                   $matches[1] = preg_replace("/TPRE_CODE/","<pre class=\'code\'>\n", $matches[1]);
445                    $matches[1] = preg_replace("/TPRE_FILE/","<pre class=\'file\'>\n", $matches[1]);
446                    $matches[2] = preg_replace("/TC_NL/ms", "\n", $matches[2]);
447                    $matches[3] = "</pre>";
448                    return $matches[1] . $matches[2] . $matches[3];
449                },
450                $this->xhtml
451              );
452
453        }
454
455        $this->xhtml = preg_replace_callback(
456        '/~~START_HTML_BLOCK~~[\n\s]*(.*?)CLOSE_HTML_BLOCK/ms',
457        function($matches) {
458            $matches[1] = str_replace("&amp;","&",$matches[1]);
459            $matches[1] =  html_entity_decode($matches[1],ENT_QUOTES, "UTF-8");
460            $matches[1] = preg_replace("/<\/?code.*?>/", "",$matches[1]);
461            $matches[1] = preg_replace("/^\s*<\/p>/","",$matches[1]);
462            $tmp = explode("\n", $matches[1]);
463            for($n=0; $n<7; $n++) {
464                if( (preg_match("/(<p>\s*)*(&nbsp;|\s+)<\/p>/",$tmp[$n])) || (preg_match("/^\s+$/",$tmp[$n]))) {
465                    unset($tmp[$n]);
466                }
467            }
468            return "~~START_HTML_BLOCK~~" . implode("\n",$tmp) . "CLOSE_HTML_BLOCK";
469        },$this->xhtml);
470
471        $this->xhtml = preg_replace_callback(
472            '/(<pre)(.*?)(>)(.*?)(<\/pre>)/ms',
473            function($matches) {
474                $matches[4] = preg_replace("/(\||\^)[ ]+(\||\^)/ms","$1 &nbsp; $2" , $matches[4]);
475                return  $matches[1] . $matches[2] . $matches[3] . $matches[4] . $matches[5];
476            },
477            $this->xhtml
478        );
479
480          $this->xhtml = preg_replace_callback(
481            '/~~MULTI_PLUGIN_OPEN~~(.*?)~~MULTI_PLUGIN_CLOSE~~/ms',
482            function($matches) {
483                return str_replace("&lt;", "< ",$matches[0]);
484            },
485            $this->xhtml
486          );
487		  //insures breaks are retained for single spacing
488      $this->xhtml = preg_replace('/<p>\s*<br\/>\s*<\/p>/ms', '<br/>', $this->xhtml);
489
490      if($this->draft_started) return $this->xhtml;
491       $cname = getCacheName($INFO['client'].$ID,'.draft.fckl');
492   // msg($cname);
493       $this->draft_started = false;
494       if(file_exists($cname)  && !$this->draft_started) {
495
496           $this->draft_started = true;
497
498          $cdata =  unserialize(io_readFile($cname,false));
499          $prefix =  isset($cdata['prefix']) ? urldecode($cdata['prefix']) : "" ;
500          if($prefix) $prefix = $this-> _preprocess($prefix);
501          $text = urldecode($cdata['text']);
502          $suffix = isset($cdata['suffix']) ? urldecode($cdata['suffix']) : "" ;
503
504          if($suffix) $suffix = $this-> _preprocess($suffix);
505
506          preg_match_all("/<\/(.*?)\>/", $cdata['text'],$matches);
507          /* exclude drafts saved from preview mode */
508          if (!in_array('code', $matches[1]) && !in_array('file', $matches[1]) && !in_array('nowiki', $matches[1])) {
509             //$this->draft_text = $cdata['text'];
510             $this->draft_text = $prefix . $text . $suffix;
511              $this->draft_found = true;
512              msg($this->getLang('draft_msg')) ;
513          }
514          unlink($cname);
515       }
516       if($this->draft_started) return $this->xhtml;
517       return true;
518    }
519
520
521   /**
522      Check for for alternate style sheet
523    */
524    function alt_style_sheet() {
525       $stylesheet = DOKU_PLUGIN . 'ckgedit/ckeditor/css/_style.css';
526       if(file_exists($stylesheet)) {
527           global $conf;
528           $tpl_name = $conf['template'];
529           if($fh = fopen($stylesheet,"r")) {
530               $line_num = 0;
531               while (!feof($fh) &&  $line_num < 4) {
532                    $line = fgets($fh,1024);            //msg($line);
533                    if(strpos($line,$tpl_name)!==false) {
534                         return DOKU_BASE . '/lib/plugins/ckgedit/ckeditor/css/_style.css' ;
535                        break;
536                     }
537                    $line_num ++;
538               }
539           }
540       }
541      return "";
542    }
543
544
545   /**
546    * function _print
547    * @author  Myron Turner
548    */
549    function _print()
550    {
551        global $INFO;
552        global $lang;
553        global $ckgedit_lang;
554        global $ID;
555        global $REV;
556        global $DATE;
557        global $PRE;
558        global $SUF;
559        global $SUM;
560        $wr = $INFO['writable'];
561        if($wr){
562           if ($REV) print p_locale_xhtml('editrev');
563           $ro=false;
564        }else{
565            // check pseudo action 'source'
566            if(!actionOK('source')){
567                msg('Command disabled: source',-1);
568                return false;
569            }
570            print p_locale_xhtml('read');
571            $ro='readonly="readonly"';
572        }
573
574        if(!$DATE) $DATE = $INFO['lastmod'];
575        $guest_toolbar = $this->getConf('guest_toolbar');
576        $guest_media  = $this->getConf('guest_media');
577        if(!isset($INFO['userinfo']) && !$guest_toolbar) {
578            $toolbar = "DokuwikiNoGuest";
579        }
580       else if(!isset($INFO['userinfo']) && !$guest_media) {
581	        $toolbar = "DokuwikiGuest";
582	   }
583        else $toolbar = 'Dokuwiki';
584
585$height = isset($_COOKIE['ckgEdht']) && $_COOKIE['ckgEdht'] ? $_COOKIE['ckgEdht']: 250;
586if(!is_numeric($height)) $height = 250;
587$fbsz_increment = isset($_COOKIE['fbsz']) && $_COOKIE['fbsz'] ? $_COOKIE['fbsz'] : false;
588$fbrowser_width = 1070;
589$fbrowser_height = 660;
590if($fbsz_increment) {
591    $fbrowser_width  = $fbrowser_width + ($fbrowser_width*($fbsz_increment/100));
592    $fbrowser_height  =$fbrowser_height + ($fbrowser_height*($fbsz_increment/100));
593}
594
595$doku_base=  rtrim(DOKU_BASE,'/');
596$ns = getNS($_COOKIE['FCK_NmSp']);
597
598//get user file browser if allowed
599if ($this->getConf('allow_ckg_filebrowser') == 'all') {
600    $fb = $this->getUserFb();
601} else {
602    //use only allowed file browser
603    $fb = $this->getConf('allow_ckg_filebrowser');
604}
605
606//setup options
607if ($fb == 'dokuwiki') {
608    $fbOptions = "filebrowserImageBrowseUrl: \"$doku_base/lib/exe/mediamanager.php?ns=$ns&edid=wiki__text&onselect=ckg_edit_mediaman_insert&ckg_media=img\",
609    filebrowserBrowseUrl: \"$doku_base/lib/exe/mediamanager.php?ns=$ns&edid=wiki__text&onselect=ckg_edit_mediaman_insertlink&ckg_media=link\"";
610} else {
611    $fbOptions = "filebrowserImageBrowseUrl :  \"$doku_base/lib/plugins/ckgedit/fckeditor/editor/filemanager/browser/default/browser.html?Type=Image&Connector=$doku_base/lib/plugins/ckgedit/fckeditor/editor/filemanager/connectors/php/connector.php\",
612    filebrowserBrowseUrl: \"$doku_base/lib/plugins/ckgedit/fckeditor/editor/filemanager/browser/default/browser.html?Type=File&Connector=$doku_base/lib/plugins/ckgedit/fckeditor/editor/filemanager/connectors/php/connector.php\"";
613}
614if($this->getConf('style_sheet')) {
615   $contents_css = $this->alt_style_sheet();
616}
617else {
618   $contents_css = "";
619}
620//msg($contents_css);
621$ckeditor_replace =<<<CKEDITOR_REPLACE
622
623		   ckgeditCKInstance = CKEDITOR.replace('wiki__text',
624		       {
625                  toolbar: '$toolbar' ,
626                  height: $height,
627                   filebrowserWindowWidth: $fbrowser_width,
628                   filebrowserWindowHeight:  $fbrowser_height,
629                  $fbOptions,
630                    on : {  'instanceReady' : function( evt ) {
631                         evt.editor.document.on( 'mousedown', function()
632                   {
633                              var browser_level = (window.top != window.self) ? window.self : window.top; browser_level.handlekeypress(evt);
634                             //  parent. handlekeypress(evt);
635                         } );
636                       }
637                     },
638                     on : {  'instanceReady' : function( evt ) {
639                         evt.editor.document.on( 'focus', function()
640                      {
641                               var browser_level = (window.top != window.self) ? window.self : window.top; browser_level.handlekeypress(evt);
642                              // parent. handlekeypress(evt);
643                         } );
644                      }
645                   },
646
647               }
648		   );
649           FCKeditor_OnComplete(ckgeditCKInstance);
650           if("$contents_css") {
651            CKEDITOR.config.contentsCss = "$contents_css";
652         }
653
654CKEDITOR_REPLACE;
655
656		 echo  $this->helper->registerOnLoad($ckeditor_replace);
657
658         global $skip_styling;
659
660?>
661<?php
662            global $INPUT;
663            if($this->page_from_template) {
664             $ckg_template = 'tpl';
665            }
666            else $ckg_template ="";
667
668             if($INPUT->has('hid')) {
669               $hid = $INPUT->str('hid');
670           }
671           else {
672               $hid = "";
673           }
674         /* accommodates include plugin's redirect to original page after editing included page */
675       $ckgedit_redirect =  $INPUT->str('redirect_id', "");
676
677 ?>
678   <form id="dw__editform" method="post" action="<?php echo script()?>"  accept-charset="<?php echo $lang['encoding']?>">
679    <div class="no">
680      <input type="hidden" name="id"   value="<?php echo $ID?>" />
681      <input type="hidden" name="rev"  value="<?php echo $REV?>" />
682      <input type="hidden" name="date" value="<?php echo $DATE?>" />
683      <input type="hidden" name="prefix" value="<?php echo formText($PRE)?>" />
684      <input type="hidden" name="suffix" value="<?php echo formText($SUF)?>" />
685      <input type="hidden" id="ckgedit_mode_type"  name="mode" value="" />
686      <input type="hidden" id="fck_preview_mode"  name="fck_preview_mode" value="nil" />
687      <input type="hidden" id="fck_wikitext"    name="fck_wikitext" value="__false__" />
688       <input type="hidden" id="styling"  name="styling" value="styles" />
689      <?php if(!empty($ckgedit_redirect)):?>
690     <input type="hidden" id="ckgedit_redirect"  name="ckgedit_redirect" value="<?php echo $ckgedit_redirect ?>" />
691      <?php endif ?>
692	  <?php if(!empty($hid)):?>
693       <input type="hidden" id="hid"  name="hid" value="<?php echo $hid; ?>" />
694	  <?php endif ?>
695      <input type="hidden" id="template"  name="template" value="<?php echo $ckg_template?>" />
696      <?php
697      if(function_exists('formSecurityToken')) {
698           formSecurityToken();
699      }
700      ?>
701    </div>
702<?php
703/*
704$this->xhtml=<<<ERRTXT
705[<a class="wikilink1 curid" data-curid="true" href="/dokuwiki/doku.php?id=*:*" title="*:*">go to top</a> | <a class="wikilink1" href="/dokuwiki/doku.php?id=*:start#system_configuration" title="*:start">back to Index</a> | <a class="wikilink1" href="/dokuwiki/doku.php?id=*:start" title="*:start">Wiki start page</a> ]
706ERRTXT;*/
707?>
708
709    <textarea name="wikitext" id="wiki__text" <?php echo $ro?> cols="80" rows="10" class="edit" tabindex="1"><?php echo "\n".$this->xhtml?></textarea>
710
711<?php
712
713$temp=array();
714
715if(class_exists('dokuwiki\Extension\Event')) {
716    Event::createAndTrigger('HTML_EDITFORM_INJECTION', $temp);
717}
718else {
719 trigger_event('HTML_EDITFORM_INJECTION', $temp);
720}
721$DW_EDIT_disabled = '';
722$guest_perm = auth_quickaclcheck($_REQUEST['id']);
723$guest_group = false;
724$guest_user = false;
725
726if(isset($INFO['userinfo'])&& isset($INFO['userinfo']['grps'])) {
727   $user_groups = $INFO['userinfo']['grps'];
728   if(is_array($user_groups) && $user_groups) {
729      foreach($user_groups as $group) {
730        if (strcasecmp('guest', $group) == 0) {
731          $guest_group = true;
732          break;
733        }
734     }
735   }
736  if($INFO['client'] == 'guest') $guest_user = true;
737}
738
739if(($guest_user || $guest_group) && $guest_perm <= 2) $DW_EDIT_disabled = 'disabled';
740global $USERINFO;
741$DW_EDIT_hide = $this->helper->dw_edit_displayed();
742$is_ckgeditChrome = false;
743 if(stripos($_SERVER['HTTP_USER_AGENT'],'Chrome') !== false) {
744      preg_match("/Chrome\/(\d+)/", $_SERVER['HTTP_USER_AGENT'],$cmatch);
745      if((int)$cmatch[1] <26)  $is_ckgeditChrome =true;
746}
747
748?>
749
750    <div id="wiki__editbar">
751      <div id="size__ctl" style="display: none"></div>
752      <?php if($wr){?>
753         <div class="editButtons">
754            <input type="checkbox" name="ckgedit" value="ckgedit" checked="checked" style="display: none"/>
755             <input class="button" type="button" id = "save_button"
756                   name="do[save]"
757                   value="<?php echo $lang['btn_save']?>"
758                   title="<?php echo $lang['btn_save']?> "
759                   <?php echo $DW_EDIT_disabled; ?>
760                  />
761
762            <input class="button" id="ebtn__delete" type="submit"
763                   <?php echo $DW_EDIT_disabled; ?>
764                   name="do[delete]" value="<?php echo $lang['btn_delete']?>"
765                   title="<?php echo $this->getLang('title_dw_delete') ?>"
766                   style = "font-size: 100%;"
767            />
768
769
770             <?php if(!$is_ckgeditChrome): ?>
771             <input class="button"  id = "ebtn__dwedit"
772                 <?php echo $DW_EDIT_disabled; ?>
773                 <?php echo $DW_EDIT_hide; ?>
774                 style = "font-size: 100%;"
775                 type="submit"
776                 name="do[save]"
777                 value="<?php echo $this->getLang('btn_dw_edit')?>"
778                 title="<?php echo $this->getLang('title_dw_edit')?>"
779                  />
780             <?php endif; ?>
781
782             <?php if($this->getConf('allow_ckg_filebrowser') == 'all'): ?>
783            <input class="button" id="ebtn__fbswitch"
784                   style="font-size: 100%;"
785                   type="submit"
786                   name="do[save]"
787                   value="<?php echo $this->get_switch_fb_value() ?>"
788                   title="<?php echo $this->get_switch_fb_title() ?>"
789                   />
790             <?php endif; ?>
791<?php
792global $INFO;
793
794  $disabled = 'Disabled';
795  $inline = $this->test ? 'inline' : 'none';
796  $chrome_dwedit_link =  '<a href="'.wl($INFO['id'],array('do'=>'show')).'" ' . 'onclick="draft_delete();setDWEditCookie(2);"class="action edit" rel="nofollow" title="DW Edit"><span>DW Edit</span></a>';
797  $backup_btn =$this->getLang('dw_btn_backup') ? $this->getLang('dw_btn_backup') : $this->getLang('dw_btn_refresh');
798  $backup_title = $this->getLang('title_dw_backup') ? $this->getLang('title_dw_backup') : $this->getLang('title_dw_refresh');
799  $using_scayt = ($this->getConf('scayt')) == 'on';
800
801?>
802            <input class="button" type="submit"
803                 name="do[draftdel]"
804                 id = "ebut_cancel"
805                 value="<?php echo $lang['btn_cancel']?>"
806                 style = "font-size: 100%;"
807                 title = "<?php echo $this->getLang('title_dw_cancel')?>"
808             />
809
810           <!-- aspell button removed, not supported -->
811
812            <input class="button" type="button" value = "Test"
813                   title="Test"
814                   style = 'display:<?php echo $inline ?>;'
815                   onmousedown="parse_wikitext('test');"
816                  />
817
818 <?php if($this->draft_found) { ?>
819             <input class="button"
820                 style = "background-color: yellow"
821                 id="ckgedit_draft_btn"
822                 type="button" value="<?php echo $this->getLang('btn_draft') ?>"
823                 title="<?php echo $this->getLang('title_draft') ?>"
824                  />
825 <?php } else { ?>
826
827
828             <input class="button" type="button"
829                   id = "backup_button"
830                   value="<?php echo $backup_btn ?>"
831                   title="<?php echo $backup_title ?>"
832
833                  />
834
835             <input class="button" type="button"
836                   id = "revert_to_prev_btn"
837                   value="<?php echo $this->getLang('dw_btn_revert')?>"
838                   title="<?php echo $this->getLang('title_dw_revert')?>"
839
840                  />
841     <?php if(!$skip_styling) : ?>
842              <input class="button" type="submit"
843                   name ="do[edit]"
844                   id = "no_styling_btn"
845                   style = "font-size: 100%;"
846                   value="<?php echo $this->getLang('dw_btn_styling')?>"
847                   title="<?php echo $this->getLang('title_styling')?>"
848                  />
849    <?php endif ?>
850             &nbsp;&nbsp;&nbsp;
851
852<?php
853if($is_ckgeditChrome) echo $chrome_dwedit_link;
854?>
855 <br />
856
857 <?php }  ?>
858
859 <?php if($this->debug) { ?>
860         <input class="button" type="button" value = "Debug"
861                   title="Debug"
862                   onclick="HTMLParser_debug();"
863                  />
864
865            <br />
866 <?php } ?>
867
868   <div id = "backup_msg" class="backup_msg" style=" display:none;">
869     <table><tr><td class = "backup_msg_td">
870      <div id="backup_msg_area" class="backup_msg_area"></div>
871     <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
872     <td align="right">
873      <a href="javascript:hide_backup_msg();void(0);" class="backup_msg_close">[ close ]</a>&nbsp;&nbsp;&nbsp;
874     </table>
875
876 </div>
877<?php
878
879if(!isset($_COOKIE['ckgEdPaste'])) {
880    $paste_value = 'on';
881}
882else {
883    $paste_value = (isset($_COOKIE['ckgEdPaste']) && $_COOKIE['ckgEdPaste'] == 'off' )  ? 'on' : 'off';
884}
885?>
886
887     <label class="nowrap" for="complex_tables" id="complex_tables_label">
888        <input type="checkbox" name="complex_tables" value="complex_tables"  id = "complex_tables"
889                     /><span id='complex_tables_label_text'> <?php echo $this->getLang('complex_tables');?></span></label>
890      &nbsp;&nbsp;<label class="nowrap" for="editor_height"><?php echo $this->getLang('editor_height');?></label>
891        <input type="text" size= "4" name="editor_height" title = "<?php echo $this->getLang('editor_height_title'); ?>" value="<?php echo $height?>"  id = "editor_height"  onchange="setEdHeight(this.value);" />  px
892    &nbsp;&nbsp;<label class="nowrap" for="ckg_img_paste" title ="<?php echo $this->getLang('ckg_img_paste_title'); ?>"> <?php echo $this->getLang('ckg_img_paste') . " ". $this->getLang($paste_value) ?></label>
893        &nbsp;<input type="checkbox" name="ckg_img_paste" title = "<?php echo $this->getLang('ckg_img_paste_title'); ?>"
894            id = "ckg_img_paste"  value = "<?php echo $paste_value?>" onchange="ckgd_setImgPaste(this.value);" />
895
896      <input style="display:none;" class="button" id="edbtn__save" type="submit" name="do[save]"
897                      value="<?php echo $lang['btn_save']?>"
898                      onmouseup="draft_delete();"
899                      <?php echo $DW_EDIT_disabled; ?>
900                      title="<?php echo $lang['btn_save']?> "  />
901
902            <!-- Not used by ckgedit but required to prevent null error when DW adds events -->
903            <input type="button" id='edbtn__preview' style="display: none"/>
904
905
906 <div id='saved_wiki_html' style = 'display:none;' ></div>
907 <div id='ckgedit_draft_html' style = 'display:none;' >
908 <?php echo $this->draft_text; ?>
909 </div>
910
911         </div>
912      <?php } ?>
913
914        <?php if($wr){ ?>
915            <div class="summary">
916                <label for="edit__summary" class="nowrap"><?php echo $lang['summary']?>:</label>
917                <input type="text" class="edit" name="summary" id="edit__summary" size="50" value="<?php echo formText($SUM)?>" tabindex="2" />
918                <label class="nowrap" for="minoredit"><input type="checkbox" id="minoredit" name="minor" value="1" tabindex="3" /> <span><?php echo $this->getLang('minor_changes') ?></span></label>
919            </div>
920        <?php }?>
921        <?php if($this->captcha && $this->captcha->isEnabled()) echo $this->captcha->getHTML(); ?>
922    </div>
923   </form>
924
925        <!-- draft messages from DW -->
926        <div id="draft__status"></div>
927  <script type="text/javascript">
928//<![CDATA[
929        <?php  echo 'var backup_empty = "' . $this->getLang('backup_empty') .'";'; ?>
930        /* aspell_window removed, not supported */
931        if(window.unsetDokuWikiLockTimer) window.unsetDokuWikiLockTimer();
932
933
934  function getComplexTables() {
935     return  document.getElementById('complex_tables').checked;
936  }
937
938    <?php  global $useComplexTables;  if($useComplexTables) { ?>
939        document.getElementById('complex_tables').click();
940    <?php } ?>
941    <?php  if($this->getConf('complex_tables')) { ?>
942         document.getElementById('complex_tables').disabled = true;
943         document.getElementById('complex_tables_label').style = "display:none";
944         document.getElementById('complex_tables_label_text').style = "display:none";
945    <?php } ?>
946
947<?php
948
949
950   if(preg_match("/MISIE|Trident/",$_SERVER['HTTP_USER_AGENT'])) {
951      echo "var isIE = true;";
952   }
953   else {
954     echo "var isIE = false;";
955   }
956
957   echo "var doku_base = '" . DOKU_BASE ."'";
958
959?>
960
961   var ckgedit_draft_btn = "<?php echo $this->getLang('btn_exit_draft') ?>";
962   var ckgedit_draft_btn_title = "<?php echo $this->getLang('title_exit_draft')?>";
963   function ckgedit_get_draft() {
964      var dom = GetE('ckgedit_draft_html');
965      var draft = dom.innerHTML;
966      var dw_text =  CKEDITOR.instances.wiki__text.getData();
967
968      CKEDITOR.instances.wiki__text.setData(draft);
969      dom.innerHTML = dw_text;
970      var btn = GetE('ckgedit_draft_btn');
971      var tmp = btn.value;
972      btn.value = ckgedit_draft_btn;
973      ckgedit_draft_btn = tmp;
974      tmp = ckgedit_draft_btn_title;
975      btn.title = ckgedit_draft_btn_title;
976      ckgedit_draft_btn_title = tmp;
977   }
978
979
980   function safe_convert(value) {
981
982     if(oDokuWiki_FCKEditorInstance.dwiki_fnencode && oDokuWiki_FCKEditorInstance.dwiki_fnencode == 'safe') {
983      <?php
984       global $updateVersion;
985       if(!isset($updateVersion)) $updateVersion = 0;
986       echo "updateVersion=$updateVersion;";
987       $list = plugin_list('action');
988       $safe_converted = false;
989       if(in_array( 'safefnrecode' , $list)) {
990          $safe_converted = true;
991       }
992
993     ?>
994
995 		if(value.match(/%25/ && value.match(/%25[a-z0-9]/))) {
996                          value = value.replace(/%25/g,"%");
997                          <?php
998                          if($updateVersion > 30 || $safe_converted) {
999                            echo 'value = value.replace(/%5D/g,"]");';
1000                          }
1001                          ?>
1002
1003                          value =  dwikiUTF8_decodeFN(value,'safe');
1004                       }
1005        }
1006        return value;
1007
1008     }
1009
1010RegExp.escape = function(str)
1011{
1012    var specials = new RegExp("[.*+?|()\\[\\]{}\\\\]", "g"); // .*+?|()[]{}\
1013    return str.replace(specials, "\\$&");
1014}
1015var ckgedit_xcl_fonts =parseInt  ("<?php echo $this->getConf('font_options') ;?>");
1016var ckgedit_xcl_colors =parseInt("<?php echo $this->getConf('color_options') ;?>");
1017var ckgedit_xcl_styles = (ckgedit_xcl_fonts + ckgedit_xcl_colors ==2) ? true : false;
1018var HTMLParser_DEBUG = "";
1019var ckgedit_hasCaptcha = "<?php echo $this->captcha?1:0?>";
1020
1021<?php if($this->debug) { ?>
1022   function HTMLParser_debug() {
1023       HTMLParser_DEBUG = "";
1024       parse_wikitext("");
1025/*
1026      for(var i in oDokuWiki_FCKEditorInstance) {
1027         HTMLParser_DEBUG += i + ' = ' + oDokuWiki_FCKEditorInstance[i] + "\n";;
1028       }
1029*/
1030
1031       var w = window.open();
1032       w.document.write('<pre>' + HTMLParser_DEBUG + '</pre>');
1033       w.document.close();
1034  }
1035<?php } ?>
1036
1037<?php
1038       global $conf;
1039
1040       if(isset($conf['animal'])) {
1041         echo "var config_animal='" . $conf['animal'] . "';";
1042       }
1043   ?>
1044
1045 //]]>
1046
1047  </script>
1048
1049
1050
1051<?php
1052    }
1053
1054    /**
1055     * Renders a list of instruction to minimal xhtml
1056     *@author Myron Turner <turnermm02@shaw.ca>
1057     */
1058    function _render_xhtml($text){
1059        $mode = 'ckgedit';
1060
1061        global $skip_styling, $INPUT;
1062        $post_styling = $INPUT->post->str('styling');
1063        $skip_styling =  $this->getConf('nofont_styling');
1064
1065        if(!$skip_styling && $post_styling == 'no_styles') {
1066            $skip_styling = true;
1067        }
1068
1069        if(strpos($text,'~~NO_STYLING~~') !== false) {
1070            $skip_styling = true;
1071        }
1072 //    $text = preg_replace("/\\\\(\n|\s)/ms","CODE_BLOCK_EOL_MASK$1",$text);
1073     $text = preg_replace_callback('/\[\[(.*?>)(.*?)\]\]/ms',
1074              function ($matches) {
1075                 if(strpos($matches[0],"\n") !== false) return $matches[0];
1076                 if(preg_match("#<(\w+)>.*?<\/\\1>#",$matches[0])) return $matches[0];
1077                 list($name,$link_text) = explode('|',$matches[2]);
1078                 $retv = '[[' . $matches[1] . "oIWIKIo" . $name ."cIWIKIc";
1079                 if(!empty($link_text)) {
1080                     $retv .= "|$link_text";
1081                 }
1082                 return $retv . ']]';
1083              },
1084           $text);
1085
1086        // try default renderer first:
1087        $file = DOKU_INC."inc/parser/$mode.php";
1088
1089        if(@file_exists($file)){
1090
1091            require_once $file;
1092            $rclass = "Doku_Renderer_$mode";
1093
1094            if ( !class_exists($rclass) ) {
1095                trigger_error("Unable to resolve render class $rclass",E_USER_WARNING);
1096                msg("Renderer for $mode not valid",-1);
1097                return null;
1098            }
1099            $Renderer = new $rclass();
1100        }
1101        else{
1102            // Maybe a plugin is available?
1103            $Renderer = plugin_load('renderer',$mode);
1104            if(is_null($Renderer)){
1105                msg("No renderer for $mode found",-1);
1106                return null;
1107            }
1108        }
1109// aimed at wrap plugin which allows multiple newlines in a cell
1110$text = preg_replace_callback(
1111    '#(\|.*?)\|.?[\n\r]#ms',
1112        function ($matches) {
1113            $matches[0] = preg_replace("#\\\\\\\\\s*[\r\n]#ms", "  \\\\\\\\  ",$matches[0]);
1114            return ($matches[0]);
1115        },
1116    $text);
1117
1118        // prevents utf8 conversions of quotation marks
1119         $text = str_replace('"',"_ckgedit_QUOT_",$text);
1120
1121        $text = preg_replace_callback('/(<code.*?>)([^<]+)(<\/code>)/ms',
1122            function($matches) {
1123                $quot = str_replace("_ckgedit_QUOT_", "\"", $matches[2]);
1124                $quot = str_replace("\\\\ ", "_ckgedit_NL", $quot);
1125                $quot .= "_ckgedit_NL";
1126                return $matches[1] . $quot . $matches[3];
1127          }, $text);
1128
1129         $text = preg_replace_callback('/(<file.*?>)([^<]+)(<\/file>)/ms',
1130            function($matches) {
1131                $quot = str_replace("_ckgedit_QUOT_", "\"", $matches[2]);
1132                $quot = str_replace("\\\\ ", "_ckgedit_NL", $quot);
1133                $quot .= "_ckgedit_NL";
1134                return $matches[1] . $quot . $matches[3];
1135          }, $text);
1136
1137          $text = preg_replace_callback('/\|([\s\S]+)\|/ms',  // prevents  extra backslash  from hanging on a new line
1138            function ($matches) {
1139                if(!strpos($matches[1], "_ckgedit_NL")) return $matches[0];
1140                $matches[1]  =  str_replace("\\_ckgedit_NL","_ckgedit_NL",$matches[1]);
1141
1142                return '|' . $matches[1] . '|';
1143                return $matches[0];
1144            },
1145           $text
1146        );
1147
1148          $text = preg_replace_callback('/(<code>|<file>)([^<]+)(<\/code>|<\/file>)/ms',
1149             function($matches) {
1150               $matches[2] = str_replace("&lt;font","ckgeditFONTOpen",$matches[2]);
1151               $matches[2] = str_replace("font&gt;","ckgeditFONTClose",$matches[2]);
1152                return $matches[1] .$matches[2] . $matches[3];
1153             }, $text);
1154
1155           $text = str_replace('CODE_BLOCK_EOL_MASK','\\', $text);
1156
1157            $instructions = p_get_instructions("=== header ==="); // loads DOKU_PLUGINS array --M.T. Dec 22 2009
1158
1159        $instructions = p_get_instructions($text);
1160        if(is_null($instructions)) return '';
1161
1162        $Renderer->notoc();
1163        if(!$this->getConf('smiley_as_text')) {
1164        $Renderer->smileys = getSmileys();
1165        }
1166        $Renderer->entities = getEntities();
1167        $Renderer->acronyms = array();
1168        $Renderer->interwiki = getInterwiki();
1169
1170        // Loop through the instructions
1171        /*
1172           By-passing plugin processing was sugested and first implemented
1173           by Matti Lattu<matti.lattu@iki.fi>
1174           It is a significant contribution to the functionality of ckgEdit
1175        */
1176        foreach ( $instructions as $instruction ) {
1177             if ($instruction[0] == 'plugin') {
1178                $Renderer->doc .= $instruction[1][3];
1179          } else {
1180               // Execute the callback against the Renderer
1181               call_user_func_array(array(&$Renderer, $instruction[0]),$instruction[1]);
1182            }
1183        }
1184
1185        //set info array
1186        $info = $Renderer->info;
1187
1188        // Post process and return the output
1189        $data = array($mode,& $Renderer->doc);
1190        if(class_exists('dokuwiki\Extension\Event')) {
1191           Event::createAndTrigger('RENDERER_CONTENT_POSTPROCESS', $data);
1192        }
1193        else {
1194        trigger_event('RENDERER_CONTENT_POSTPROCESS',$data);
1195        }
1196
1197        $xhtml = $Renderer->doc;
1198	    $xhtml = str_replace(
1199		    array('NWIKISTART','NWIKICLOSE'),
1200		    array('&amp;lt;nowiki>','&amp;lt;/nowiki>'),$xhtml);
1201
1202        if(!$skip_styling) {  // create font styles from font plugin markup for html display
1203        $xhtml = preg_replace_callback(
1204            '|&amp;lt;font\s+(.*?)/([\w ,\-]+);;([\(\)),\w,\s\#]+);;([\(\)),\w,\s\#]+)&gt;(.*?)&amp;lt;/font&gt;|ms',
1205             function($matches) {
1206               $count = 0; $str='';
1207              if($matches[3] && $matches[3] != 'inherit') { $str .= '<span style = "color:' . $matches[3] .'">'; $count++;}
1208              if($matches[1] && $matches[1] != 'inherit') { $str .= '<span style = "font-size:' . $matches[1] .'">'; $count++; }
1209              if($matches[2] && $matches[2] != 'inherit') { $str .= '<span style = "font-family:' . $matches[2] .'">'; $count++; }
1210              if($matches[4] && $matches[4] != 'inherit') { $str .= '<span style = "background-color:' . $matches[4] .'">'; $count++; }
1211              $str .= $matches[5];
1212              for($i =0; $i<$count; $i++) {
1213                  $str .= '</span>';
1214              }
1215               return $str;
1216             }, $xhtml
1217        );
1218        }
1219
1220    /**
1221     * Alternative to  the one liner at 1179:  $xhtml = str_replace(array('oiwikio','ciwikic'),array('oIWIKIo','cIWIKIc'),$xhtml);
1222     *  if it turns out that there are users using  'oiwikio','ciwikic'
1223     $xhtml = preg_replace_callback(
1224        '|class=\"interwiki.*?href=\".*?:oiwikiotowerciwikic\".*?title=\".*?oiwikiotowerciwikic\"|ms',
1225        function($matches) {
1226           $matches[0] = str_replace(array('oiwikio','ciwikic'),array('oIWIKIo','cIWIKIc'),$matches[0]);
1227          return $matches[0];
1228       },$xhtml
1229       );
1230     */
1231     if(stripos($xhtml,'oIWIKIo') !== false) {
1232        $xhtml = str_replace(array('oiwikio','ciwikic'),array('oIWIKIo','cIWIKIc'),$xhtml);
1233            $xhtml = preg_replace_callback(
1234                '/<?(.*?)oIWIKIo(.*?)cIWIKIc/ms',
1235                 function($matches) {
1236                     if(preg_match("/^\w+$/",$matches[2]) && $matches[1] == "/")  return "/". $matches[2];
1237                     return $matches[0];
1238                 },
1239              $xhtml
1240            );
1241            $xhtml = preg_replace_callback(
1242                '/>oIWIKIo(.*?)cIWIKIc(?=<\/a>)/ms',
1243                 function($matches) {
1244                    return ">". $matches[1] ;
1245                 },
1246              $xhtml
1247            );
1248
1249           }
1250
1251        $pos = strpos($xhtml, 'MULTI_PLUGIN_OPEN');
1252        if($pos !== false) {
1253           $xhtml = preg_replace_callback(
1254            '|MULTI_PLUGIN_OPEN.*?MULTI_PLUGIN_CLOSE|ms',
1255            function($matches) {
1256                  $matches[0] = str_replace("//<//", "< ",$matches[0]);
1257                  $matches[0] = str_replace(array("oIWIKIo","cIWIKIc"),"",$matches[0]);
1258                  return preg_replace("/\n/ms","<br />",$matches[0]);
1259            },
1260            $xhtml
1261          );
1262
1263           $xhtml = preg_replace('/~\s*~\s*MULTI_PLUGIN_OPEN~\s*~/', "\n\n~~MULTI_PLUGIN_OPEN~~<span class='multi_p_open'>\n\n</span>\n\n", $xhtml);
1264           $xhtml = preg_replace('/~\s*~\s*MULTI_PLUGIN_CLOSE~\s*~/', "<span class='multi_p_close'>\n\n<br /></span>\n\n~~MULTI_PLUGIN_CLOSE~~\n\n", $xhtml);
1265
1266        }
1267
1268
1269         // remove empty paragraph: see _ckgedit_NPBBR_ comment above
1270        $xhtml = preg_replace('/<p>\s+_ckgedit_NPBBR_\s+<\/p>/ms',"\n",$xhtml);
1271        $xhtml = str_replace('_ckgedit_NPBBR_', "<span class='np_break'>&nbsp;</span>", $xhtml);
1272        $xhtml = str_replace('_ckgedit_QUOT_', '&quot;', $xhtml);
1273        $xhtml = str_replace('_ckgedit_NL', "\n", $xhtml);
1274        $xhtml = str_replace('</pre>', "\n\n</pre><p>&nbsp;</p>", $xhtml);
1275        // inserts p before an initial codeblock to enable text entry above block
1276        $xhtml = preg_replace('/^<pre/',"<p>&nbsp;</p><pre",$xhtml);
1277        //remove empty markup remaining after removing marked-up acronyms in lists
1278        $xhtml = preg_replace('/<(em|b|u|i)>\s+<\/(em|b|u|i)>/ms',"",$xhtml);
1279        $xhtml = preg_replace("/col\d+\s+(\w+align)/ms", "$1",$xhtml);  //remove col number for cell prpoerties dialog
1280        $xhtml = str_replace('ckgeditFONTOpen', '&amp;lt;font',$xhtml);  // protect font markup in code blocks
1281        $xhtml = str_replace('ckgeditFONTClose', 'font&amp;gt;',$xhtml);
1282        $xhtml = str_replace('DBLBACKSPLASH', '\\ ',$xhtml);
1283        $xhtml = str_replace('NWPIPECHARACTER', '|',$xhtml);
1284        $xhtml = str_replace('&amp;lt;blockquote&gt;','<blockquote>',$xhtml);
1285        $xhtml = str_replace('&amp;lt;/blockquote&gt;','</blockquote>',$xhtml);
1286
1287       $xhtml= preg_replace_callback(
1288            '/(<p>\s*)?<blockquote>(.*?)<\/blockquote>(\s*<\/p>)?/ms',
1289            function($matches) {
1290                $matches[0] = preg_replace("/(<p>)?\s*(<blockquote>)\s*(<\/p>)?/m","<p></p>$2",$matches[0]);
1291                $matches[0] = preg_replace("/(<p>)?\s*(<\/blockquote>)\s*(<\/p>)?/m","$2<p></p>",$matches[0]);
1292             //   $matches[0] = str_replace('<blockquote>',  '<blockquote class ="blockquote-plugin">', $matches[0]);
1293               return $matches[0];
1294            },    $xhtml
1295        );
1296
1297      $ua = strtolower ($_SERVER['HTTP_USER_AGENT']);
1298	  if(strpos($ua,'chrome') !== false) {
1299       $xhtml = preg_replace_callback(
1300             '/(?<=<a )(href=\".*?\")(\s+\w+=\".*?\")(.*?)(?=>)/sm',
1301			 function($matches) {
1302			  $ret_str = " " . trim($matches[3]) . " " . trim($matches[2])  . " " . trim($matches[1]) ;
1303			  return $ret_str;
1304			 },
1305			 $xhtml
1306			 );
1307		}
1308
1309        return $xhtml;
1310    }
1311
1312  function write_debug($what,$line="") {
1313     return;
1314     $handle = fopen("ckgedit_php.txt", "a");
1315    // if(is_array($what)) $what = print_r($what,true);
1316     if($line) $what = "line $line\n" . $what;
1317     fwrite($handle,"$what\n");
1318     fclose($handle);
1319  }
1320
1321    function get_switch_fb_value() {
1322        if ($this->getUserFb() == 'dokuwiki') {
1323            $fbText = $this->getLang('btn_val_ckg_fb');
1324        } else {
1325            $fbText = $this->getLang('btn_val_dw_fb');
1326        }
1327        return $fbText;
1328    }
1329
1330    function get_switch_fb_title() {
1331        if ($this->getUserFb() == 'dokuwiki') {
1332            $fbText = $this->getLang('btn_title_ckg_fb');
1333        } else {
1334            $fbText = $this->getLang('btn_title_dw_fb');
1335        }
1336        return $fbText;
1337    }
1338
1339    function getUserFb() {
1340        //get user file browser
1341        if (!isset($_COOKIE['ckgFbOpt'])) {
1342            $_COOKIE['ckgFbOpt'] = $this->getConf('default_ckg_filebrowser');
1343        }
1344        return $_COOKIE['ckgFbOpt'];
1345    }
1346
1347} //end of action class
1348
1349?>
1350