Twee Mode for Emacs

Tue 24 March, 2015

Twee is the command line variant of Twine, a piece of software to write and publish CYOA-style stories to the web.

Twine is a GUI editor where you can visualise and manipulate the relationships between different story chunks on a graph. It’s a neat piece of software. But despite being OSS, there’s no Linux build.

Thankfully, Twee and Twine story files are just plain text files sprinkled with some markup, so Emacs can come to the rescue.

I’m no lisp hacker, but here’s a skeleton for a twee-mode for Emacs. It has basic syntax highlighting and not much else:

;; MIT/ISC/WTFPL

(defvar twee-mode-hook nil)
(add-to-list 'auto-mode-alist '("\\.tw\\'" . twee-mode))


(defconst twee-font-lock-keywords
  (list
   '("^\\(::.+\\)" . font-lock-function-name-face)  ; ::Passage
   '("\\(\\[\\[\\(.+\\)\\]\\]\\)" . font-lock-keyword-face)  ; [[foo]]
   '("\\(<<.+>>\\)" . font-lock-comment-face)))  ; <<bar>>


(defvar twee-dev-env "twee -t sugarcane")
(defun twee-compile ()
  (interactive)
  (let ((out-file (concat "/tmp/" (buffer-file-name) ".html"))
    (compile (concat twee-dev-env
                     " "
                     (buffer-file-name)
                     " > "
                     out-file))
  (browse-url out-file)))


(defun twee-mode ()
  (interactive)
  (kill-all-local-variables)
  (visual-line-mode)
  (set (make-local-variable 'font-lock-defaults) '(twee-font-lock-keywords))
  (setq major-mode 'twee-mode)
  (setq mode-name "twee")
  (run-hooks 'twee-mode-hook))

(provide 'twee-mode)

Not using Twine does have one unexpected plus—you can organise your story project into logically separated files and ‘compile’ the final product using a makefile or similar:

$ tree
.
├── Beyond.html
├── CREDITS
├── DISCLAIMER
├── LICENSE
├── Makefile
├── README.md
├── setup.tw
├── style.tw
├── tweefiles
│   ├── intro.tw
│   ├── people.tw
│   ├── self.tw
│   └── world.tw
└── twee-mode.el

1 directory, 13 files