(defun irc-to-html (point mark)
"Convert the region containing IRC captures into a correct HTML blockquote."
(interactive "r")
(let ((start (set-marker (make-marker) point))
(end (set-marker (make-marker) mark)))
(unwind-protect
(progn
(goto-char point)
(indent-according-to-mode)
(insert "
")
(newline)
(irc-htmlize-lines end)
(when (and (eolp) (not (bolp)))
(newline))
(insert "
")
(indent-according-to-mode))
(setq start nil
end nil))))
(defun irc-htmlize-lines (end)
"Loop through all lines of IRC and convert to HTML until end is reached."
(let ((state nil)
(line 0))
(while (<= (point) (marker-position end))
(if (bolp)
(progn (indent-according-to-mode)
(cond
((eq (char-after) ?<)
(when (> line 0)
(insert "
"))
(delete-char 1)
(insert "<")
(setq state 'say))
((eq (char-after) ?*)
(when (> line 0)
(insert "
"))
(insert "")
(forward-char)
(setq state 'action))
(t
(setq state nil)
(forward-char)))
(incf line))
(cond
((eq state 'say)
(if (not (or (eolp) (char-equal (char-after) ?>)))
(forward-char)
(setq state nil)
(when (equal (char-after) ?>)
(delete-char 1))
(insert ">")))
((eq state 'action)
(if (not (or (eolp) (and (char-equal (char-after) ? )
(not (char-equal (char-before) ?*)))))
(forward-char)
(setq state nil)
(insert "")))
(t (cond
((char-equal (char-after) ?<)
(delete-char 1)
(insert "<"))
((char-equal (char-after) ?>)
(delete-char 1)
(insert ">"))
((char-equal (char-after) ?&)
(delete-char 1)
(insert "&"))
(t (forward-char)))))))))