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