<?php if (!defined('PmWiki')) exit(); /* Copyright 2007 Patrick R. Michaud (pmichaud@pobox.com) This file is converttiki.php; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This script attempts to convert TikiWiki pages to PmWiki. It's still a preliminary implementation. The first step is to use TikiWiki's "export" function to get a tar image of all of the wiki pages, then extract that tar image into a directory. The resulting directory should contain one file for each page stored in TikiWiki. Then, in PmWiki, add the following lines to local/config.php: include_once('cookbook/converttiki.php'); UseTikiDir('tiki.d', 'Tiki'); Here, 'tiki.d' is the name of the directory containing the page files exported from TikiWiki, and 'Tiki' is the name of the PmWiki group to use for the pages. If all works well, then the TikiWiki pages should appear as though they are standard PmWiki pages. Any edits made to pages in the Tiki/ group will be saved in PmWiki's wiki.d/ directory (thus leaving the original TikiWiki exported files intact). This script also adds "?action=converttiki", which allows a wiki administrator to batch convert some or all of the TikiWiki pages into PmWiki format. */ $RecipeInfo['ConvertTikiWiki']['Version'] = '2007-03-30'; ## TikiWiki markup to PmWiki markup conversions SDVA($ConvertTiki, array( # {CODE(0,0)}...{CODE} --> [@...@] '/\\{CODE\\(0,0\\)\\}(.+?)\\{CODE\\}/s' => '[@$1@]', # ==underline== --> '+underline+' '/==(.+)==/' => "'+$1+'", # __bold__ --> '''bold''' '/__(.+)__/' => "'''$1'''", # ;term:definition --> :term:definition '/(;+)(.*?:)/e' => "str_replace(';', ':', '$1') . PSS('$2')", # -+monospace+- --> @@monospace@@ '/-\\+(.+?)\\+-/' => '@@$1@@', # ((pagename)) --> [[pagename]] '/\\(\\((.+?)\\)\\)/' => '[[$1]]', )); class PageStoreTiki extends PageStore { var $group; function PageStoreTiki($path, $group) { $this->dirfmt = $path; $this->group = $group; $this->iswrite = 0; $GLOBALS['PageExistsCache'] = array(); } function pagefile($pagename) { if (!preg_match("/^{$this->group}\\./", $pagename)) return ''; return FmtPageName($this->dirfmt, $pagename); } function read($pagename) { global $ConvertTiki; $pagefile = $this->pagefile($pagename); if ($pagefile && ($fp=@fopen($pagefile, "r"))) { ## get heading details into $attr $seenboundary = 0; $boundary='--xxx'; while (!feof($fp)) { $line = fgets($fp, 4096); while (substr($line, -1, 1) != "\n" && !feof($fp)) $line .= fgets($fp, 4096); $line = rtrim($line); if (preg_match('/^\\s+(\\w+)=(.*)$/', $line, $match)) { list($x, $k, $v) = $match; $v = preg_replace('/;$/', '', $v); $attr[$k] = preg_replace('/^"(.*)"$/', '$1', $v); if ($k == 'boundary') $boundary = "--{$attr[$k]}"; continue; } if ($line == $boundary) $seenboundary = 1; if ($line == '' && $seenboundary) break; } ## get page markup into $text $text = ''; while (!feof($fp)) { $line = fgets($fp, 4096); while (substr($line, -1, 1) != "\n" && !feof($fp)) $line .= fgets($fp, 4096); $line = rtrim($line); if ($line == $boundary) break; $text .= $line . "\n"; } fclose($fp); ## convert TikiWiki attributes to PmWiki attributes foreach(array('pagename'=>'name', 'author'=>'author', 'lastmodified'=>'time', 'version'=>'rev') as $t=>$p) if (isset($attr[$t])) $page[$p] = $attr[$t]; $page['text'] = preg_replace(array_keys($ConvertTiki), array_values($ConvertTiki), $text); } return @$page; } function ls($pats = NULL) { global $GroupPattern, $NamePattern; StopWatch("PageStoreTiki::ls begin {$this->dirfmt}"); $pats=(array)$pats; array_push($pats, "/^$GroupPattern\.$NamePattern$/"); $maxslash = substr_count($dir, '/'); $dir = preg_replace('!/*[^/]*\\$.*$!','',$this->dirfmt); $out = array(); $dfp = @opendir($dir); if ($dfp) { while ( ($pagefile = readdir($dfp)) !== false) { if ($pagefile{0} == '.') continue; $o[] = $this->group . ".$pagefile"; } closedir($dfp); StopWatch("PageStore::ls merge {$this->dirfmt}"); $out = array_merge($out, MatchPageNames($o, $pats)); } StopWatch("PageStore::ls end {$this->dirfmt}"); return $out; } } function UseTikiDir($path, $group = 'Tiki') { global $WikiLibDirs; if (!is_dir($path)) { Abort("?$path is not an accessible directory"); exit(); } array_splice($WikiLibDirs, 1, 0, array(new PageStoreTiki("$path/\$Name", $group))); } SDV($HandleActions['converttiki'], 'HandleConvertTiki'); SDV($HandleAuth['converttiki'], 'admin'); function HandleConvertTiki($pagename, $auth = 'admin') { $page = RetrieveAuthPage($pagename, $auth, true, READPAGE_CURRENT); if (!$page) Abort("?$auth permission required"); global $WikiDir, $WikiLibDirs; Lock(2); $from = 'TikiWiki'; $to = 'PmWiki'; $oldlist = array(); $olddirs = array(); $path = ''; foreach($WikiLibDirs as $d) { if (!is_a($d, 'PageStoreTiki')) continue; $olddirs[] = $d; $path .= ' ' . preg_replace('![^/]*\\$.*!', '', $d->dirfmt); $oldlist = array_merge($oldlist, $d->ls()); } $newlist = ListPages(); $bothlist = array_intersect($oldlist,$newlist); sort($bothlist); $difflist = array_diff($oldlist,$newlist); sort($difflist); $bcount = count($bothlist); $dcount = count($difflist); echo " <html> <head> <title>Convert $from pages to $to</title> </head> <body> <h2>Convert and Copy $from pages into $to</h2> "; $copy = array(); if (@$_POST['copydiff']) $copy = $difflist; if (@$_POST['copyboth']) $copy = array_merge($copy,$bothlist); if (@$_POST['copy']) $copy = array_merge($copy,$_POST['copy']); if (@$copy) { echo "<p>Okay, I'm now converting the pages you've requested. When this is finished, you can see if anything else needs to be converted, otherwise you can remove this conversion script from your local/config.php file.</p>"; $copy = array_unique($copy); foreach($copy as $p) { echo "<li>Converting $p</li>\n"; foreach($olddirs as $d) if ($d->exists($p)) { $page = $d->read($p); break; } WritePage($p,$page); } echo "<p>Converted ", count($copy), " pages.</p>\n"; } else { echo " <p>This function will migrate pages from a $from directory ($path) into your $to wiki.d/ directory, converting markups as it proceeds. Note that the files in your $from directory are not affected by this script, so if the conversion doesn't work out for any reason you still have your original pages lying around.</p> "; } /* now rebuild the lists */ $oldlist = array(); $olddirs = array(); foreach($WikiLibDirs as $d) { if (!is_a($d, 'PageStoreTiki')) continue; $olddirs[] = $d; $oldlist = array_merge($oldlist, $d->ls()); } $newlist = ListPages(); $bothlist = array_intersect($oldlist,$newlist); sort($bothlist); $difflist = array_diff($oldlist,$newlist); sort($difflist); $bcount = count($bothlist); $dcount = count($difflist); echo " <form method='post'> "; echo "<h3>Migrate pages from $from to $to (don't overwrite existing $to pages)</h3>"; if ($difflist) { echo " <p>The following $dcount pages exist only in the $from directory. </p> <dd><input type='submit' name='copydiff' value='Copy and convert all pages that do not already exist' /></dd> <p>or</p><dd><input type='submit' name='copyindv' value='Copy and convert pages checked in the list below' /><p></p></dd> "; foreach($difflist as $p) echo "<dd><input type='checkbox' name='copy[]' value='$p' /> $p</dd>\n"; } else { echo "<p>There aren't any pages in your $from directory that are not already in your $to directory.</p>"; } echo "<h3>Migrate pages from $from to $to (overwrite existing $to pages)</h3> <p>The following $bcount pages exist in <em>both</em> the $from and $to directories. If you use one of the buttons below, then your converted $from pages will <em>overwrite</em> the existing $to pages, and you will lose any edits that you might have made in the $to installation (it's possible that this is what you want).</p> <dd><input type='submit' name='copyboth' value='Convert and overwrite pages that do already exist' /></dd> <p>or</p><dd><input type='submit' name='copyindv' value='Convert and overwrite pages checked in the list below' /><p></p></dd> "; foreach($bothlist as $p) echo "<dd><input type='checkbox' name='copy[]' value='$p' /> $p</dd>\n"; echo "</form></body></html>\n"; exit(); }