<?php if (!defined('PmWiki')) exit();
/*  Copyright 2004 Patrick R. Michaud (pmichaud@pobox.com)
    This file is usemod.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 file attempts to ease conversions of UseMod pages 
    to PmWiki 2.  This is definitely a preliminary implementation and
    still probably needs some work.

    The major components are UseModPageDir($path, $group) and 
    ConvertUseModPageDir($path, $group).  UseModPageDir tells PmWiki
    to make use of an existing UseMod page/ directory, converting to
    PmWiki markup as the page is read.  The pages appear under the
    WikiGroup given by $group (default is 'UseMod').  Any edits or
    changes to these pages will be saved in the PmWiki 2 installation's
    wiki.d/ directory.

    The intent is that a wiki administrator can install, configure, and
    test a PmWiki 2 installation on an existing set of UseMod pages
    without losing or modifying the UseMod page files.

    ConvertUseModPageDir($path, $group) is a function that allows 
    batch conversion of pages from a UseMod directory into the
    PmWiki directory all at once.

    Details on this are being maintained at the Cookbook
    page at http://www.pmwiki.org/wiki/Cookbook/ConvertUseMod .
*/

SDVA($UseModConversions, array(
  # <nowiki>
  "!<nowiki>(.*?)</nowiki>!s" => '[=$1=]',

  # <h1>, <h2>, <h3> headers
  "!<h1>(.*?)</h1>!" =>  "\n! $1",
  "!<h2>(.*?)</h2>!" =>  "\n!! $1",
  "!<h3>(.*?)</h3>!" =>  "\n!!! $1",

  # =, ==, === headers
  "/^(=+)(.*?)\\1/me" => "str_repeat('!',strlen('$1')).PSS('$2')",

  # <b>, <i>
  "!<b>(.*?)</b>!" => "'''$1'''",
  "!<i>(.*?)</i>!" => "''$1''",

  # <br>
  "!<br>!" => "\\\\\n",

  # indented text:
  "!^(:+)!em" => "str_repeat('-', strlen('$1')).'>'",

  # Term + definition:
  "!^(;+)(.*?):!em" => "str_repeat(':', strlen('$1')).PSS('$2').':'",

  # [bracketed links]
  "/\\[(http:[^$UrlExcludeChars\\s]+)\\]/e" => "Keep(PSS('[[$1 |#]]'))", 
  "/\\[(http:.*?)\\s(.*?)\\]/" => '[[$1 | $2 ]]',

  # <font>
  "!<font (.*?)>(.*?)</font>!" => '%$1%$2%%',

  # <pre>
  "!<pre>(.*?)</pre>!s" => " [=$1=]",

  # /SubPage
  "!\\B/($WikiWordPattern)!" => "[[{\$Name}-$1 |$0]]",
));

class UseModStore extends PageStore {
  var $umgroup;
  function setgroup($group) { $this->umgroup = $group; }
  function pfile($pagename) {
    global $FmtV;
    $ninit = substr(FmtPageName('$Name', $pagename), 0, 1);
    $pagefile = FmtPageName($this->dirfmt."/$ninit/\$Name.db", $pagename);
    $pagefile = preg_replace('!-([^-/]+)$!', '/$1', $pagefile);
    return $pagefile;
  }
  function read($pagename) {
    global $UseModConversions, $KeepToken;
    $group = FmtPageName('$Group', $pagename);
    if ($group != $this->umgroup) return false;
    $pagefile = $this->pfile($pagename);
    if ($pagefile && $fp=@fopen($pagefile,"r")) {
      while (!feof($fp)) { $text .= fgets($fp, 4096); }
      fclose($fp);
      preg_match('/\\xb3[23]text\\xb33(.*?)\\xb33/s',$text,$match);
      $text = preg_replace('!<nowiki>(.*?)</nowiki>!se',
                "Keep(PSS('$1'))", $match[1]);
      $text = preg_replace(array_keys($UseModConversions),
                array_values($UseModConversions), $text);
      $page['text'] = preg_replace("/$KeepToken(\\d.*?)$KeepToken/e",
                "\$GLOBALS['KPV']['$1']", $text);
    }
    return @$page;
  }
  function exists($pagename) {
    $group = FmtPageName('$Group', $pagename);
    if ($group != $this->umgroup) return false;
    $pagefile = $this->pfile($pagename);
    return file_exists($pagefile);
  }
  function ls($pats=NULL) {
    $dir = FmtPageName($this->dirfmt,'');
    $dirlist = array(preg_replace('!/?[^/]*\$.*$!', '', $dir));
    $out = array(); $base = array();
    while (count($dirlist)>0) {
      $dir = array_shift($dirlist);
      $pref = in_array(basename($dir), $base) ? '.'.basename($dir).'-' : '.';
      $dfp = opendir($dir); if (!$dfp) continue;
      while ( ($pagefile = readdir($dfp)) !== false) {
        if ($pagefile{0} == '.') continue;
        if (is_dir("$dir/$pagefile")) 
          { array_push($dirlist, "$dir/$pagefile"); continue; }
        if (@$seen[$pagefile]++) continue;
        if (substr($pagefile, -3) != '.db') continue;
        $pn = substr($pagefile, 0, strlen($pagefile)-3);
        $base[] = $pn;
        $out[] = 
          $this->umgroup . $pref . substr($pagefile, 0, strlen($pagefile)-3);
      }
    }
    return $out;
  }
}

function UseModPageDir($path, $group='UseMod') {
  global $WikiLibDirs;
  if (!is_dir($path)) {
    Abort("?$path is not an accessible directory");
    exit();
  }
  $UseModDir = new UseModStore($path);
  $UseModDir->setgroup($group);
  array_splice($WikiLibDirs, 1, 0, array($UseModDir));
}


function ConvertUseModPageDir($path, $group='UseMod') {
  if (!is_dir($path)) {
    Abort("?$path is not an accessible directory");
    exit();
  }
  $UseModDir = new UseModStore($path);
  $UseModDir->setgroup($group);
  $oldlist = $UseModDir->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 UseMod pages to PmWiki</title>
    </head>
    <body>
    <h2>Convert and Copy UseMod pages into PmWiki v2</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 get rid of the 
       <tt>include_once('cookbook/usemod.php');</tt> and
       <tt>ConvertUseModPageDir()</tt> lines that are in your 
       local/config.php file.</p>";
    $copy = array_unique($copy);
    foreach($copy as $p) { 
      echo "<li>Converting $p</li>\n"; 
      $page = $UseModDir->read($p);
      WritePage($p,$page);
    }
    echo "<p>Converted ", count($copy), " pages.</p>\n";
  } else {
    echo "
      <p>This function will migrate pages from a UseMod page directory ($path)
      into your 2.x wiki.d/ directory, converting markups as it proceeds. 
      Note that the files in your UseMod 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 = $UseModDir->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 UseMod to v2 (don't overwrite existing 
    v2 pages)</h3>";

  if ($difflist) {
    echo "
      <p>The following $dcount pages exist only in the UseMod 
      page/ 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 UseMod page/ directory that 
      are not already in your version 2 directory.</p>";
  }
  
  echo "<h3>Migrate pages from UseMod to v2 (overwrite existing v2 pages)</h3>
    <p>The following $bcount pages exist in <em>both</em> the UseMod and
    PmWiki wiki.d/ directories.  If you use one of the buttons below,
    then your converted version 1 pages will <em>overwrite</em> the existing 
    version 2 pages, and you will lose any edits that you might have made
    in the version 2 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();
}

    
?>