xref: /dokuwiki/inc/parserutils.php (revision c112d57805d6740c6e0a200fd5fd3f2717f86c69)
1*c112d578Sandi<?php
2*c112d578Sandi/**
3*c112d578Sandi * Utilities for collecting data from config files
4*c112d578Sandi *
5*c112d578Sandi * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6*c112d578Sandi * @author     Harry Fuecks <hfuecks@gmail.com>
7*c112d578Sandi * @author     Andreas Gohr <andi@splitbrain.org>
8*c112d578Sandi */
9*c112d578Sandi
10*c112d578Sandi  if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
11*c112d578Sandi
12*c112d578Sandi  require_once(DOKU_INC.'inc/confutils.php');
13*c112d578Sandi  require_once(DOKU_INC.'inc/pageutils.php');
14*c112d578Sandi
15*c112d578Sandi/**
16*c112d578Sandi * Returns the parsed Wikitext in XHTML for the given id and revision.
17*c112d578Sandi *
18*c112d578Sandi * If $excuse is true an explanation is returned if the file
19*c112d578Sandi * wasn't found
20*c112d578Sandi *
21*c112d578Sandi * @author Andreas Gohr <andi@splitbrain.org>
22*c112d578Sandi */
23*c112d578Sandifunction p_wiki_xhtml($id, $rev='', $excuse=true){
24*c112d578Sandi  $file = wikiFN($id,$rev);
25*c112d578Sandi  $ret  = '';
26*c112d578Sandi
27*c112d578Sandi  //ensure $id is in global $ID (needed for parsing)
28*c112d578Sandi  global $ID;
29*c112d578Sandi  $ID = $id;
30*c112d578Sandi
31*c112d578Sandi  if($rev){
32*c112d578Sandi    if(@file_exists($file)){
33*c112d578Sandi      $ret = p_render_xhtml(p_get_instructions($file)); //no caching on old revisions
34*c112d578Sandi    }elseif($excuse){
35*c112d578Sandi      $ret = p_locale_xhtml('norev');
36*c112d578Sandi    }
37*c112d578Sandi  }else{
38*c112d578Sandi    if(@file_exists($file)){
39*c112d578Sandi      $ret = p_cached_xhtml($file);
40*c112d578Sandi    }elseif($excuse){
41*c112d578Sandi      $ret = p_locale_xhtml('newpage');
42*c112d578Sandi    }
43*c112d578Sandi  }
44*c112d578Sandi
45*c112d578Sandi  return $ret;
46*c112d578Sandi}
47*c112d578Sandi
48*c112d578Sandi/**
49*c112d578Sandi * Returns the specified local text in parsed format
50*c112d578Sandi *
51*c112d578Sandi * @author Andreas Gohr <andi@splitbrain.org>
52*c112d578Sandi */
53*c112d578Sandifunction p_locale_xhtml($id){
54*c112d578Sandi  //fetch parsed locale
55*c112d578Sandi  $html = p_cached_xhtml(localeFN($id));
56*c112d578Sandi  return $html;
57*c112d578Sandi}
58*c112d578Sandi
59*c112d578Sandi/**
60*c112d578Sandi * Returns the given file parsed to XHTML
61*c112d578Sandi *
62*c112d578Sandi * Uses and creates a cachefile
63*c112d578Sandi *
64*c112d578Sandi * @author Andreas Gohr <andi@splitbrain.org>
65*c112d578Sandi */
66*c112d578Sandifunction p_cached_xhtml($file){
67*c112d578Sandi  global $conf;
68*c112d578Sandi  $cache  = $conf['datadir'].'/_cache/xhtml/';
69*c112d578Sandi  $cache .= md5($file.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT']);
70*c112d578Sandi
71*c112d578Sandi  // check if cache can be used
72*c112d578Sandi  $cachetime = @filemtime($cache); // 0 if not exists
73*c112d578Sandi
74*c112d578Sandi  if( @file_exists($file)                                             // does the source exist
75*c112d578Sandi      && $cachetime > @filemtime($file)                               // cache is fresh
76*c112d578Sandi      && ((time() - $cachetime) < $conf['cachetime'])                 // and is cachefile young enough
77*c112d578Sandi      && !isset($_REQUEST['purge'])                                   // no purge param was set
78*c112d578Sandi
79*c112d578Sandi      && ($cachetime > @filemtime(DOKU_INC.'conf/dokuwiki.php'))      // newer than the config file
80*c112d578Sandi      && ($cachetime > @filemtime(DOKU_INC.'conf/local.php'))         // newer than the local config file
81*c112d578Sandi      && ($cachetime > @filemtime(DOKU_INC.'inc/parser/xhtml.php'))   // newer than the renderer
82*c112d578Sandi      && ($cachetime > @filemtime(DOKU_INC.'inc/parser/parser.php'))  // newer than the parser
83*c112d578Sandi      && ($cachetime > @filemtime(DOKU_INC.'inc/parser/handler.php')))// newer than the handler
84*c112d578Sandi  {
85*c112d578Sandi    //well then use the cache
86*c112d578Sandi    $parsed = io_readfile($cache);
87*c112d578Sandi    $parsed .= "\n<!-- cachefile $cache used -->\n";
88*c112d578Sandi  }else{
89*c112d578Sandi    $parsed = p_render_xhtml(p_cached_instructions($file)); //try to use cached instructions
90*c112d578Sandi    io_saveFile($cache,$parsed); //save cachefile
91*c112d578Sandi    $parsed .= "\n<!-- no cachefile used, but created -->\n";
92*c112d578Sandi
93*c112d578Sandi    /* FIXME add nocache directive handling like this:
94*c112d578Sandi    if($parser['cache']){
95*c112d578Sandi      io_saveFile($cache,$parsed); //save cachefile
96*c112d578Sandi      $parsed .= "\n<!-- no cachefile used, but created -->\n";
97*c112d578Sandi    }else{
98*c112d578Sandi      @unlink($cache); //try to delete cachefile
99*c112d578Sandi      $parsed .= "\n<!-- no cachefile used, caching forbidden -->\n";
100*c112d578Sandi    }
101*c112d578Sandi    */
102*c112d578Sandi  }
103*c112d578Sandi
104*c112d578Sandi  return $parsed;
105*c112d578Sandi}
106*c112d578Sandi
107*c112d578Sandi/**
108*c112d578Sandi * Returns the render instructions for a file
109*c112d578Sandi *
110*c112d578Sandi * Uses and creates a serialized cache file
111*c112d578Sandi *
112*c112d578Sandi * @author Andreas Gohr <andi@splitbrain.org>
113*c112d578Sandi */
114*c112d578Sandifunction p_cached_instructions($file){
115*c112d578Sandi  global $conf;
116*c112d578Sandi  $cache  = $conf['datadir'].'/_cache/instructions/';
117*c112d578Sandi  $cache .= md5($file.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT']);
118*c112d578Sandi
119*c112d578Sandi  // check if cache can be used
120*c112d578Sandi  $cachetime = @filemtime($cache); // 0 if not exists
121*c112d578Sandi
122*c112d578Sandi  if( @file_exists($file)                                             // does the source exist
123*c112d578Sandi      && $cachetime > @filemtime($file)                               // cache is fresh
124*c112d578Sandi      && !isset($_REQUEST['purge'])                                   // no purge param was set
125*c112d578Sandi      && ($cachetime > @filemtime(DOKU_INC.'conf/dokuwiki.php'))      // newer than the config file
126*c112d578Sandi      && ($cachetime > @filemtime(DOKU_INC.'conf/local.php'))         // newer than the local config file
127*c112d578Sandi      && ($cachetime > @filemtime(DOKU_INC.'inc/parser/parser.php'))  // newer than the parser
128*c112d578Sandi      && ($cachetime > @filemtime(DOKU_INC.'inc/parser/handler.php')))// newer than the handler
129*c112d578Sandi  {
130*c112d578Sandi    //well then use the cache
131*c112d578Sandi    return unserialize(io_readfile($cache));
132*c112d578Sandi  }elseif(@file_exists($file)){
133*c112d578Sandi    // no cache - do some work
134*c112d578Sandi    $ins = p_get_instructions($file);
135*c112d578Sandi    io_savefile($cache,serialize($ins));
136*c112d578Sandi    return $ins;
137*c112d578Sandi  }
138*c112d578Sandi
139*c112d578Sandi  return NULL;
140*c112d578Sandi}
141*c112d578Sandi
142*c112d578Sandi/**
143*c112d578Sandi * turns a page into a list of instructions
144*c112d578Sandi *
145*c112d578Sandi * @author Harry Fuecks <hfuecks@gmail.com>
146*c112d578Sandi * @author Andreas Gohr <andi@splitbrain.org>
147*c112d578Sandi */
148*c112d578Sandifunction p_get_instructions($file){
149*c112d578Sandi  global $conf;
150*c112d578Sandi
151*c112d578Sandi  $text = io_readfile($file);
152*c112d578Sandi
153*c112d578Sandi  require_once DOKU_INC . 'inc/parser/parser.php';
154*c112d578Sandi
155*c112d578Sandi  // Create the parser
156*c112d578Sandi  $Parser = & new Doku_Parser();
157*c112d578Sandi
158*c112d578Sandi  // Add the Handler
159*c112d578Sandi  $Parser->Handler = & new Doku_Handler();
160*c112d578Sandi
161*c112d578Sandi  // Load all the modes
162*c112d578Sandi  $Parser->addMode('listblock',new Doku_Parser_Mode_ListBlock());
163*c112d578Sandi  $Parser->addMode('preformatted',new Doku_Parser_Mode_Preformatted());
164*c112d578Sandi  $Parser->addMode('notoc',new Doku_Parser_Mode_NoToc());
165*c112d578Sandi  $Parser->addMode('header',new Doku_Parser_Mode_Header());
166*c112d578Sandi  $Parser->addMode('table',new Doku_Parser_Mode_Table());
167*c112d578Sandi
168*c112d578Sandi  $formats = array (
169*c112d578Sandi      'strong', 'emphasis', 'underline', 'monospace',
170*c112d578Sandi      'subscript', 'superscript', 'deleted',
171*c112d578Sandi  );
172*c112d578Sandi  foreach ( $formats as $format ) {
173*c112d578Sandi      $Parser->addMode($format,new Doku_Parser_Mode_Formatting($format));
174*c112d578Sandi  }
175*c112d578Sandi
176*c112d578Sandi  $Parser->addMode('linebreak',new Doku_Parser_Mode_Linebreak());
177*c112d578Sandi  $Parser->addMode('footnote',new Doku_Parser_Mode_Footnote());
178*c112d578Sandi  $Parser->addMode('hr',new Doku_Parser_Mode_HR());
179*c112d578Sandi
180*c112d578Sandi  $Parser->addMode('unformatted',new Doku_Parser_Mode_Unformatted());
181*c112d578Sandi  $Parser->addMode('php',new Doku_Parser_Mode_PHP());
182*c112d578Sandi  $Parser->addMode('html',new Doku_Parser_Mode_HTML());
183*c112d578Sandi  $Parser->addMode('code',new Doku_Parser_Mode_Code());
184*c112d578Sandi  $Parser->addMode('file',new Doku_Parser_Mode_File());
185*c112d578Sandi  $Parser->addMode('quote',new Doku_Parser_Mode_Quote());
186*c112d578Sandi
187*c112d578Sandi  $Parser->addMode('smiley',new Doku_Parser_Mode_Smiley(array_keys(getSmileys())));
188*c112d578Sandi  $Parser->addMode('acronym',new Doku_Parser_Mode_Acronym(array_keys(getAcronyms())));
189*c112d578Sandi  #$Parser->addMode('wordblock',new Doku_Parser_Mode_Wordblock(getBadWords()));
190*c112d578Sandi  $Parser->addMode('entity',new Doku_Parser_Mode_Entity(array_keys(getEntities())));
191*c112d578Sandi
192*c112d578Sandi  $Parser->addMode('multiplyentity',new Doku_Parser_Mode_MultiplyEntity());
193*c112d578Sandi  $Parser->addMode('quotes',new Doku_Parser_Mode_Quotes());
194*c112d578Sandi
195*c112d578Sandi  if($conf['camelcase']){
196*c112d578Sandi    $Parser->addMode('camelcaselink',new Doku_Parser_Mode_CamelCaseLink());
197*c112d578Sandi  }
198*c112d578Sandi
199*c112d578Sandi  $Parser->addMode('internallink',new Doku_Parser_Mode_InternalLink());
200*c112d578Sandi  $Parser->addMode('rss',new Doku_Parser_Mode_RSS());
201*c112d578Sandi  $Parser->addMode('media',new Doku_Parser_Mode_Media());
202*c112d578Sandi  $Parser->addMode('externallink',new Doku_Parser_Mode_ExternalLink());
203*c112d578Sandi  $Parser->addMode('email',new Doku_Parser_Mode_Email());
204*c112d578Sandi  $Parser->addMode('windowssharelink',new Doku_Parser_Mode_WindowsShareLink());
205*c112d578Sandi  //$Parser->addMode('filelink',new Doku_Parser_Mode_FileLink()); //FIXME ???
206*c112d578Sandi  $Parser->addMode('eol',new Doku_Parser_Mode_Eol());
207*c112d578Sandi
208*c112d578Sandi  // Do the parsing
209*c112d578Sandi  return $Parser->parse($text);
210*c112d578Sandi}
211*c112d578Sandi
212*c112d578Sandi/**
213*c112d578Sandi * Renders a list of instruction to XHTML
214*c112d578Sandi *
215*c112d578Sandi * @author Harry Fuecks <hfuecks@gmail.com>
216*c112d578Sandi * @author Andreas Gohr <andi@splitbrain.org>
217*c112d578Sandi */
218*c112d578Sandifunction p_render_xhtml($instructions){
219*c112d578Sandi  if(is_null($instructions)) return '';
220*c112d578Sandi
221*c112d578Sandi  // Create the renderer
222*c112d578Sandi  require_once DOKU_INC . 'inc/parser/xhtml.php';
223*c112d578Sandi  $Renderer = & new Doku_Renderer_XHTML();
224*c112d578Sandi
225*c112d578Sandi  $Renderer->smileys = getSmileys();
226*c112d578Sandi  $Renderer->entities = getEntities();
227*c112d578Sandi  $Renderer->acronyms = getAcronyms();
228*c112d578Sandi  $Renderer->interwiki = getInterwiki();
229*c112d578Sandi  #$Renderer->badwords = getBadWords();
230*c112d578Sandi
231*c112d578Sandi  // Loop through the instructions
232*c112d578Sandi  foreach ( $instructions as $instruction ) {
233*c112d578Sandi      // Execute the callback against the Renderer
234*c112d578Sandi      call_user_func_array(array(&$Renderer, $instruction[0]),$instruction[1]);
235*c112d578Sandi  }
236*c112d578Sandi  // Return the output
237*c112d578Sandi  return $Renderer->doc;
238*c112d578Sandi}
239*c112d578Sandi
240*c112d578Sandi//Setup VIM: ex: et ts=2 enc=utf-8 :
241