I modified, somewhat, some code that I've been using for a few years from Jack Moffit to automate most parts of my work flow for publishing posts to this site.
Read through the code and make sure that the path's make sense. Basically:
Your wiki files are located on your system in a folder beneath at
"/path/to/wiki", and
All source files for the wiki are in "/path/to/wiki/source/"
directory, with drafts and other configuration files in the
"wiki/" folder.
Draft blog post entries are located at
"/path/to/wiki/drafts/". If you provide access to
I maintain two distinct blogs, differentiated by having files
located in the "source/rhizome/" and "source/essay/". You can
have more or less, but you'll need to munge the code a bit. Also you
could probably do the code
Here's the code:
;; tycho-ikiwiki.el
;;
;; Emacs support for ikiwiki blogs.
;;
;; To use, just put this file somewhere in the load path and
;; (require 'tycho-ikiwiki)
;;
;; TODO improve documentation here.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Global Settings
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(provide 'tycho-ikiwiki)
;;
;; Variables
;;
(defvar ikiwiki-post-ext ".mdwn"
"File extension of (tychoish) posts.")
(defvar ikiwiki-directory "/path/to/wiki/"
"Path to ikiwiki blog.")
(defvar ikiwiki-drafts-dir "drafts/"
"Path to ikiwiki blog.")
(defvar ikiwiki-essay-dir "source/essay/"
"Path to ikiwiki blog.")
(defvar ikiwiki-rhizome-dir "source/rhizome/"
"Path to ikiwiki blog.")
(defvar ikiwiki-blog-template
"[[!meta title=\"%s\"]]\n[[!meta author=\"tycho garen\"]]\n[[!meta date=\"\"]]\n[[!tag ]]\n"
"Default template for ikiwiki-blog. %s will be replace by the post title.")
;;
;; Helper Functions
;;
(defun ikiwiki-file-make-slug (s)
"Turn a string into a slug."
(replace-regexp-in-string
" " "-" (downcase
(replace-regexp-in-string
"[^A-Za-z0-9 ]" "" s))))
(defun ikiwiki-file-escape (s)
"Escape a string for ikiwiki title."
(if (or (string-match ":" s)
(string-match "\"" s))
(concat "\"" (replace-regexp-in-string "\"" "\\\\\"" s) "\"")
s))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Working Functions
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun ikiwiki-create-blog-post (title)
"Create a new ikwiki blog post."
(interactive "sPost Title: ")
(let ((draft-file (concat (concat ikiwiki-directory ikiwiki-drafts-dir)
(ikiwiki-file-make-slug title)
ikiwiki-post-ext)))
(if (file-exists-p draft-file)
(find-file draft-file)
(find-file draft-file)
(insert (format ikiwiki-blog-template (ikiwiki-file-escape title))))))
(defun ikiwiki-essay-publish-post ()
"Move a draft post to the esasy directory."
(interactive)
(cond
((not (equal
(file-name-directory (buffer-file-name (current-buffer)))
(concat ikiwiki-directory ikiwiki-drafts-dir)))
(message "This is not a draft post.")
(insert (file-name-directory (buffer-file-name (current-buffer))) "\n"
(concat ikiwiki-directory ikiwiki-drafts-dir)))
((buffer-modified-p)
(message "Can't publish post; buffer has modifications."))
(t
(let ((filename
(concat ikiwiki-directory ikiwiki-essay-dir
(file-name-nondirectory
(buffer-file-name (current-buffer)))))
(old-point (point)))
(rename-file (buffer-file-name (current-buffer))
filename)
(kill-buffer nil)
(find-file filename)
(set-window-point (selected-window) old-point)
(pwd)))))
(defun ikiwiki-rhizome-publish-post ()
"Move a draft post to the rhizome directory,"
(interactive)
(cond
((not (equal
(file-name-directory (buffer-file-name (current-buffer)))
(concat ikiwiki-directory ikiwiki-drafts-dir)))
(message "This is not a draft post.")
(insert (file-name-directory (buffer-file-name (current-buffer))) "\n"
(concat ikiwiki-directory ikiwiki-drafts-dir)))
((buffer-modified-p)
(message "Can't publish post; buffer has modifications."))
(t
(let ((filename
(concat ikiwiki-directory ikiwiki-rhizome-dir
(file-name-nondirectory
(buffer-file-name (current-buffer)))))
(old-point (point)))
(rename-file (buffer-file-name (current-buffer))
filename)
(kill-buffer nil)
(find-file filename)
(set-window-point (selected-window) old-point)
(pwd)))))
(defun ikiwiki-meta-date () "Insert Ikiwiki Meta Date String" (interactive)
(shell-command "/path/to/scripts/wiki-date" 1 nil))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Key Bindings
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(global-set-key (kbd "C-c t n") 'ikiwiki-create-blog-post)
(global-set-key (kbd "C-c t t") 'ikiwiki-meta-date)
(global-set-key (kbd "C-c t p r") 'ikiwiki-rhizome-publish-post)
(global-set-key (kbd "C-c t p e") 'ikiwiki-essay-publish-post)
(global-set-key (kbd "C-c t d") (lambda ()
(interactive)
(find-file "/path/to/wiki/drafts/")))
(global-set-key (kbd "C-c t r") (lambda ()
(interactive)
(find-file "/pat/to/wiki/source/rhizome/")))
(global-set-key (kbd "C-c t e") (lambda ()
(interactive)
(find-file "/path/to/wiki/source/essay/")))
The /path/to/scripts/wiki-date is the following file. Basically it
inserts a "YYYY-MM-DD" formatted day. One could totally do this in
elisp, I just did it in Python because it seemed like a good idea at
the time.
#!/usr/bin/env python2
import time, datetime, sys
today = datetime.date.today()
sys.stdout.write(str(today))
If the drafts and wiki source directories are in different git
repositories, then you need the following shell functions in your
.bashrc or .zshrc to do the full publication process:
git-readd() {
if [ "`git ls-files -d | wc -l`" -gt "0" ]; then
git rm --quiet `git ls-files -d`
fi
git add .
}
publish-rhizome () {
CURRENTDIR=`pwd`
cd ~/wikish
git add rhizome/.
git commit
cd ~/sites/wikish/drafts/
git-readd
git commit -m "removing a draft post, routine commit"
git pull --rebase
git push
cd ~/wikish/
git pull --rebase
git push
echo "new post published"
cd $CURRENTDIR
}