[ Index ]
 

Code source de DokuWiki 2006-11-06

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/inc/ -> parserutils.php (source)

   1  <?php
   2  /**
   3   * Utilities for collecting data from config files
   4   *
   5   * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
   6   * @author     Harry Fuecks <hfuecks@gmail.com>
   7   * @author     Andreas Gohr <andi@splitbrain.org>
   8   */
   9  
  10    if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
  11  
  12    require_once (DOKU_INC.'inc/confutils.php');
  13    require_once (DOKU_INC.'inc/pageutils.php');
  14    require_once (DOKU_INC.'inc/pluginutils.php');
  15    require_once (DOKU_INC.'inc/cache.php');
  16  
  17  /**
  18   * Returns the parsed Wikitext in XHTML for the given id and revision.
  19   *
  20   * If $excuse is true an explanation is returned if the file
  21   * wasn't found
  22   *
  23   * @author Andreas Gohr <andi@splitbrain.org>
  24   */
  25  function p_wiki_xhtml($id, $rev='', $excuse=true){
  26    $file = wikiFN($id,$rev);
  27    $ret  = '';
  28  
  29    //ensure $id is in global $ID (needed for parsing)
  30    global $ID;
  31    $keep = $ID;
  32    $ID   = $id;
  33  
  34    if($rev){
  35      if(@file_exists($file)){
  36        $ret = p_render('xhtml',p_get_instructions(io_readfile($file)),$info); //no caching on old revisions
  37      }elseif($excuse){
  38        $ret = p_locale_xhtml('norev');
  39      }
  40    }else{
  41      if(@file_exists($file)){
  42        $ret = p_cached_output($file,'xhtml',$id);
  43      }elseif($excuse){
  44        $ret = p_locale_xhtml('newpage');
  45      }
  46    }
  47  
  48    //restore ID (just in case)
  49    $ID = $keep;
  50  
  51    return $ret;
  52  }
  53  
  54  /**
  55   * Returns starting summary for a page (e.g. the first few
  56   * paragraphs), marked up in XHTML.
  57   *
  58   * If $excuse is true an explanation is returned if the file
  59   * wasn't found
  60   *
  61   * @param string wiki page id
  62   * @param reference populated with page title from heading or page id
  63   * @deprecated
  64   * @author Harry Fuecks <hfuecks@gmail.com>
  65   */
  66  function p_wiki_xhtml_summary($id, &$title, $rev='', $excuse=true){
  67    $file = wikiFN($id,$rev);
  68    $ret  = '';
  69  
  70    //ensure $id is in global $ID (needed for parsing)
  71    global $ID;
  72    $keep = $ID;
  73    $ID   = $id;
  74  
  75    if($rev){
  76      if(@file_exists($file)){
  77        //no caching on old revisions
  78        $ins = p_get_instructions(io_readfile($file));
  79      }elseif($excuse){
  80        $ret = p_locale_xhtml('norev');
  81        //restore ID (just in case)
  82        $ID = $keep;
  83        return $ret;
  84      }
  85  
  86    }else{
  87  
  88      if(@file_exists($file)){
  89        // The XHTML for a summary is not cached so use the instruction cache
  90        $ins = p_cached_instructions($file);
  91      }elseif($excuse){
  92        $ret = p_locale_xhtml('newpage');
  93        //restore ID (just in case)
  94        $ID = $keep;
  95        return $ret;
  96      }
  97    }
  98  
  99    $ret = p_render('xhtmlsummary',$ins,$info);
 100  
 101    if ( $info['sum_pagetitle'] ) {
 102      $title = $info['sum_pagetitle'];
 103    } else {
 104      $title = $id;
 105    }
 106  
 107    $ID = $keep;
 108    return $ret;
 109  }
 110  
 111  /**
 112   * Returns the specified local text in parsed format
 113   *
 114   * @author Andreas Gohr <andi@splitbrain.org>
 115   */
 116  function p_locale_xhtml($id){
 117    //fetch parsed locale
 118    $html = p_cached_output(localeFN($id));
 119    return $html;
 120  }
 121  
 122  /**
 123   *     *** DEPRECATED ***
 124   *
 125   * use p_cached_output()
 126   *
 127   * Returns the given file parsed to XHTML
 128   *
 129   * Uses and creates a cachefile
 130   *
 131   * @deprecated
 132   * @author Andreas Gohr <andi@splitbrain.org>
 133   * @todo   rewrite to use mode instead of hardcoded XHTML
 134   */
 135  function p_cached_xhtml($file){
 136    return p_cached_output($file);
 137  }
 138  
 139  /**
 140   * Returns the given file parsed into the requested output format
 141   *
 142   * @author Andreas Gohr <andi@splitbrain.org>
 143   * @author Chris Smith <chris@jalakai.co.uk>
 144   */
 145  function p_cached_output($file, $format='xhtml', $id='') {
 146    global $conf;
 147  
 148    $cache = new cache_renderer($id, $file, $format);
 149    if ($cache->useCache()) {
 150      $parsed = $cache->retrieveCache();
 151      if($conf['allowdebug']) $parsed .= "\n<!-- cachefile {$cache->cache} used -->\n";
 152    } else {
 153      $parsed = p_render($format, p_cached_instructions($file,false,$id), $info);
 154  
 155      if ($info['cache']) {
 156        $cache->storeCache($parsed);               //save cachefile
 157        if($conf['allowdebug']) $parsed .= "\n<!-- no cachefile used, but created -->\n";
 158      }else{
 159        $cache->removeCache();                     //try to delete cachefile
 160        if($conf['allowdebug']) $parsed .= "\n<!-- no cachefile used, caching forbidden -->\n";
 161      }
 162    }
 163  
 164    return $parsed;
 165  }
 166  
 167  /**
 168   * Returns the render instructions for a file
 169   *
 170   * Uses and creates a serialized cache file
 171   *
 172   * @author Andreas Gohr <andi@splitbrain.org>
 173   */
 174  function p_cached_instructions($file,$cacheonly=false,$id='') {
 175    global $conf;
 176  
 177    $cache = new cache_instructions($id, $file);
 178  
 179    if ($cacheonly || $cache->useCache()) {
 180      return $cache->retrieveCache();
 181    } else if (@file_exists($file)) {
 182      // no cache - do some work
 183      $ins = p_get_instructions(io_readfile($file));
 184      $cache->storeCache($ins);
 185      return $ins;
 186    }
 187  
 188    return NULL;
 189  }
 190  
 191  /**
 192   * turns a page into a list of instructions
 193   *
 194   * @author Harry Fuecks <hfuecks@gmail.com>
 195   * @author Andreas Gohr <andi@splitbrain.org>
 196   */
 197  function p_get_instructions($text){
 198  
 199    $modes = p_get_parsermodes();
 200  
 201    // Create the parser
 202    $Parser = & new Doku_Parser();
 203  
 204    // Add the Handler
 205    $Parser->Handler = & new Doku_Handler();
 206  
 207    //add modes to parser
 208    foreach($modes as $mode){
 209      $Parser->addMode($mode['mode'],$mode['obj']);
 210    }
 211  
 212    // Do the parsing
 213    trigger_event('PARSER_WIKITEXT_PREPROCESS', $text);
 214    $p = $Parser->parse($text);
 215  //  dbg($p);
 216    return $p;
 217  }
 218  
 219  /**
 220   * returns the metadata of a page
 221   *
 222   * @author Esther Brunner <esther@kaffeehaus.ch>
 223   */
 224  function p_get_metadata($id, $key=false, $render=false){
 225    global $INFO;
 226  
 227    if ($id == $INFO['id'] && !empty($INFO['meta'])) {
 228      $meta = $INFO['meta'];
 229    } else {
 230      $file = metaFN($id, '.meta');
 231  
 232      if (@file_exists($file)) $meta = unserialize(io_readFile($file, false));
 233      else $meta = array();
 234  
 235      // metadata has never been rendered before - do it!
 236      if ($render && !$meta['description']['abstract']){
 237        $meta = p_render_metadata($id, $meta);
 238        io_saveFile($file, serialize($meta));
 239      }
 240    }
 241  
 242    // filter by $key
 243    if ($key){
 244      list($key, $subkey) = explode(' ', $key, 2);
 245      if (trim($subkey)) return $meta[$key][$subkey];
 246      else return $meta[$key];
 247    }
 248  
 249    return $meta;
 250  }
 251  
 252  /**
 253   * sets metadata elements of a page
 254   *
 255   * @author Esther Brunner <esther@kaffeehaus.ch>
 256   */
 257  function p_set_metadata($id, $data, $render=false){
 258    if (!is_array($data)) return false;
 259  
 260    $orig = p_get_metadata($id);
 261  
 262    // render metadata first?
 263    if ($render) $meta = p_render_metadata($id, $orig);
 264    else $meta = $orig;
 265  
 266    // now add the passed metadata
 267    $protected = array('description', 'date', 'contributor');
 268    foreach ($data as $key => $value){
 269  
 270      // be careful with sub-arrays of $meta['relation']
 271      if ($key == 'relation'){
 272        foreach ($value as $subkey => $subvalue){
 273          $meta[$key][$subkey] = array_merge($meta[$key][$subkey], $subvalue);
 274        }
 275  
 276      // be careful with some senisitive arrays of $meta
 277      } elseif (in_array($key, $protected)){
 278        if (is_array($value)){
 279          #FIXME not sure if this is the intended thing:
 280          if(!is_array($meta[$key])) $meta[$key] = array($meta[$key]);
 281          $meta[$key] = array_merge($meta[$key], $value);
 282        }
 283  
 284      // no special treatment for the rest
 285      } else {
 286        $meta[$key] = $value;
 287      }
 288    }
 289  
 290    // save only if metadata changed
 291    if ($meta == $orig) return true;
 292  
 293    // check if current page metadata has been altered - if so sync the changes
 294    global $INFO;
 295    if ($id == $INFO['id'] && isset($INFO['meta'])) {
 296      $INFO['meta'] = $meta;
 297    }
 298  
 299    return io_saveFile(metaFN($id, '.meta'), serialize($meta));
 300  }
 301  
 302  /**
 303   * renders the metadata of a page
 304   *
 305   * @author Esther Brunner <esther@kaffeehaus.ch>
 306   */
 307  function p_render_metadata($id, $orig){
 308    require_once  DOKU_INC."inc/parser/metadata.php";
 309  
 310    // get instructions
 311    $instructions = p_cached_instructions(wikiFN($id),false,$id);
 312  
 313    // set up the renderer
 314    $renderer = & new Doku_Renderer_metadata();
 315    $renderer->meta = $orig;
 316  
 317    // loop through the instructions
 318    foreach ($instructions as $instruction){
 319      // execute the callback against the renderer
 320      call_user_func_array(array(&$renderer, $instruction[0]), $instruction[1]);
 321    }
 322  
 323    return $renderer->meta;
 324  }
 325  
 326  /**
 327   * returns all available parser syntax modes in correct order
 328   *
 329   * @author Andreas Gohr <andi@splitbrain.org>
 330   */
 331  function p_get_parsermodes(){
 332    global $conf;
 333  
 334    //reuse old data
 335    static $modes = null;
 336    if($modes != null){
 337      return $modes;
 338    }
 339  
 340    //import parser classes and mode definitions
 341    require_once  DOKU_INC . 'inc/parser/parser.php';
 342  
 343    // we now collect all syntax modes and their objects, then they will
 344    // be sorted and added to the parser in correct order
 345    $modes = array();
 346  
 347    // add syntax plugins
 348    $pluginlist = plugin_list('syntax');
 349    if(count($pluginlist)){
 350      global $PARSER_MODES;
 351      $obj = null;
 352      foreach($pluginlist as $p){
 353        if(!$obj =& plugin_load('syntax',$p)) continue; //attempt to load plugin into $obj
 354        $PARSER_MODES[$obj->getType()][] = "plugin_$p"; //register mode type
 355        //add to modes
 356        $modes[] = array(
 357                     'sort' => $obj->getSort(),
 358                     'mode' => "plugin_$p",
 359                     'obj'  => $obj,
 360                   );
 361        unset($obj); //remove the reference
 362      }
 363    }
 364  
 365    // add default modes
 366    $std_modes = array('listblock','preformatted','notoc','nocache',
 367                       'header','table','linebreak','footnote','hr',
 368                       'unformatted','php','html','code','file','quote',
 369                       'internallink','rss','media','externallink',
 370                       'emaillink','windowssharelink','eol');
 371    if($conf['typography']){
 372      $std_modes[] = 'quotes';
 373      $std_modes[] = 'multiplyentity';
 374    }
 375    foreach($std_modes as $m){
 376      $class = "Doku_Parser_Mode_$m";
 377      $obj   = new $class();
 378      $modes[] = array(
 379                   'sort' => $obj->getSort(),
 380                   'mode' => $m,
 381                   'obj'  => $obj
 382                 );
 383    }
 384  
 385    // add formatting modes
 386    $fmt_modes = array('strong','emphasis','underline','monospace',
 387                       'subscript','superscript','deleted');
 388    foreach($fmt_modes as $m){
 389      $obj   = new Doku_Parser_Mode_formatting($m);
 390      $modes[] = array(
 391                   'sort' => $obj->getSort(),
 392                   'mode' => $m,
 393                   'obj'  => $obj
 394                 );
 395    }
 396  
 397    // add modes which need files
 398    $obj     = new Doku_Parser_Mode_smiley(array_keys(getSmileys()));
 399    $modes[] = array('sort' => $obj->getSort(), 'mode' => 'smiley','obj'  => $obj );
 400    $obj     = new Doku_Parser_Mode_acronym(array_keys(getAcronyms()));
 401    $modes[] = array('sort' => $obj->getSort(), 'mode' => 'acronym','obj'  => $obj );
 402    $obj     = new Doku_Parser_Mode_entity(array_keys(getEntities()));
 403    $modes[] = array('sort' => $obj->getSort(), 'mode' => 'entity','obj'  => $obj );
 404  
 405  
 406    // add optional camelcase mode
 407    if($conf['camelcase']){
 408      $obj     = new Doku_Parser_Mode_camelcaselink();
 409      $modes[] = array('sort' => $obj->getSort(), 'mode' => 'camelcaselink','obj'  => $obj );
 410    }
 411  
 412    //sort modes
 413    usort($modes,'p_sort_modes');
 414  
 415    return $modes;
 416  }
 417  
 418  /**
 419   * Callback function for usort
 420   *
 421   * @author Andreas Gohr <andi@splitbrain.org>
 422   */
 423  function p_sort_modes($a, $b){
 424    if($a['sort'] == $b['sort']) return 0;
 425    return ($a['sort'] < $b['sort']) ? -1 : 1;
 426  }
 427  
 428  /**
 429   * Renders a list of instruction to the specified output mode
 430   *
 431   * In the $info array are informations from the renderer returned
 432   *
 433   * @author Harry Fuecks <hfuecks@gmail.com>
 434   * @author Andreas Gohr <andi@splitbrain.org>
 435   */
 436  function p_render($mode,$instructions,& $info){
 437    if(is_null($instructions)) return '';
 438  
 439    if ($mode=='wiki') { msg("Renderer for $mode not valid",-1); return null; } //FIXME!! remove this line when inc/parser/wiki.php works.
 440  
 441    // Create the renderer
 442    if(!@file_exists(DOKU_INC."inc/parser/$mode.php")){
 443      msg("No renderer for $mode found",-1);
 444      return null;
 445    }
 446  
 447    require_once DOKU_INC."inc/parser/$mode.php";
 448    $rclass = "Doku_Renderer_$mode";
 449    if ( !class_exists($rclass) ) {
 450      trigger_error("Unable to resolve render class $rclass",E_USER_WARNING);
 451      msg("Renderer for $mode not valid",-1);
 452      return null;
 453    }
 454    $Renderer = & new $rclass(); #FIXME any way to check for class existance?
 455  
 456    $Renderer->smileys = getSmileys();
 457    $Renderer->entities = getEntities();
 458    $Renderer->acronyms = getAcronyms();
 459    $Renderer->interwiki = getInterwiki();
 460    #$Renderer->badwords = getBadWords();
 461  
 462    // Loop through the instructions
 463    foreach ( $instructions as $instruction ) {
 464        // Execute the callback against the Renderer
 465        call_user_func_array(array(&$Renderer, $instruction[0]),$instruction[1]);
 466    }
 467  
 468    //set info array
 469    $info = $Renderer->info;
 470  
 471    // Post process and return the output
 472    $data = array($mode,& $Renderer->doc);
 473    trigger_event('RENDERER_CONTENT_POSTPROCESS',$data);
 474    return $Renderer->doc;
 475  }
 476  
 477  /**
 478   * Gets the first heading from a file
 479   *
 480   * @author Andreas Gohr <andi@splitbrain.org>
 481   */
 482  function p_get_first_heading($id){
 483    global $conf;
 484    return $conf['useheading'] ? p_get_metadata($id,'title') : null;
 485  }
 486  
 487  /**
 488   * Wrapper for GeSHi Code Highlighter, provides caching of its output
 489   *
 490   * @author Christopher Smith <chris@jalakai.co.uk>
 491   */
 492  function p_xhtml_cached_geshi($code, $language) {
 493    $cache = getCacheName($language.$code,".code");
 494  
 495    if (@file_exists($cache) && !$_REQUEST['purge'] &&
 496       (filemtime($cache) > filemtime(DOKU_INC . 'inc/geshi.php'))) {
 497  
 498      $highlighted_code = io_readFile($cache, false);
 499      @touch($cache);
 500  
 501    } else {
 502  
 503      require_once (DOKU_INC . 'inc/geshi.php');
 504  
 505      $geshi = new GeSHi($code, strtolower($language), DOKU_INC . 'inc/geshi');
 506      $geshi->set_encoding('utf-8');
 507      $geshi->enable_classes();
 508      $geshi->set_header_type(GESHI_HEADER_PRE);
 509      $geshi->set_overall_class("code $language");
 510      $geshi->set_link_target($conf['target']['extern']);
 511  
 512      $highlighted_code = $geshi->parse_code();
 513  
 514      io_saveFile($cache,$highlighted_code);
 515    }
 516  
 517    return $highlighted_code;
 518  }
 519  
 520  //Setup VIM: ex: et ts=2 enc=utf-8 :


Généré le : Tue Apr 3 20:47:31 2007 par Balluche grâce à PHPXref 0.7