Dungeons and Dragons Wiki:Wikipedia-mode Extension
Talk0
9,507pages on
this wiki
this wiki
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))
;;;; 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-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)
;;;; C-c M-s will change the capitalized fragment under the point from Foobar to
;;;; ''[[SRD:Foobar|foobar]]''
(define-key wikipedia-mode-map (kbd "C-c M-s") 'dungeons-srd-link-spell)
;;;; C-c M-w / M-r turns the word/region under the link into an SRD link.
(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)
;;;; C-c M-a turns the fragment under the point into an in-page link.
(define-key wikipedia-mode-map (kbd "C-c M-a") 'dungeons-inpage-link)
;;;; 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.
(defvar dungeons-fragment-separator "[,\\.\n]"
"Regular expression that tells Emacs how to separate D&D Wiki list fragments from each other.")
;;;; 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 "''[[SRD:")
; Find the end, delete.
(let ((text (dungeons-delete-fragment)))
(insert text)
(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 "[[#")
; Find the end, delete.
(let ((text (dungeons-delete-fragment)))
(insert text)
(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:")))
;;;; 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-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))))
;;;; 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-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 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-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 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-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 to the end of the current 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))