;;;;;;;;;;;;;; Command paths ;;;;;;;;;;;;;;

(defvar markdown-command-string "perl D:\\usr\\bin\\Markdown\\markdown.pl"
  "Shell command for Markdown filter")

(defvar smartypants-command-string "perl D:\\usr\\bin\\Markdown\\SmartyPants.pl"
  "Shell command for Smartypants filter")

(defvar textile-command-string "python -u D:\\usr\\bin\\textile-2.0.10\\run.py"
  "Shell command for Textile filter")

;;;;;;;;;;;;;; Generic functions to filter text ;;;;;;;;;;;;;;

(defun clear-buffer (buf)
  "Clear a buffer"
  (save-excursion
    (set-buffer buf)
    (kill-region (point-min) (point-max))))

(defun convert-buffer-text (command)
  "Run a text-to-HTML converter on the current buffer"
  (let ((buf (get-buffer-create "*post-preview*")))
    (clear-buffer buf)
    (shell-command-on-region (point-min) (point-max) command buf nil)
    (switch-to-buffer buf)
    (delete-other-windows)
    (html-mode)))

(defun convert-region-text (start end command)
  "Run a text-to-HTML converter on the current region"
  (let ((buf (get-buffer-create "*post-preview*")))
    (clear-buffer buf)
    (shell-command-on-region start end command buf nil)
    (switch-to-buffer buf)
    (delete-other-windows)
    (html-mode)))

(defun convert-text-to-html (command) 
  "Run a text-to-HTML converter on the current region/buffer"
  (if (and (boundp 'transient-mark-mode) transient-mark-mode mark-active) 
      (convert-region-text (region-beginning) (region-end) command)
    (convert-buffer-text command)))


;;;;;;;;;;;;;; Specific functions to filter text ;;;;;;;;;;;;;;

(defun markdown () 
  "Run Markdown on the current buffer. If the mark is active, 
then run it on the current region. The HTML output is displayed in a
buffer named *post-preview*."
  (interactive)
  (convert-text-to-html markdown-command-string))

(defun markdown-preview ()
  "Converts the current buffer/region to HTML via Markdown, and then the output is
displayed in your default web browser.

Also see http://blog.goterkyourself.com/articles/2007/01/31/emacs-markdown-functions"
  (interactive)
  (markdown)
  (let ((buf (get-buffer-create "*post-preview*")))
    (browse-url-of-buffer buf)))

(defun textile () 
  "Run Textile on the current buffer. If the mark is active, 
then run it on the current region. The HTML output is displayed in a
buffer named *post-preview*."
  (interactive)
  (convert-text-to-html textile-command-string))

;;;;;;;;;;;;;; Smart quotes  ;;;;;;;;;;;;;;

;; Ongoing : http://www.tbray.org/ongoing/When/200x/2003/09/27/UniEmacs
;; Easy Insertion of Commonly-Used Special Characters

(defun one-quote () "" (interactive) (insert ?'))
(defvar sq-state 'nil "In single-quotes?")
(defvar dq-state 'nil "In double quotes?")
(defun ong-insert-special (c) 
  "Insert special characters, like so:
 s => open/close single quotes
 d => open/close double quotes
 ' => apostrophe
 a => <a href=
 i => <img src=
 & => &amp;
 < => &lt;
 - => mdash
 . => horizontal ellipses"
  (interactive "c" "'")
  (cond
   ((= c ?s)
    (if sq-state
        (progn
          (ucs-insert #x2019)
          (setq sq-state 'nil))
      (ucs-insert #x2018)
      (setq sq-state 't)))
   ((= c ?d)
    (if dq-state
        (progn
          (ucs-insert #x201d)
          (setq dq-state 'nil))
      (ucs-insert #x201c)
      (setq dq-state 't)))
   ((= c ?') (ucs-insert #x2019))
   ((= c ?a) 
    (progn
      (if (> (current-column) 0) (newline-and-indent))
      (insert "<a href=\"\">")
      (backward-char 2)
      ))
   ((= c ?i) 
    (progn
      (if (> (current-column) 0) (newline-and-indent))
      (insert "<img src=\"\" alt=\"\" />")
      (backward-char 11)
      ))
   ((= c ?&) (insert "&amp;"))
   ((= c ?<) (insert "&lt;"))
   ((= c ?-) (ucs-insert #x2014))
   ((= c ?`) (insert "`"))
   ((= c ?.) (ucs-insert #x002026))))

;;;;;;;;;;;;;; Initialization  ;;;;;;;;;;;;;;

(setq auto-mode-alist
      (cons '("\\.post$" . blog-post-setup) auto-mode-alist))

(defun blog-post-setup () 
  (html-mode)
  (if (boundp 'longlines-mode) (longlines-mode) (auto-fill-mode -1))
  (local-set-key "\C-cm" 'markdown)
  (local-set-key "\C-cp" 'markdown-preview)
  (local-set-key "\C-cs" 'ispell)
  (local-set-key "`" 'ong-insert-special)
  (font-lock-add-keywords nil
                          '((".*\n?------*" . font-lock-type-face)
                            (".*\n?======*" . font-lock-type-face)
                            ("\\*\\w+\\*" . font-lock-string-face)
                            ("_\\w+_" . font-lock-string-face)
                            ("^>.*$" . font-lock-comment-face)
                            ("^    .*$" . font-lock-comment-face)
                            ("!?\\[.+\\]\\[\\w+\\]" . font-lock-comment-face)
                            ("`\\w+`" . font-lock-string-face)
                            ("^\\*.*$" . font-lock-comment-face)
                            ("\\[\\w+\\]:" . font-lock-comment-face))))

(provide 'posts)