Dungeons and Dragons Wiki:Wikipedia-mode Extension

Emacs has a great mode for editing wiki-text, with syntax highlighting and various helpful key-commands. You can use Emacs as your default editor for Wikia through browser-specific settings (Firefox has an extension called It's All Text! that supports this). However, there are a few common tasks on this wiki that are performed often, and are helpful to be automate.d These include:


 * Making a link to a spell.
 * Making an in-page link.
 * Making a link to the SRD.

The Emacs Lisp code here automates all of these tasks with keystrokes that do not conflict with Wikipedia-mode keystrokes. To use it, just copy and paste it into your .emacs or init.el file.

;;;; Make this the mode when we edit wikia.com stuff from the browser with Its All Text! (add-to-list 'auto-mode-alist '("\\.wikia\\.com.*\\.txt\\'". wikipedia-mode))

(define-key wikipedia-mode-map (kbd "C-c M-f") 'dungeons-next-fragment) (define-key wikipedia-mode-map (kbd "C-c M-b") 'dungeons-previous-fragment) (define-key wikipedia-mode-map (kbd "C-c M-a") 'dungeons-start-of-fragment) (define-key wikipedia-mode-map (kbd "C-c M-e") 'dungeons-end-of-fragment) (define-key wikipedia-mode-map (kbd "C-c M-d") 'dungeons-delete-fragment)
 * Movement over list fragment. Keys are intended to be reflective of word
 * movement and massaging word keys.

(define-key wikipedia-mode-map (kbd "C-c M-s") 'dungeons-srd-link-spell) (define-key wikipedia-mode-map (kbd "C-c M-w") 'dungeons-srd-link-word) (define-key wikipedia-mode-map (kbd "C-c M-r") 'dungeons-srd-link-region) (define-key wikipedia-mode-map (kbd "C-c M-a") 'dungeons-inpage-link)
 * C-c M-s will change the capitalized fragment under the point from Foobar to
 * foobar
 * C-c M-w / M-r turns the word/region under the link into an SRD link.
 * C-c M-a turns the fragment under the point into an in-page link.

(defvar dungeons-fragment-separator "[,\\.\n]"	"Regular expression that tells Emacs how to separate D&D Wiki list fragments from each other.")
 * This variable represents the regular expression that separates one list
 * fragment from the next, or preceding, list fragment. In the case of the
 * dungeons and dragons wiki, its either a comma, a period, or a newline.
 * Various Dungeons & Dragons Wiki functions. ;;;;

(defun dungeons-srd-link-spell	"Turns an upper-case spell under the point into a properly italicized, capitalized SRD link."	(interactive)	; Go back to the start of this spell. This function works fine even if	; the point is already at the start of the spell.	(dungeons-start-of-fragment)	(insert "")		(insert (downcase text)))	(insert "")	; Now that we're done with this guy, jump to the start of the next fragment.	(dungeons-next-fragment)) (defun dungeons-inpage-link	"Turns the current fragment into an in-page link."	(interactive)	(dungeons-start-of-fragment)	(insert "")		(insert text))	(insert "")	; Now that we're done with this guy, jump to the start of the next fragment.	(dungeons-next-fragment))

(defun dungeons-srd-link-word	"Turns the current word into an SRD link."	(interactive)	(if	(not (or (equal " " (char-to-string (preceding-char))) (equal "\n" (char-to-string (preceding-char))))) (backward-word))	(save-excursion (insert "SRD:")		(forward-word)		(insert "")))

(defun dungeons-srd-link-region(beg end)	"Turns the current region into an SRD link."	(interactive (list (point) (mark)))	(unless (and beg end) (error "The mark is not set, so there is no region."))	(if (< end beg) (progn			; Exchange variables			(setq end (list end beg))			(setq beg (car end))			(setq end (cadr end))))	(save-excursion (goto-char end) (insert "|]]") (goto-char beg) (insert "[[SRD:")))

(defun dungeons-delete-fragment	"Kills the fragment under the point."	(interactive)	(let ; Variables. ((start (point))		(end (progn			(dungeons-end-of-fragment)			(point)))) ; Expression. (if (interactive-p)			(kill-region start end)			(delete-and-extract-region start end))))
 * If called un-interactively, it deletes and returns the fragment under the
 * point. If called interactively, it kills the fragment under the point.

(defun dungeons-next-fragment	"Jumps to the next list fragment."	(interactive)	(re-search-forward dungeons-fragment-separator)	(while (equal " " (char-to-string (following-char))) (forward-char)))
 * Seeks the point to the start of the next fragment, kind of like next-word.
 * Only really works if the point is over a fragment already.

(defun dungeons-previous-fragment	"Jumps to the previous list fragment, or the start of the current fragment."	(interactive)	(let ((oldpoint (point))) (dungeons-start-of-fragment) (if (= oldpoint (point))			(progn ; Search backwards gets right behind the prior fragment separator, ; then we can just jump to its start. (re-search-backward dungeons-fragment-separator) (dungeons-start-of-fragment)))))
 * Seeks the point to the previous fragment. If we're in the middle of a
 * fragment, move it to the start of the current fragment. If not, move it
 * back a fragment.

(defun dungeons-start-of-fragment	"Jumps to the start of the list fragment under the point."	(interactive)	(re-search-backward dungeons-fragment-separator)	; Forward at least one character. Once to get past whatever we matched, 	; then again to consume any spaces so we can put the point at the start of	; the spell.	(forward-char)	(while (equal " " (char-to-string (following-char))) (forward-char)))
 * Seeks the point to the beginning of the fragment the point is currently
 * over. This works fine even if the point is already at the start of the
 * fragment.

(defun dungeons-end-of-fragment	"Jumps to the end of the list fragment under the point."	(interactive)	(re-search-forward dungeons-fragment-separator)	(backward-char))
 * Seeks to the end of the current fragment.

(define-key wikipedia-mode-map (kbd "C-c M-k") 'dungeons-make-skill-property) (defun dungeons-make-skill-property  "Turns a Name link into a  link."  (interactive)  (dungeons-start-of-fragment)  (let ((begin (point))) (search-forward "" (char-to-string (following-char))))	 (forward-char))	(forward-char)	(let ((start (point)))	  (while (not (equal "]" (char-to-string (following-char))))		(forward-char))	  (let ((text (delete-and-extract-region start (point))))		(search-forward "") (delete-region begin (point)) (insert "")))) (dungeons-next-fragment)  (search-backward ",")  (forward-char)  (insert "\n")  (if (equal " " (char-to-string (following-char))) (delete-char 1)))
 * Cleanup code for old Class/PrC pages that don't have skill semantic properties.
 * Kind of awkward mixture of functional code and destructive updates, but that's Emacs Lisp for you.
 * This is temporary while we need it.