includes/render.php
changeset 1027 98c052fc3337
parent 1003 28e2f75d66fd
child 1044 ad6a22377507
equal deleted inserted replaced
1026:f0431eb8161e 1027:98c052fc3337
   183   private static function next_gen_wiki_format($text, $flags = 0)
   183   private static function next_gen_wiki_format($text, $flags = 0)
   184   {
   184   {
   185     global $db, $session, $paths, $template, $plugins; // Common objects
   185     global $db, $session, $paths, $template, $plugins; // Common objects
   186     global $lang;
   186     global $lang;
   187     
   187     
   188     require_once(ENANO_ROOT.'/includes/wikiformat.php');
       
   189     require_once(ENANO_ROOT.'/includes/wikiengine/Tables.php');
       
   190     
       
   191     profiler_log("RenderMan: starting wikitext render");
   188     profiler_log("RenderMan: starting wikitext render");
   192     
   189     require_once( ENANO_ROOT . '/includes/wikiformat.php' );
       
   190     require_once( ENANO_ROOT . '/includes/wikiengine/TagSanitizer.php' );
       
   191     require_once( ENANO_ROOT . '/includes/wikiengine/Tables.php' );
       
   192     
       
   193     // this is still needed by parser plugins
   193     $random_id = md5( time() . mt_rand() );
   194     $random_id = md5( time() . mt_rand() );
   194     
   195     
   195     // Strip out <nowiki> sections and PHP code
   196     // Strip out <nowiki> sections and PHP code
   196     
   197     
   197     $nw = preg_match_all('#<nowiki>(.*?)<\/nowiki>#is', $text, $nowiki);
   198     self::nowiki_strip($text, $nowiki_stripped);
   198     
       
   199     for($i=0;$i<sizeof($nowiki[1]);$i++)
       
   200     {
       
   201       $text = str_replace('<nowiki>'.$nowiki[1][$i].'</nowiki>', '{NOWIKI:'.$random_id.':'.$i.'}', $text);
       
   202     }
       
   203     
   199     
   204     $code = $plugins->setHook('render_wikiformat_veryearly');
   200     $code = $plugins->setHook('render_wikiformat_veryearly');
   205     foreach ( $code as $cmd )
   201     foreach ( $code as $cmd )
   206     {
   202     {
   207       eval($cmd);
   203       eval($cmd);
   208     }
   204     }
   209     
   205     
   210     $php = preg_match_all('#<\?php(.*?)\?>#is', $text, $phpsec);
   206     self::php_strip($text, $php_stripped);
   211     
   207     
   212     for($i=0;$i<sizeof($phpsec[1]);$i++)
   208     $carpenter = new Carpenter();
   213     {
   209     $carpenter->flags = $flags;
   214       $text = str_replace('<?php'.$phpsec[1][$i].'?>', '{PHP:'.$random_id.':'.$i.'}', $text);
   210     $carpenter->hook(array(__CLASS__, 'hook_pre'), PO_AFTER, 'lang');
   215     }
   211     $carpenter->hook(array(__CLASS__, 'hook_posttemplates'), PO_AFTER, 'templates');
   216     
   212     if ( $flags & RENDER_WIKI_TEMPLATE )
       
   213     {
       
   214       // FIXME: process noinclude/nodisplay
       
   215     }
       
   216     $text = $carpenter->render($text);
       
   217     
       
   218     // For plugin compat
       
   219     $result =& $text;
       
   220     
       
   221     $code = $plugins->setHook('render_wikiformat_post');
       
   222     foreach ( $code as $cmd )
       
   223     {
       
   224       eval($cmd);
       
   225     }
       
   226     
       
   227     /*
   217     $text = preg_replace('/<noinclude>(.*?)<\/noinclude>/is', '\\1', $text);
   228     $text = preg_replace('/<noinclude>(.*?)<\/noinclude>/is', '\\1', $text);
   218     if ( $paths->namespace == 'Template' )
   229     if ( $paths->namespace == 'Template' )
   219     {
   230     {
   220       $text = preg_replace('/<nodisplay>(.*?)<\/nodisplay>/is', '', $text);
   231       $text = preg_replace('/<nodisplay>(.*?)<\/nodisplay>/is', '', $text);
   221     }
   232     }
   222     
   233     
   223     if ( !($flags & RENDER_BLOCKONLY) )
       
   224     {
       
   225       preg_match_all('/<lang (?:code|id)="([a-z0-9_-]+)">([\w\W]+?)<\/lang>/', $text, $langmatch);
       
   226       foreach ( $langmatch[0] as $i => $match )
       
   227       {
       
   228         if ( $langmatch[1][$i] == $lang->lang_code )
       
   229         {
       
   230           $text = str_replace_once($match, $langmatch[2][$i], $text);
       
   231         }
       
   232         else
       
   233         {
       
   234           $text = str_replace_once($match, '', $text);
       
   235         }
       
   236       }
       
   237     
       
   238       $code = $plugins->setHook('render_wikiformat_pre');
       
   239       foreach ( $code as $cmd )
       
   240       {
       
   241         eval($cmd);
       
   242       }
       
   243     
       
   244     //$template_regex = "/\{\{([^\]]+?)((\n([ ]*?)[A-z0-9]+([ ]*?)=([ ]*?)(.+?))*)\}\}/is";
       
   245       $template_regex = "/\{\{(.+)((\n|\|[ ]*([A-z0-9]+)[ ]*=[ ]*(.+))*)\}\}/isU";
       
   246       $i = 0;
       
   247       while ( preg_match($template_regex, $text) )
       
   248       {
       
   249         $i++;
       
   250         if ( $i == 5 )
       
   251           break;
       
   252         $text = RenderMan::include_templates($text);
       
   253       }
       
   254       
       
   255       $code = $plugins->setHook('render_wikiformat_posttemplates');
       
   256       foreach ( $code as $cmd )
       
   257       {
       
   258         eval($cmd);
       
   259       }
       
   260       
       
   261       // Process images
       
   262       $text = RenderMan::process_image_tags($text, $taglist);
       
   263       $text = RenderMan::process_imgtags_stage2($text, $taglist);
       
   264     }
       
   265     
       
   266     // Before shipping it out to the renderer, replace spaces in between headings and paragraphs:
       
   267     $text = preg_replace('/<\/(h[0-9]|div|p)>([\s]+)<(h[0-9]|div|p)( .+?)?>/i', '</\\1><\\3\\4>', $text);
       
   268     
       
   269     $text = process_tables($text);
   234     $text = process_tables($text);
   270     
   235     */
   271     if ( !($flags & RENDER_BLOCKONLY) )
   236     
   272       $text = RenderMan::parse_internal_links($text);
   237     self::nowiki_unstrip($text, $nowiki_stripped);
   273     
   238     self::php_unstrip($text, $php_stripped);
   274     $wiki = Text_Wiki::singleton('Mediawiki');
       
   275     $wiki->setRenderConf('Xhtml', 'wikilink', 'view_url', contentPath);
       
   276     $wiki->setRenderConf('Xhtml', 'Url', 'css_descr', 'external');
       
   277     if ( $flags & RENDER_BLOCKONLY )
       
   278     {
       
   279       $wiki->disableRule('Freelink');
       
   280       $wiki->disableRule('Url');
       
   281       $wiki->disableRule('Toc');
       
   282       $wiki->disableRule('Image');
       
   283     }
       
   284     else if ( $flags & RENDER_INLINEONLY )
       
   285     {
       
   286       foreach ( array('code', 'html', 'raw', 'include', 'embed', 'horiz', 'break', 'blockquote', 'list', 'newline', 'paragraph', 'revise', 'tighten') as $rule )
       
   287       {
       
   288         $wiki->disableRule($rule);
       
   289       }
       
   290     }
       
   291     $result = $wiki->transform($text, 'Xhtml');
       
   292     
       
   293     // HTML fixes
       
   294     $result = preg_replace('#<tr>([\s]*?)<\/tr>#is', '', $result);
       
   295     $result = preg_replace('#<p>([\s]*?)<\/p>#is', '', $result);
       
   296     $result = preg_replace('#<br />([\s]*?)<table#is', '<table', $result);
       
   297     $result = str_replace("<pre><code>\n", "<pre><code>", $result);
       
   298     $result = preg_replace("/<p><table([^>]*?)><\/p>/", "<table\\1>", $result);
       
   299     $result = str_replace("<br />\n</td>", "\n</td>", $result);
       
   300     $result = str_replace("<p><tr>", "<tr>", $result);
       
   301     $result = str_replace("<tr><br />", "<tr>", $result);
       
   302     $result = str_replace("</tr><br />", "</tr>", $result);
       
   303     $result = str_replace("</table><br />", "</table>", $result);
       
   304     $result = preg_replace('/<\/table>$/', "</table><br /><br />", $result);
       
   305     $result = str_replace("<p></div></p>", "</div>", $result);
       
   306     $result = str_replace("<p></table></p>", "</table>", $result);
       
   307     
       
   308     if ( !($flags & RENDER_BLOCKONLY) )
       
   309     {
       
   310       $code = $plugins->setHook('render_wikiformat_post');
       
   311       foreach ( $code as $cmd )
       
   312       {
       
   313         eval($cmd);
       
   314       }
       
   315     }
       
   316     
       
   317     // Reinsert <nowiki> sections
       
   318     for($i=0;$i<$nw;$i++)
       
   319     {
       
   320       $result = str_replace('{NOWIKI:'.$random_id.':'.$i.'}', $nowiki[1][$i], $result);
       
   321     }
       
   322     
       
   323     // Reinsert PHP
       
   324     for($i=0;$i<$php;$i++)
       
   325     {
       
   326       $result = str_replace('{PHP:'.$random_id.':'.$i.'}', '<?php'.$phpsec[1][$i].'?>', $result);
       
   327     }
       
   328     
   239     
   329     profiler_log("RenderMan: finished wikitext render");
   240     profiler_log("RenderMan: finished wikitext render");
   330     
   241     
   331     return $result;
   242     return $text;
   332     
   243   }
   333   }
   244   
       
   245   public static function hook_pre($text)
       
   246   {
       
   247     global $db, $session, $paths, $template, $plugins; // Common objects
       
   248     
       
   249     $code = $plugins->setHook('render_wikiformat_pre');
       
   250     foreach ( $code as $cmd )
       
   251     {
       
   252       eval($cmd);
       
   253     }
       
   254     
       
   255     return $text;
       
   256   }
       
   257   
       
   258   public static function hook_posttemplates($text)
       
   259   {
       
   260     global $db, $session, $paths, $template, $plugins; // Common objects
       
   261     
       
   262     $code = $plugins->setHook('render_wikiformat_posttemplates');
       
   263     foreach ( $code as $cmd )
       
   264     {
       
   265       eval($cmd);
       
   266     }
       
   267     
       
   268     return $text;
       
   269   }
       
   270   
       
   271   /**
       
   272    * Strip out <nowiki> tags (to bypass parsing on them)
       
   273    * @access private
       
   274    */
       
   275   
       
   276   private static function nowiki_strip(&$text, &$stripdata)
       
   277   {
       
   278     self::tag_strip('nowiki', $text, $stripdata);
       
   279   }
       
   280   
       
   281   /**
       
   282    * Restore stripped <nowiki> tags.
       
   283    * @access private
       
   284    */
       
   285   
       
   286   public static function nowiki_unstrip(&$text, &$stripdata)
       
   287   {
       
   288     self::tag_unstrip('nowiki', $text, $stripdata);
       
   289   }
       
   290   
       
   291   /**
       
   292    * Strip out an arbitrary HTML tag.
       
   293    * @access private
       
   294    */
       
   295   
       
   296   public static function tag_strip($tag, &$text, &$stripdata)
       
   297   {
       
   298     $random_id = md5( time() . mt_rand() );
       
   299     
       
   300     preg_match_all("#<$tag>(.*?)</$tag>#is", $text, $blocks);
       
   301     
       
   302     foreach ( $blocks[0] as $i => $match )
       
   303     {
       
   304       $text = str_replace($match, "{{$tag}:{$random_id}:{$i}}", $text);
       
   305     }
       
   306     
       
   307     $stripdata = array(
       
   308         'random_id' => $random_id,
       
   309         'blocks' => $blocks[1]
       
   310       );
       
   311   }
       
   312   
       
   313   /**
       
   314    * Restore stripped <nowiki> tags.
       
   315    * @access private
       
   316    */
       
   317   
       
   318   public static function tag_unstrip($tag, &$text, &$stripdata)
       
   319   {
       
   320     $random_id = $stripdata['random_id'];
       
   321     
       
   322     foreach ( $stripdata['blocks'] as $i => $block )
       
   323     {
       
   324       $text = str_replace("{{$tag}:{$random_id}:{$i}}", $block, $text);
       
   325     }
       
   326     
       
   327     $stripdata = array();
       
   328   }
       
   329   
       
   330   /**
       
   331    * Strip out PHP code (to prevent it from being sent through the parser). Private because it does not do what you think it does. (The method you are looking for is strip_php.)
       
   332    * @access private
       
   333    */
       
   334   
       
   335   private static function php_strip(&$text, &$stripdata)
       
   336   {
       
   337     $random_id = md5( time() . mt_rand() );
       
   338     
       
   339     preg_match_all('#<\?(?:php)?[\s=].+?\?>#is', $text, $blocks);
       
   340     
       
   341     foreach ( $blocks[0] as $i => $match )
       
   342     {
       
   343       $text = str_replace($match, "{PHP:$random_id:$i}", $text);
       
   344     }
       
   345     
       
   346     $stripdata = array(
       
   347         'random_id' => $random_id,
       
   348         'blocks' => $blocks[0]
       
   349       );
       
   350   }
       
   351   
       
   352   /**
       
   353    * Restore stripped PHP code
       
   354    * @access private
       
   355    */
       
   356   
       
   357   private static function php_unstrip(&$text, &$stripdata)
       
   358   {
       
   359     $random_id = $stripdata['random_id'];
       
   360     
       
   361     foreach ( $stripdata['blocks'] as $i => $block )
       
   362     {
       
   363       $text = str_replace("{PHP:$random_id:$i}", $block, $text);
       
   364     }
       
   365     
       
   366     $stripdata = array();
       
   367   }
       
   368   
       
   369   /**
       
   370    * Deprecated.
       
   371    */
   334   
   372   
   335   public static function wikiFormat($message, $filter_links = true, $do_params = false, $plaintext = false)
   373   public static function wikiFormat($message, $filter_links = true, $do_params = false, $plaintext = false)
   336   {
   374   {
   337     global $db, $session, $paths, $template, $plugins; // Common objects
   375     global $db, $session, $paths, $template, $plugins; // Common objects
   338     
   376     
   779   }
   817   }
   780   
   818   
   781   /**
   819   /**
   782    * Preprocesses an HTML text string prior to being sent to MySQL.
   820    * Preprocesses an HTML text string prior to being sent to MySQL.
   783    * @param string $text
   821    * @param string $text
   784    * @param bool $strip_all_php - if true, strips all PHP regardless of user permissions. Else, strips PHP only if user level < USER_LEVEL_ADMIN.
   822    * @param bool $strip_all_php - if true, strips all PHP regardless of user permissions. Else, strips PHP only if user level < USER_LEVEL_ADMIN. Defaults to true.
   785    */
   823    * @param bool $sqlescape - if true, sends text through $db->escape(). Otherwise returns unescaped text. Defaults to true.
   786   public static function preprocess_text($text, $strip_all_php = true, $sqlescape = true)
   824    * @param bool $reduceheadings - if true, finds HTML headings and replaces them with wikitext. Else, does not touch headings. Defaults to true.
       
   825    */
       
   826   public static function preprocess_text($text, $strip_all_php = true, $sqlescape = true, $reduceheadings = true)
   787   {
   827   {
   788     global $db, $session, $paths, $template, $plugins; // Common objects
   828     global $db, $session, $paths, $template, $plugins; // Common objects
   789     $random_id = md5( time() . mt_rand() );
   829     $random_id = md5( time() . mt_rand() );
   790     
   830     
   791     $code = $plugins->setHook('render_sanitize_pre');
   831     $code = $plugins->setHook('render_sanitize_pre');
   834     foreach ( $code as $cmd )
   874     foreach ( $code as $cmd )
   835     {
   875     {
   836       eval($cmd);
   876       eval($cmd);
   837     }
   877     }
   838     
   878     
   839     // gently apply some reverse-processing to allow Text_Wiki to do magic with TOCs and stuff
   879     // gently apply some reverse-processing to allow the parser to do magic with TOCs and stuff
   840     $text = self::reverse_process_headings($text);
   880     if ( $reduceheadings )
       
   881       $text = self::reverse_process_headings($text);
   841     
   882     
   842     // Reinsert <nowiki> sections
   883     // Reinsert <nowiki> sections
   843     for($i=0;$i<$nw;$i++)
   884     for($i=0;$i<$nw;$i++)
   844     {
   885     {
   845       $text = str_replace('{NOWIKI:'.$random_id.':'.$i.'}', '<nowiki>'.$nowiki[1][$i].'</nowiki>', $text);
   886       $text = str_replace('{NOWIKI:'.$random_id.':'.$i.'}', '<nowiki>'.$nowiki[1][$i].'</nowiki>', $text);