anchor.diff:  ;;; for prepare old cliki pages
   
   (in-package #:cliki2.converter)
  -
  -(defun read-file (path)
  -  (alexandria:read-file-into-string path :external-format :latin1))
   
   (defun convert-article-revision (content)
     (flet ((fixup-tag (regex str fixup)
  
positive.code: 
    (open-store (merge-pathnames "store/" cliki2::*datadir*))
  
    (let ((old-articles (make-hash-table :test 'equalp))) ;; case insensitive
      (dolist (file (cl-fad:list-directory old-article-dir))
        (let ((file-name (cliki2::cut-whitespace
                          (hunchentoot:url-decode
                           (substitute #\% #\= (pathname-name file))
                           hunchentoot::+latin-1+))))
          (setf (gethash file-name old-articles)
                (merge 'list
                       (list file)
                       (gethash file-name old-articles)
                       #'<
                       :key (lambda (x)
                              (parse-integer (or (pathname-type x) "0")
  
negative.code:           do (setf content (fixup-tag regex content action)))
      content))
  
  (defstruct (edit (:type list)) date article-name author summary)
  
  (defun load-edits (old-article-dir)
    (with-open-file (s (merge-pathnames "admin/recent-changes.dat"
                                        old-article-dir)
                       :external-format :latin1)
      (loop for x = (read s nil) while x collect x)))
  
  (defun edits-for-article (article-name edits)
    (remove-if (lambda (edit)
                 (not (equal article-name (edit-article-name edit))))
               edits))
  
  (defun unknown-edit (date article-name)
    (list date article-name "no edit summary available" "import from CLiki"))
  
  (defun match-edits-to-files (article-name edits files)
    (let ((num-edits (length edits))
          (num-files (length files)))
      (cond ((> num-edits num-files)
             (subseq edits (- num-edits num-files)))
            ((= num-edits 0)
             (let ((timestamp-skew 0))
               (loop for file in files collecting
                    (unknown-edit (+ (incf timestamp-skew 60)
                                     (file-write-date file))
                                  article-name))))
            (t (let ((edit-date (edit-date (car edits))))
                 (append (reverse
                          (loop repeat (- num-files num-edits)
                             do (decf edit-date 60)
                             collect (unknown-edit edit-date article-name)))
                         edits))))))
  
  (defun delete-article? (revision content all-revisions)
    (and (eq revision (car (last all-revisions)))
         (search "*(delete this page)" content :test #'char-equal)))
  
  (defun make-revision (article revision-path authorship summary all-revisions)
    (let ((content (convert-article-revision
                    (alexandria:read-file-into-string
                     revision-path :external-format :latin1))))
      (or (when (delete-article? revision-path content all-revisions)
            (cliki2::latest-revision
             (cliki2::toggle-delete (bknr.datastore:store-object-id article)
                                    authorship)))
          (cliki2::add-revision article summary content authorship))))
  
  (defun import-revisions (account article edits revision-paths)
    (loop for path in revision-paths
          for edit in edits do
         (let* ((date (edit-date edit))
                (revision
                 (make-revision article
                                path
                                (list :author    account
                                      :author-ip "0.0.0.0"
                                      :date      date)
                                (format nil "~@[~A ~]~@[(~A)~]"
                                        (edit-summary edit) (edit-author edit))
                                revision-paths))
                (unix-date (local-time:timestamp-to-unix
                            (local-time:universal-to-timestamp date))))
           (sb-posix:utimes (cliki2::revision-path revision)
                            unix-date unix-date))))
  
  (defun decode-article-name (file-name)
    (cliki2::cut-whitespace
     (hunchentoot:url-decode
      (substitute #\% #\= file-name)
      hunchentoot::+latin-1+)))
  
  (defun load-old-articles (old-article-dir)
    "WARNING: This WILL blow away your old store."
  