;; -*- emacs-lisp -*-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; $Id: wiki.el,v 1.11 2006/03/06 12:07:06 ole Exp $
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;_* Wiki stuff
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;; (add-to-list 'load-path (expand-file-name "emacs-wiki" emacs-packages-dir))
(add-to-list 'load-path (expand-file-name "emacs-wiki-journal" emacs-packages-dir))

(require 'emacs-wiki)
(require 'emacs-wiki-journal)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;_+ Emacs Wiki Journal
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(setq emacs-wiki-journal-icons-subdirectory "img"
      emacs-wiki-journal-wiki "JournalPage"
      emacs-wiki-journal-directory "~/doc/sugarshark"
      emacs-wiki-journal-publishing-directory "~/html/sugarshark/www"
      emacs-wiki-journal-server-prefix ""
      )

(emacs-wiki-journal-update-wiki-project)

(defun switch-to-journal (&optional addentry)
  "Switch to the wiki journal"
  (interactive "P")
  (emacs-wiki-find-file emacs-wiki-journal-wiki nil emacs-wiki-journal-directory)
  (if addentry (emacs-wiki-journal-add-entry)))    

(define-key goto-keymap [?j] 'switch-to-journal)
  
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;_+ Emacs Wiki
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(setq emacs-wiki-interwiki-names 
   (quote
    ;; internal
    (("SugarShark" lambda (tag) (emacs-wiki-project-interwiki-link "sugarshark" (or tag "WelcomePage")))
        ("AnwynProject" lambda (tag) (emacs-wiki-project-interwiki-link "anwyn" (or tag "WelcomePage")))
        ("WikiPlanner" lambda (tag) (emacs-wiki-project-interwiki-link "WikiPlanner" tag))
        ;; external
        ("EmacsWiki" lambda (tag) (concat "http://www.emacswiki.org/cgi-bin/wiki?" (or tag "SiteMap")))
        ("GoogleSearch" lambda (tag) (concat "http://www.google.com/search?q=" (or tag "")))
        ("GoogleGroups" lambda (tag) (concat "http://www.google.com/groups?q=" (or tag "")))
        ("SourceForge" lambda (tag) (concat "http://www.sourceforge.net/projects/" (or tag "")))
        ("FreshMeat" lambda (tag) (concat "http://freshmeat.net/projects/" (or tag "")))
        ("GnuEmacs" . "http://www.gnu.org/software/emacs/emacs.html")
        ("WikiPedia" lambda (tab)  (concat "http://www.wikipedia.org/wiki/" (or tag "Main_Page")))
        ("MeatballWiki" lambda (tag) (concat "http://www.usemod.com/cgi-bin/mb.pl?" (or tag "MeatballWiki"))))))

(setq emacs-wiki-projects 
      '(
        ("sugarshark" .
         ((emacs-wiki-publishing-directory . "~/html/sugarshark/www/")
          (emacs-wiki-directories . ("~/doc/sugarshark"))
          (emacs-wiki-style-sheet 
           . "<link href=\"sugarshark.css\" type=\"text/css\" rel=\"stylesheet\">")
          ))
        ("hochzeit" .
         ((emacs-wiki-publishing-directory . "~/html/sugarshark/www/hochzeit")
          (emacs-wiki-directories . ("~/doc/hochzeit"))
          (emacs-wiki-style-sheet 
           . "<link href=\"hochzeit.css\" type=\"text/css\" rel=\"stylesheet\">")
          ))
        ("anwyn" .
        ((emacs-wiki-publishing-directory . "~/html/anwyn/wiki")
         (emacs-wiki-directories . ("~/projects/anwyn/doc/wiki"))))
        ("default" .
        ((emacs-wiki-publishing-directory . "~/html/wiki")
         (emacs-wiki-directories . ("~/doc/wiki"))))
        ))

(setq emacs-wiki-table-attributes "border=\"0\" cellpadding=\"0\" cellspacing=\"0\"")

(setq emacs-wiki-default-project "sugarshark")
(setq emacs-wiki-publishing-directory "~/html/sugarshark/www/")
(setq emacs-wiki-publishing-header "<lisp>(my-publishing-header)</lisp>")
(setq emacs-wiki-publishing-footer "<lisp>(my-publishing-footer)</lisp>")
(setq emacs-wiki-index-title-threshold 200)

(setq emacs-wiki-directories '("~/doc/sugarshark" "~/doc/wiki" "~/doc/hochzeit" "~/projects/anwyn/doc/wiki"))
(add-to-list 'auto-mode-alist '(".*/doc/sugarshark/[^/]*$" . emacs-wiki-mode))
(add-to-list 'auto-mode-alist '(".*/doc/hochzeit/[^/]*$" . emacs-wiki-mode))
(add-to-list 'auto-mode-alist '(".*/projects/anwyn/doc/wiki/.*$" . emacs-wiki-mode))

(setq emacs-wiki-file-ignore-regexp
      "\\(CVS/.*\\|include/.*\\|img/.*\\|\\..*\\|.*,v\\|.*~\\|\\.css\\)\\'")

;; strip following extensions for wiki names
(setq emacs-wiki-ignored-extensions-regexp 
      "\\.\\(bz2\\|gz\\|[Zz]\\|enc\\|cache\\|css\\)\\'")

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;_ + Publishing
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defvar oa-emacs-wiki-header "include/header")
(defvar oa-emacs-wiki-footer "include/footer")

;; save defaults
(defvar my-default-emacs-wiki-publishing-header
  emacs-wiki-publishing-header)

;; save defaults
(defvar my-default-emacs-wiki-publishing-footer
  emacs-wiki-publishing-footer)

(defun my-publishing-header ()
  "Insert a header"
  (let ((filename (expand-file-name oa-emacs-wiki-header)))
    (if (not (file-exists-p filename))
        my-default-emacs-wiki-publishing-header
      (insert-file-contents filename)
      "" )))

(defun my-publishing-footer ()
  "Insert a footer"
  (let ((filename  (expand-file-name oa-emacs-wiki-footer)))
    (if (not (file-exists-p filename))
        my-default-emacs-wiki-publishing-footer
      (insert-file filename)
      "" )))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;_ + Menu Generation
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(unless (fboundp 'join-string)
  (defun join-string(list &optional sep)
    "Join a list of strings into one string with an optional separator."
    (cond ((null list) "")
          ((null (cdr list)) (car list))
          (t (concat (car list) (or sep " ") (join-string (cdr list) sep)))))
)

(defun oa-emacs-wiki-make-menu-entry (category)
  "Make a HTML link for the category.
If the current  buffer name is a member of the category mark its link
with a class=\"selected\" attribute."
  (let* ((desc (car category))
         (linkto (cdr category))
         (buffername (if (buffer-file-name)
                         (file-name-nondirectory (buffer-file-name))
                       "WikiIndex"))
         (iscat (member buffername linkto)))
    (concat "<a " (and iscat "class=\"selected\" ")
            "href=\"" (emacs-wiki-published-name
                       (if iscat buffername (car linkto))) "\">" desc "</a> ")))

(defun oa-emacs-wiki-make-primary-menu ()
  "Make the primary HTML menu. This makes a link for every category,
delegating the hard work to `oa-emacs-wiki-make-menu-entry'."
  (join-string (mapcar 'oa-emacs-wiki-make-menu-entry
                       emacs-wiki-publish-categories)))

(defsubst oa-emacs-wiki-get-categegory-for-buffer (bname)
  "Get the category for the buffer name from the
definitions in `emacs-wiki-publish-categories'."
  (find-if (lambda (x) (member bname (cdr x))) emacs-wiki-publish-categories))

(defun oa-emacs-wiki-make-secondary-menu (&optional buffername)
  "Make the secondary HTML menu.
The optional parameter buffername defaults to the current buffer name.
This function returns a HTML list with links to all pages in 'buffername's category.
The link to buffername is marked with a class=\"selected\" attribute.
"
  (let* ((bname (or buffername (if (buffer-file-name)
                                   (file-name-nondirectory (buffer-file-name))
                                 "WikiIndex")))
         (category  (oa-emacs-wiki-get-categegory-for-buffer bname))
         (pages (cdr category)))
    (cond
     ;; no secondary menu on the the first category (HomePage)
     ((equal category (car  emacs-wiki-publish-categories)) "")
     ((and category pages)
      (let ((menu pages)
        (result "<ul>"))
        (while menu
          (let ((link (car menu))
                (desc (or (emacs-wiki-get-title-fast (car menu))
                          (emacs-wiki-prettify-title (car menu)))))
            (setq result (concat result "<li><a "
                                 (if (string= link bname) "class=\"selected\" ")
                                 "href=\"" (emacs-wiki-published-name link) "\">"
                                 desc "</a><li>")))
          (setq menu (cdr menu)))
        (concat result "</ul>")))
     (t ""))))

(defvar emacs-wiki-publish-categories
  (quote
   (("Home"      . ("WelcomePage"))
    ("Projects"  . ("ProjectPage"))
    ("Downloads" . ("DownloadPage"))
    ("CoolStuff" . ("StuffPage" "GamesPage" "DevelopmentPage" "LinksPage"))
    ("Journal"   . ("JournalPage" "CategoryGames" "CategoryEmacs" "CategoryJava" "CategoryTravel"))
    ("About"     . ("AboutPage" "ProfilePage" "PartnerPage"))))
  "Defines how the website is structured. Every entry describes a category.
The top level menu entry will be the car of each entry.
The secondary menu will be constructed from the list of pages in the cdr of the cons.")

(setq emacs-wiki-publishing-transforms  '(("WelcomePage" . "index")))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;_+ New Markup Tags
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(require 'emacs-wiki-boxes)

;;;_++ <example mode=....></example>
;;; Stolen from sachac, in turn 
;;; Stolen shamelessy from code by Satyaki Das <satyaki@theforce.stanford.edu>
;;; http://verify.stanford.edu/satyaki/emacs/EmacsWikiTricks.html
(require 'htmlize)

(defun ole-htmlfontify-insert-region (buffer begin end)
  "Insert into BUFFER the htmlified text between BEGIN and END."
  (save-excursion
    (let* ((hfy-optimisations (cons 'skip-refontification hfy-optimisations))
           (input-text (buffer-substring begin end))
           (temp-file (make-temp-file "html-input"))
           output-buffer)
      (with-temp-buffer
        (insert input-text)
        (setq buffer-file-name temp-file)
        (save-excursion (setq output-buffer (htmlfontify-buffer nil nil)))
        (set-buffer-modified-p nil))
      (unwind-protect
          (let (b e yanked-output)
            (set-buffer output-buffer)
            (goto-char (point-min))
            (search-forward "<pre>\n")
            (setq b (line-beginning-position))
            (goto-char (point-max))
            (search-backward "</pre>")
            (forward-line -1)
            (setq e (line-beginning-position))
            (setq yanked-output (buffer-substring-no-properties b e))
            (set-buffer buffer)
            (insert yanked-output))
        (set-buffer output-buffer)
        (set-buffer-modified-p nil)
        (delete-file temp-file)
        (kill-buffer output-buffer)))))

(defun ole-emacs-wiki-example-tag (beg end attrs highlight-p)
  "Mark up text as an example with optional font-locking."
  (if highlight-p
      (progn
        (remove-text-properties
         beg end '(face nil font-lock-multiline nil
                        invisible nil intangible nil display nil
                        mouse-face nil keymap nil help-echo nil))
        (goto-char end))
    ;; I don't know what would happen if you don't have
    ;; htmlfontify. I guess if you are installing this you
    ;; should have it...
    (let ((end-marker (set-marker (make-marker) (1+ end))))
      (save-restriction
        (narrow-to-region beg end)
        (let* ((mode (cdr (assoc "mode" attrs)))
               (start (progn (forward-line) (point)))
               (stop (progn (goto-char end) (beginning-of-line) (point)))
               (text (buffer-substring-no-properties start stop))
               (buffer (current-buffer)))
          (delete-region beg end)
          (with-temp-buffer
            (insert text)
            (when (and mode (and (stringp mode) (functionp (intern mode))))
              (funcall (intern mode))
              (font-lock-fontify-buffer))
            (ole-htmlfontify-insert-region buffer (point-min) (point-max)))
          (goto-char (point-min))
          (insert "<pre class=\"example\">\n")
          (goto-char (point-max))
          (insert "</pre>\n")
          (add-text-properties (point-min) (point-max)
                               '(rear-nonsticky (read-only) read-only t))))
      (goto-char end-marker))))

(add-to-list 'emacs-wiki-markup-tags '("example" t t t ole-emacs-wiki-example-tag))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;_+ Preview and Publish
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun emacs-wiki-preview-source ()
  "Preview the html source generated by `emacs-wiki-publish-this-page'"
  (interactive)
  (emacs-wiki-publish-this-page)
  (find-file (emacs-wiki-published-file)))

(defun emacs-wiki-preview-html ()
  "Preview the html generated by `emacs-wiki-publish-this-page'.
The browser is called with `browse-url'"
  (interactive)
  (emacs-wiki-publish-this-page)
  (browse-url (emacs-wiki-published-file)))

(defun emacs-wiki-preview-html-mozilla ()
  "Preview the html generated by `emacs-wiki-publish-this-page' with mozilla."
  (interactive)
  (emacs-wiki-publish-this-page)
  (browse-url-mozilla (emacs-wiki-published-file)))

;; auto publishing, thanks sacha
(defun sacha/emacs-wiki-auto-publish ()
  (when (or (equal major-mode 'emacs-wiki-mode)
            (equal major-mode 'planner-mode))
    (unless emacs-wiki-publishing-p
      (let ((emacs-wiki-publishing-p t)
            (emacs-wiki-after-wiki-publish-hook nil))
        (emacs-wiki-publish-this-page)))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;_+ Emacs Wiki Mode Hook
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun my-wiki-mode-hook ()
  (outline-minor-mode 1)
  (footnote-mode 1)
;;  (flyspell-mode 1)
  (local-set-key [(control ?c) ?j] 'emacs-wiki-journal-add-entry)
  (local-set-key [(control ?c) ?m ?p] 'emacs-wiki-publish-this-page)
  (local-set-key [(control ?c) ?m ?h] 'emacs-wiki-preview-html)
  (local-set-key [(control ?c) ?m ?s] 'emacs-wiki-preview-source)
  (local-set-key [(control ?c) ?m ?m] 'emacs-wiki-preview-html-mozilla)
  (local-set-key [(control ?c) ?m ?i] 'publish-init-files)
  (local-set-key [(control ?c) ?m ?W] 'publish-website)
;  (add-hook 'after-save-hook 'sacha/emacs-wiki-auto-publish nil t)
)
  
(add-hook 'emacs-wiki-mode-hook 'my-wiki-mode-hook)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;_+ Tidy Published Markup
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(require 'tidy)

(defun my-emacs-wiki-after-markup-hook ()
  "cleanup after markup"
  (if (buffer-file-name (current-buffer))
      (tidy-buffer)))

(add-hook 'emacs-wiki-after-markup-hook 'my-emacs-wiki-after-markup-hook t)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;_+ Simple Wiki
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(require 'simple-wiki-completion nil t)
(require 'simple-emacswiki nil t)
(require 'wiki-remote)

(eval-after-load "simple-emacswiki"
  '(progn
     (add-to-list 'auto-mode-alist '("w3mtmp" . simple-wiki-mode))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;_+ Files from the Emacs Wiki
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(require 'wikiarea)
(setq wikiarea-managed-directory (expand-file-name "emacs-wiki/" emacs-init-dir)
      wikiarea-cached-file-list-file (expand-file-name ".wikiarea.eld" emacs-init-dir))