PageRenderTime 5ms CodeModel.GetById 644ms app.highlight 124ms RepoModel.GetById 168ms app.codeStats 0ms

/text.php

https://bitbucket.org/theprawn/minki
PHP | 692 lines | 646 code | 10 blank | 36 comment | 105 complexity | 51170031c723af15772d56f7e9e9f3e9 MD5 | raw file
  1<?php
  2# This is the text parser.
  3
  4/*function $text {
  5  if ( $mode == "_" ) $text = str_replace("_"," ",$text);
  6  else $text = str_replace(" ","_",$text);
  7  return $text;
  8}*/
  9
 10function listItems($list,$del) {
 11  $list = preg_replace('#^'.$del.' (.+?)$#im','<li>$1</li>',$list);
 12  //$list = preg_replace('#\\\\"(.+?)\\\\"#im','"$1"',$list);
 13  return $list;
 14}
 15
 16function parseText($text) {
 17  global $opts,$lang;
 18  $data = preg_split("#$#im",$text);
 19  if ( isset($_GET['text']) || ( isset($_GET['export']) && $_GET['export'] == 'text' ) ) {
 20    $omode = 'text';
 21  } else {
 22    $omode = '';
 23  }
 24  $filters = array(
 25  # List items
 26  # Headers
 27  'chea' => array('#^h([1-7])\.([a-z0-9]+)?:([^:]*):([^:]*): *(.+)#im','<h$1 style="color:$3;background:$4;" id="$2">$5</h$1>','$5'."\n".str_pad($opts['hhSt'],$opts['hhSz'],$opts['hhSt'],STR_PAD_LEFT) ),
 28  'hea' => array('#^h([1-7])\.([a-z0-9]+)? *(.+)#im','<h$1 id="$2">$3</h$1>','$3'."\n".str_pad($opts['hhSt'],$opts['hhSz'],$opts['hhSt'],STR_PAD_LEFT)."\n" ),
 29  # href
 30  array('#(?![\\w\/\\\\])"([^"]+)":([^ <>|\\s]+(?:[a-z0-9?&/]))(?!\\w)#im','<a href="$2">$1</a>','$1'),
 31  # target
 32  array('#(?![\\w\/\\\\])\\^([^^:]+):([^^]+)\\^#im','<a href="#$1">$2</a>','$2'),
 33  # TagLink
 34  array('#(?<![\w/\\\\])\{, *([^\\r\\n\\t}:]+) *}#ime','\'<a href="./?tag=\'.\'$1\'.\'" class="wikiPage">$1</a>\'','\'$1\''),
 35  # WikiPage
 36  //<a href="./?page=$1" class="wikiPage">$1</a>
 37  array('#(?<![\w/\\\\])\{ *([^\\r\\n\\t}:]+?) *}#ime','\'<a href="./?page=\'.\'$1\'.\'" class="wikiPage">$1</a>\'','\'$1\''),
 38  array('#(?<![\w/\\\\])\{ *([^\\r\\n\\t}:]+[^ }]) *}#ime','\'<a href="./?page=\'.\'$1\'.\'" class="wikiPage">$1</a>\'','\'$1\''),
 39  array('#(?<![\w/\\\\])\{ *([^\\r\\n\\t}:]+[^ }]):(text|html) *}#ime','\'<a href="./?export=$2&amp;page=\'.\'$1\'.\'" class="wikiPage">$1</a>\'','\'$1\''),
 40  array('#(?<![\w/\\\\])\{ *([^\\r\\n\\t}:]+[^ }])\#([\\w]+)(?::(text|html))? *}#ime','\'<a href="./?page=\'.\'$1\'.\'&amp;export=$3#$2" class="wikiPage">$1</a>\'','\'$1\''),
 41  # Italics
 42  array('#(?<![\\w/\\\\])/([^/<>]+)/(?![\\w/>])#im','<span style="font-style:italic;">$1</span>','$1'),
 43  # Underline
 44  array('#(?<![\\w\\\\])_([^_]+)_(?![\\w])#im','<span style="text-decoration:underline;">$1</span>','$1'),
 45  # Bold
 46  array('#(?<![\\w\\\\])\\*(?! )([^*]+)\\*(?![\\w])#im','<strong>$1</strong>','$1'),
 47  # Del
 48  array('#(?<![\\w\\\\-])-((?!-).+?)-(?![\\w-])#im','<del>$1</del>','$1'),
 49  # Colors
 50  array('#(?<![\\w\\\\])%:([^:]*):([^:]*):([^%]+?)%#im','<span style="color:$1; background:$2;">$3</span>','$3'),
 51  # Search Link
 52  array('#(?<![\\w\\\\])\{([^\\r\\n\\t}]+)(?:\#|&gt;|>) *([^\\r\\n\\t}]+) *: *([a-z0-9]+) (.*?) *}#im','<a href="./?search=$2&q=$3 $4">$1</a>','$3'),
 53  array('#(?<![\\w\\\\])\{(?:\#|&gt;|>) *([^\\r\\n\\t}]+) *: *([a-z0-9]+) (.*?) *}#im','<a href="./?search=$1&q=$2 $3">$3</a>','$3'),
 54  # Image
 55  array('#!l:([^\\s\\\\!]+)!?([^!]*)!#im','<img src="$1" align="left" alt="$2" />','[$2]'),
 56  array('#!r:([^\\s\\\\!]+)!?([^!]*)!#im','<img src="$1" align="right" alt="$2" />','[$2]'),
 57  array('#!([^\s\\\\!]+)\\!?([^!]*)!#im','<img src="$1" alt="$2" />','[$2]'),
 58  # Rogue Hyperlink
 59  array('#(?<![\\w\\\\:!"])(http|ftp|gopher|irc|https)://[^" <>\\s]+#im','<a href="$0">$0</a>','$0'),
 60  # Horizontal rule
 61  array('#^---([0-9a-z]+)?$#im',"<hr id=".'"$1"'." />",str_pad($opts['hrSt'],$opts['hrSz'],$opts['hrSt'],STR_PAD_LEFT)."\n" ),
 62  # Search Box
 63  array('#(?<![\\w\\\\])\#searchBox (.*?)\##im','<form method="get" action="./"><input type="hidden" name="search" value="$1" /><input type="text" name="q" /><input type="submit" value="'.$lang['searBtn'].'" /> <a href="./?search=$1">'.$lang['searHlL'].'</a></form>',''),
 64  # Block quote
 65  'blk' => array('#^: ([^\\r\\n]+)$#im','<blockquote>$1</blockquote>','     "$1"',0),
 66  # Colored Paragraphs
 67  'cpar' => array('#^:([^:]*):([^:]*):(.+?)$#im','<div style="color:$1;background:$2;">$3</div>','$3',0),
 68  # Breaks
 69  'brk' => array('#^(?!===|<blockquote|<h[0-7r]|</?pre|</?li|</?ul|</?ol|<table|<tr|<td)([\\s]+)$#im','<br />','$1',0),
 70  # Paragraphs
 71  'par' => array('#^(?!===|<blockquote|<h[0-7r]|</?pre|</?li|</?ul|</?ol|<table|<tr|<td|<br)(.+?)$#im','<div>$1</div>','$1','$1',0),
 72  );
 73
 74  # Filters to NOT process in pre-plus mode
 75  $preplusNo = array('brk','cpar','par','blk','hea','chea');
 76  if ( $omode === 'text' ) {
 77    foreach ( $filters as $num => $text ) {
 78      $filters[$num][1] = $text[2];
 79    }
 80  }
 81  $mode = '';   // table/list mode indicator
 82  $level = 0;   // current level in list mode
 83  $dlevel = 0;  // delimeter level
 84  $lcnt = 1;    // counter for numbered lists in text mode
 85  $datNum = 0;
 86  $relNum = 0;
 87  foreach ( $data as $textNum => $text ) {
 88    # Get User Filters
 89    if ( is_file("pages/$opts[usersyntax].php") ) {
 90      $userSyntaxClass = new configParse;
 91      $userSyntax = $userSyntaxClass->parseFile(getPage("pages/$opts[usersyntax].php"));
 92      if ( is_array($userSyntax) ) {
 93        foreach($userSyntax as $find => $repl) {
 94          if ( preg_match('#(.*?) (%[0-9]+)#im',$repl,$reRepl) ) {
 95            $repl = $reRepl[1];
 96            $trepl = $reRepl[2];
 97          }
 98          if ( isset($_GET['export']) && $_GET['export'] == 'text' ) {
 99            if ( isset($trepl) ) {
100              $repl = $trepl;
101            } else {
102              $repl = '%1';
103            }
104          }
105          preg_match_all('#%[0-9]+#im',$find,$vars);
106          # Escape all regex special chars
107          $find = preg_replace('#([][()+?*^$\\{}\#\\\\|.])#im','\\\\$1',$find);
108          $Rxfind = '#(?<![\\w\\\\])';
109          $Rxfind .= preg_replace('#%[0-9]+#im','(.*?)',$find);
110          $Rxfind .= '(?![\\w])#im';
111          $Rxrepl = preg_replace('#%([0-9]+)#im','\$$1',$repl);
112          $text = preg_replace($Rxfind,$Rxrepl,$text);
113          //([^*]+)
114        }
115      }
116    }
117
118    # Preformatted
119    if ( preg_match('#^===\\+?(:[^:]*:[^:]*:)?$#im',$text) && ( $mode != 'pre' && $mode != 'preplus') ) {
120      $text = trim($text);
121      if ( $tabmode == 'tab' ) {
122        $output[count($output)-1] .= "\n</table>\n";
123        $tabmode = '';
124      }
125      if ( preg_match('#^===\\+#im',$text) ) {
126        $mode = 'preplus';
127      } else {
128        $mode = 'pre';
129      }
130      if ( $omode === 'text' ) {
131        $text = preg_replace('#^===\\+?.*?$#im','',$text);
132      } else {
133        $text = preg_replace('#^===\\+?$#im','<pre>',$text);
134        $text = preg_replace('#^===\\+?:([^:]*):([^:]*):$#im','<pre style="color:$1;background:$2;">',$text);
135      }
136    } elseif ( preg_match('#^===\\+?$#im',$text) && ( $mode == 'pre' || $mode == 'preplus' ) ) {
137      $mode = '';
138      if ( $omode !== 'text' ) {
139        $text = preg_replace('#^===\\+?$#im','</pre>',$text);
140      } else {
141        $text = preg_replace('#^===\\+?$#im','',$text);
142      }
143    }
144
145    if ( $omode === 'text' && $mode != 'pre' ) {
146      foreach ( $filters as $num => $filter) {
147        if ( ( $num != 'pre' && $num != 'cpre') ) {
148          $text = preg_replace($filter[0],$filter[1],$text);
149        }
150      }
151    }
152
153    if ( !preg_match('#^;.*#im',$text) ) {
154      if ( preg_match('#^===\\+?(:[^:]*:[^:]*:)?$#im',$text) && ( $mode != 'pre' && $mode != 'preplus') ) {
155        if ( preg_match('#===\\+#im',$text) ) {
156          $mode = 'preplus';
157        } else {
158          $mode = 'pre';
159        }
160        if ( $omode === 'text' ) {
161          $text = preg_replace('#^===\\+?.*?$#im','',$text);
162        } else {
163          $text = preg_replace('#^===\\+?$#im','<pre>',$text);
164          $text = preg_replace('#^===\\+?:([^:]*):([^:]*):$#im','<pre style="color:$1;background:$2;">',$text);
165        }
166      } elseif ( preg_match('#^===\\+?$#im',$text) && ( $mode == 'pre' || $mode == 'preplus' ) ) {
167        $mode = '';
168        if ( $omode !== 'text' ) {
169          $text = preg_replace('#^===\\+?$#im','</pre>',$text);
170        } else {
171          $text = preg_replace('#^===\\+?$#im','',$text);
172        }
173      }
174
175      if ( $mode != 'pre' ) {
176        if ( preg_match('#^(\\*{1,}|\#{1,}) (.+?)$#im',$text,$nesting) ) {
177          if ( preg_match('#^\\*#im',$text) ){
178            $deli = 'ul';
179          } elseif ( preg_match('#^\##im',$text) ) {
180            $deli = 'ol';
181          }
182          $text = preg_replace('#^[*|\#]+ #im','',$text);
183          $iLev = strlen($nesting[1]);
184          if ( $level < $iLev ) {
185            $listPrefix = '';
186            for ( $n=$iLev-$level;$n>0;$n-- ) {
187              $dlevel++;
188              $delis[$dlevel] = $deli;
189              $listPrefix .= "<$delis[$dlevel]>";
190            }
191            $level = $iLev;
192            if ( $omode !== 'text' ) {
193              $text = $listPrefix."<li>".trim($text)."</li>";
194            }  else {
195              $line = '* '.trim($text);
196              $text = "\n".str_pad($line,strlen($line)+$level*2,' ',STR_PAD_LEFT);
197            }
198          } elseif ( $level > $iLev ) {
199            $listSuffix = '';
200            for ( $n=$level-$iLev;$n>0;$n-- ) {
201              $listSuffix .= "</$delis[$dlevel]>";
202              unset($delis[$dlevel]);
203              $dlevel--;
204            }
205            if ( $omode !== 'text' ) {
206              $text = "$listSuffix<li>".trim($text)."</li>";
207            } else {
208              $line = '* '.trim($text);
209              $text = "\n".str_pad($line,strlen($line)+$dlevel*2,' ',STR_PAD_LEFT);
210            }
211            $level = $iLev;
212          } else {
213            if ( $omode !== 'text' ) {
214              $text = "<li>".trim($text)."</li>";
215            } else {
216              $line = '* '.trim($text);
217              $text = "\n".str_pad($line,strlen($line)+$level*2,' ',STR_PAD_LEFT);
218            }
219          }
220        } elseif ( $level > 0 ) {
221          $listSuffix = '';
222          while($level > 0) {
223            if ( $omode !== 'text' ) {
224              $listSuffix .= "</".$delis[$dlevel].">";
225            }
226            $dlevel--;
227            $level--;
228          }
229          $output[count($output)-1] .= "\n$listSuffix";
230        }
231      }
232      # Table Parsing
233      $realNum = '';
234      if ( !isset($tabmode) ) $tabmode = '';
235      if ( $mode != 'pre' ) {
236        if ( preg_match('#^\\|(.+)\\|$#im',$text) && $mode != 'pre' && $omode !== 'text' ) {
237          $tableInsert = '';
238          if ( $tabmode != 'tab' ) {
239            if ( preg_match('#^\\|:([a-z0-9\#]*):([a-z0-9\#]*):(?:([a-z0-9\#]*):)?\\|$#im',$text,$tableFormat) || preg_match('#^\\|:([a-z0-9\#]*):([a-z0-9\#]*):(?:([a-z0-9\#]*))?:(?:([a-z0-9\#]*):)?\\|$#im',$text,$tableFormat) ) {
240              if ( strlen($tableFormat[3]) <1 ) $tableFormat[3] = 'none';
241              $tableInsert = "<table cellpadding=\"2\" cellspacing=\"0\" style=\"border: solid 1px $tableFormat[3]; color:$tableFormat[1];background:$tableFormat[2];\">";
242              if ( isset($tableFormat[4]) ) {
243                $tdstyle = " border: solid 1px $tableFormat[4];";
244              }
245              $text = '';
246            } else {
247              $tableInsert = "<table cellpadding=\"2\" cellspacing=\"0\">";
248            }
249            $tabmode = 'tab';
250            if ( !isset($tdstyle) ) $tdstyle = '';
251          }
252          //$text = preg_replace('#^\\|:([^:]*):([^:]*):(.+?)\\
253          $text = preg_replace('#^\\|:([a-z0-9\#]*):([a-z0-9\#]*):([a-z0-9\#]*):(.+?)\\|$#im','<tr><td style="color:$1;background:$2;border:solid 1px $3;'.$tdstyle.'">$4</td></tr>',$text);
254          $text = preg_replace('#^\\|:([a-z0-9\#]*):([a-z0-9\#]*):(.+?)\\|$#im','<tr><td style="color:$1;background:$2;'.$tdstyle.'">$3</td></tr>',$text);
255          $text = preg_replace('#^\\|(.+?)\\|$#im','<tr><td style="'.$tdstyle.'">$1</td></tr>',$text);
256          $text = preg_replace('#\\|:([^:\\|]*):([^:\\|]*):([^:\\|]*):#im','</td><td style="color:$1;background:$2;border:solid 1px $3;'.$tdstyle.'">',$text);
257          $text = preg_replace('#\\|:([^:\\|]*):([^:\\|]*):#im','</td><td style="color:$1;background:$2;'.$tdstyle.'">',$text);
258          $text = preg_replace('#\\|#im','</td><td style="'.$tdstyle.'">',$text);
259          $text = $tableInsert.$text;
260        } elseif ( $tabmode == 'tab' ) {
261          $output[count($output)-1] .= "\n</table>\n";
262          $tabmode = '';
263        } elseif ( $omode === 'text' && preg_match('#^\\|(.+)\\|$#im',$text,$texTab) ) {
264          $datNum = $textNum;
265          $mode = 'txtab';
266          while ( preg_match('#^\\|(.+)\\|$#im',$data[$datNum],$texTab ) ) {
267            foreach($texTab as $row => $texRow) {
268              if ( preg_match('#^:([a-z0-9\#]*):([a-z0-9\#]*):(?:([a-z0-9\#]*):)?$#im',$texRow) ) {
269                break;
270              }
271              foreach ( $filters as $num => $filter) {
272                $texRow = preg_replace($filter[0],$filter[1],$texRow);
273              }
274              if ( $row > 0 ) {
275                $texRow = explode('|',preg_replace('#(:[^:]*:[^:]*:)?#im','',html_entity_decode($texRow)));
276                $tabData[] = $texRow;
277                foreach($texRow as $cell => $rowLen) {
278                  if ( !isset($celLen[$cell]) || strlen($rowLen) > $celLen[$cell] ) {
279                    $celLen[$cell] = strlen($rowLen);
280                  }
281                }
282              }
283              $data[$datNum] = preg_replace('#^\\|(.+)\\|$#im','$1',$data[$datNum]);
284            }
285            $datNum++;
286          }
287          $text = '';
288          foreach($tabData as $vals) {
289          $text.="\n";
290            foreach($vals as $num => $val) {
291              $text.=str_pad($val,$celLen[$num]+5,' ',STR_PAD_RIGHT);
292            }
293          }
294          $tabData = array();
295        } elseif ( $mode == 'txtab') {
296          unset($celLen);
297          $celLen = array();
298          $mode = '';
299        }
300      }
301      if ( $mode != 'pre' ) {
302        foreach ( $filters as $num => $filter) {
303          if ( $mode != 'preplus' || !in_array($num,$preplusNo) ) {
304            $text = preg_replace($filter[0],$filter[1],$text);
305          }
306        }
307        # Clear escapes
308        $text = preg_replace('#\\\\(?=[\#-*/_"{!%h]|h\\d)#im','',$text);
309      }
310      $output[] = $text;
311    }
312    if ( $realNum >= $datNum ) {
313      $realNum++;
314      $datNum = $realNum;
315    } else {
316      $realNum++;
317    }
318  }
319  return implode("",$output);
320}
321
322function getCompFiles($file) {
323  global $opts;
324  $files = array();
325  for ( $n=1;$n<=$opts['prevNum'];$n++ ) {
326    if ( is_file("pages/$file.las$n.php") ) {
327      $files[] = "las$n";
328    }
329  }
330  return $files;
331}
332
333function compFilesList($filenm) {
334  global $lang;
335  $output = '<div><h3>'.$lang['compLabl'].'</h3>';
336  global $opts;
337  $compFiles = getCompFiles($filenm);
338  $output .= "<ul>";
339  foreach ( $compFiles as $file ) {
340    $date = date($opts['date'],filemtime("pages/$filenm.$file.php"));
341    if ( isset($_GET['diff']) && $_GET['diff'] == $file ) {
342      $output .= "<li>$date</li>";
343    } else {
344      $output .= '<li><a href="./?page='."$filenm&amp;diff=$file\">$date</a></li>";
345    }
346  }
347  $output .= "</ul></div>";
348  return $output;
349}
350
351function compFiles($file1,$file2,$mode=0) {
352  function simpLines(&$text) {
353    $text = trim($text);
354  }
355  $array1 = explode("\n",getPage($file1));
356  $array2 = explode("\n",getPage($file2));
357  array_walk($array1,'simpLines');
358  array_walk($array2,'simpLines');
359  $same = array_intersect($array1,$array2);
360  $same2 = array_intersect($array2,$array1);
361
362  $removed = $array1;
363  if ( $mode === 1 ) return $removed;
364  foreach($same as $num => $val ) {
365    unset($removed[$num]);
366  }
367  $added = $array2;
368  if ( $mode === 2 ) return $added;
369  foreach($same2 as $num => $val) {
370    unset($added[$num]);
371  }
372  function compCol($value,$action) {
373    if ($action == 'add') $color = array('#000','#8f8');
374    elseif ($action == 'rem') $color = array('#000','#f88');
375    else $color = array('','');
376    $value = '<div style="color:'.$color[0].';background:'.$color[1].';">'.htmlspecialchars($value).'</div>';
377    return $value;
378  }
379  if ( $mode === 3 ) {
380    $output = "<p>";
381    foreach($added as $item) {
382      $output .= compCol($item,'add');
383    }
384    foreach($removed as $item) {
385      $output .= compCol($item,'rem');
386    }
387    return $output;
388  }
389  $same = array_intersect($array2,$same);
390  $added = array_intersect($array2,$added);
391  $counter = 0;
392  foreach ( $same as $num => $val ) {
393    array_splice($array2,$num,1,compCol($val,'sam'));
394  }
395  foreach ( $added as $num => $val ) {
396    array_splice($array2,$num,1,compCol($val,'add'));
397  }
398  foreach ( $removed as $num => $val ) {
399    array_splice($array2,$num+$counter,0,compCol($val,'rem'));
400    $counter++;
401  }
402  return(implode('',$array2));
403}
404
405function breaks($str,$res='u') {
406  if ( $res == 'u' ) {
407    $str = preg_replace('/(\\r\\n)|(\\r(?!\\n))/sim',"\n",$str);
408  } elseif ( $res == 'w' ) {
409    $str = preg_replace('/((?<!\\r)\\n)|(\\r(?!\\n))/sim',"\r\n",$str);
410  } elseif ( $res == 'm' ) {
411    $str = preg_replace('/(\\r\\n)|((?!\\r)\\n)/sim',"\r",$str);
412  }
413  return $str;
414}
415
416
417# Get time offset
418function timeOffset($time) {
419  global $opts;
420  $offset = $time - date('Z',time()) + ($opts['time']*60*60) + ( date('I',time()) * $opts['tdst'] * 60*60 );
421  return $offset;
422if ( isset($_GET['debug']) ) {
423  echo date('Z',time())."<br />".$opts['time']*60*60;
424}
425echo $opts['time'];
426
427}
428
429function getPage($file) {
430  global $sitepass;
431  ob_start();
432  include($file);
433  $data = ob_get_contents();
434  ob_end_clean();
435  if ( !isset($_GET['edit']) ) {
436    return preg_replace('#^\#pass *= *(.*?)$#im','',$data);
437  } else {
438    return $data;
439  }
440}
441
442function getFileSettings($file) {
443  global $sitepass;
444  ob_start();
445  if ( is_file($file) ) {
446    require ($file);
447  } else {
448    return;
449  }
450  $file = ob_get_contents();
451  ob_end_clean();
452  if ( preg_match('#^\#pass *= *(.*?)$#im',$file,$userPass) ) {
453    $user = crypt($userPass[1],substr($userPass[1],strlen($userPass[1])-2,2));
454  } else {
455    $user = '';
456  }
457  $data = array($priv,$pass,$user);
458  return $data;
459}
460
461function getTags($iTag='',$mode=0) {
462  $handle = opendir("pages/tags");
463  $tags = array();
464  while ( $file = readdir($handle) ) {
465    if ( strlen($file) > 4 ) {
466      require "pages/tags/$file";
467      foreach($pageTags as $tag) {
468        if ( strlen($tag) > 0 ) {
469          $justTags[] = $tag;
470          $tags[$tag][] = str_replace('.php','',$file);
471        }
472      }
473    }
474  }
475  $justTags = array_unique($justTags);
476  if ( strlen($iTag) > 0 ) {
477    $file = '';
478    foreach ( $tags[$iTag] as $thisTag ) {
479      $file .= "* { $thisTag }\n";
480    }
481    return $file;
482  } else {
483    foreach ( $justTags as $tag ) {
484      $file .= "{,$tag}, ";
485    }
486    return $file;
487  }
488}
489
490function getFileTags($name,$mode=1) {
491  global $lang;
492  # mode = 1 for formatted tags
493  # mode = 0 for raw list
494  if ( is_file("pages/tags/$name.php") ) {
495    require "pages/tags/$name.php";
496    if ( $mode == 0 ) {
497      array_walk($pageTags,strClean,"_");
498      return implode(', ',$pageTags);
499    } elseif ( $mode == 1 ) {
500      $output = '';
501      foreach ( $pageTags as $tag ) {
502        $tag = $tag;
503        $output[] = "<a href=\"./?tag=$tag\">$tag</a>";
504      }
505      return implode(', ',$output);
506    }
507  } else {
508    // return $lang['noTags'];
509    return;
510  }
511}
512
513function searchIndex() {
514  global $sitepass,$opts,$lang;
515  # Get master file list
516  $files = fileLister();
517  # Associate pages with permissions
518  # There will be two indexes -- one for private and one for public
519  foreach ( $files as $file => $data ) {
520    $settings = getFileSettings("pages/$data[0].php");
521    $indexData = pageIndex(getPage("pages/$data[0].php"));
522    if ( $settings[0] < 1 ) {
523      $publicIndex[] = $data[0].','.implode(" ",$indexData);
524    }
525    $privateIndex[] = $data[0].','.implode(" ",$indexData);
526  }
527  $handle = fopen("pages/pubindex.php","w");
528  fwrite($handle,'<?php $pass = 1; $priv = 1; if ( isset($sitepass) ) {?>'.implode("\n",$publicIndex).'<?php }?>');
529  fclose($handle);
530  $handle = fopen("pages/priindex.php","w");
531  fwrite($handle,'<?php $pass = 1; $priv = 1; if ( isset($sitepass) ) {?>'.implode("\n",$privateIndex).'<?php }?>');
532  fclose($handle);
533  unset($handle);
534  return $lang['searNdx'];
535}
536
537function pageIndex($content) {
538  global $opts,$lang;
539  $_GET['export'] = 'text';
540  $content = parseText($content);
541  unset($_GET['export']);
542  $indexData = array_unique(preg_split('#'.$opts['srWrdFlt'].'#im',$content));
543  foreach($indexData as $index => $data) {
544    if (strlen($data) < $opts['srWrdLen']) {
545      unset($indexData[$index]);
546    }
547  }
548  return $indexData;
549}
550
551function pageSearch($keywords,$mode) {
552  $keywords = preg_split('#[\\s]+#',$keywords);
553  if ( $mode == 'pri' ) $index = getPage("pages/priindex.php");
554  else $index = getPage("pages/pubindex.php");
555  preg_match_all('#^(.*?),(.*?)$#sim',$index,$index,PREG_SET_ORDER);
556  foreach($index as $val) {
557    if ( preg_match('#'.implode('|',$keywords).'#im',$val[2]) ) {
558      $matches[]=$val[1];
559    }
560  }
561  if ( !is_array($matches) ) {
562    return false;
563  } elseif ( count($matches) == 1 ) {
564    return "{ $matches[0] }";
565  } else {
566    return "\n* {".implode("}\n* {",$matches)."}";
567  }
568}
569
570class configParse {
571  var $file;
572  var $data;
573  function parseFile($file) {
574    $this->file = explode("\n",$file);
575    foreach ( $this->file as $option ) {
576      if ( !preg_match('#^;#im',$option) && strlen(trim($option)) > 3 ) {
577        if ( preg_match('#^((?!;)[^= ]+) *= *(.+)#im',$option,$option) ) {
578          $this->data[trim($option[1])] = trim(str_replace('\n',"\n",$option[2]));
579        }
580      }
581    }
582    return $this->data;
583  }
584}
585
586# Generate List of all files
587function filelister($sortMethod='name',$mode=0) {
588  global $opts,$lang;
589  $fileList = array();
590  $handle=opendir('pages');
591  $n=0;
592  while ( $fileName = readdir($handle) ) {
593    if ( !preg_match('#(\\.(las[0-9]+\\.php|pass|priv|lock))$#im',$fileName) && !preg_match('#^\\.+$#im',$fileName) && $fileName != 'recent.php' && $fileName != 'pubindex.php' && $fileName != 'priindex.php' && !is_dir("pages/$fileName") && $fileName != "$opts[usersyntax].php") {
594      if ( $mode == 0 ) {
595        $fileList[$n][] = str_replace('.php','',$fileName);
596        $fileList[$n][] = filemtime('pages/'.($fileName));
597      } else {
598        $fileList[] = str_replace('.php','',$fileName);
599      }
600      if ( strlen($sortMethod) < 3 ) {
601        $sortMethod = $opts['listSrt'];
602      }
603      $names[] = str_replace('.php','',$fileName);
604      if ( $mode == 0 ) {
605        $dates[] = $fileList[$n][1];
606      }
607      $n++;
608    }
609  }
610  if ( $sortMethod == 'name' ) {
611    array_multisort($names,SORT_ASC, $fileList);
612  } else {
613    array_multisort($dates,SORT_DESC, $fileList);
614  }
615  return $fileList;
616}
617
618# I tried to enforce all lower case file names
619# But it was impossible to support international
620# characters under that scheme.  I'm using this function
621# as a workaround to make page names case insensitive
622# It just runs a case-insensitive search for the file name
623# using the filelister as an index. Slowdown is negligible.
624function fileNameSearch($name) {
625  $files = filelister('name',1);
626  if ( preg_match('#:('.$name.'):#im',':'.implode(':',$files).':',$result) ) {
627    return($result[1]);
628  } else {
629    return false;
630  }
631}
632
633function minkiSearch($data,$pageName) {
634  global $lang;
635  $rdata = preg_split('#[\\r\\n]+#sim',$data);
636  foreach ( $rdata as $query ) {
637    if ( preg_match('#^([a-z0-9]+) (.*)#im',$query,$match) ) {
638      $queries[$match[1]] = $match[2];
639      $qOut[] = "|$match[1]|$match[2]|";
640    }
641  }
642  sort($qOut);
643  preg_match('#^([a-z0-9]+) (.*)#im',$_GET['q'],$query);
644  if ( isset($queries[$query[1]]) ) {
645    $search = str_replace('%s',urlencode($query[2]),$queries[$query[1]]);
646    header("location: $search");
647  } elseif ( !isset($_GET['edit']) ) {
648    $file = "##searchBox##\n\n";
649    $file .= "|*$lang[searCoK]*|*$lang[searCoE]*|\n".implode("\n",$qOut)."\n\n";
650    $file .= $lang['searHlp'];
651    return $file;
652  } else {
653    return $data;
654  }
655}
656
657# Generate RSS 2.0 Feed
658function makeRssFeed($page) {
659  global $opts;
660  global $fname,$opts,$lang;
661  //$now = date('D, d M o H:i:s e',timeOffset(time()));
662  $now = date('r',time());
663  $oldData = file_get_contents('index.xml');
664  preg_match_all('#<item>.*?</item>#sim',$oldData,$oldItems1);
665  $oldItems = $oldItems1[0];
666  if ( $opts['rssMode'] != 0 ) $opts['rssMode'] = 3;
667  $content = htmlentities(compFiles("pages/$fname.las1.php","pages/$fname.php",$opts['rssMode']));
668  if ( count($oldItems) >= $opts['rssnum']) {
669    $oldItems = array_slice($oldItems,0,$opts['rssnum']-1);
670  }
671  $items = "<item>\n<title>$fname</title>\n<link>$opts[url]?page=$fname</link>\n<description>$content</description>\n<comments>$opts[url]?page=$fname&amp;edit</comments><pubDate>$now</pubDate>\n</item>";
672  if ( count($oldItems) > 0 ) {
673    $items .= "\n".implode("\n",$oldItems);
674  }
675$output = <<<output
676<?xml version="1.0"?>
677<rss version="2.0">
678   <channel>
679      <title>$opts[title]</title>
680      <link>$opts[url]</link>
681      <description>$opts[desc]</description>
682      <lastBuildDate>$now</lastBuildDate>
683$items
684   </channel>
685</rss>
686output;
687$handle = fopen('index.xml','w');
688fwrite($handle,$output);
689fclose($handle);
690unset($handle);
691}
692?>