(defun auto-edit-substitute (substitutions &optional buffer)
"Automatically edit a BUFFER by applying SUBSTITUTIONS to it one by one.
The SUBSTITUTIONS are an alist of elements like (START END SUBSTITUTION), where
START and END are regexps matching tags delineating a region to which a
substitution is to be applied, and SUBSTITUTION is one of:
A string -- the string is substituted for each region verbatim.
A function -- the function is applied to each region with the
current buffer set to the file being replaced, narrowed to
that region.
if you set START and END to the same thing, you deserve everything you get."
(save-current-buffer
(set-buffer (or buffer (current-buffer)))
(save-excursion
(while substitutions
(let ((subst (car substitutions))
(case-fold-search nil))
(goto-char (point-min))
(while (re-search-forward (car subst) nil t)
(let ((start-posn (point)))
(if (re-search-forward (cadr subst) nil t)
(let ((end-posn (re-search-backward (cadr subst) nil t)))
(cond
((stringp (caddr subst))
(delete-region start-posn end-posn)
(insert (caddr subst)))
((functionp (caddr subst))
(save-restriction
(narrow-to-region start-posn end-posn)
(funcall (caddr subst))))
(t
(cerror 'wrong-type-argument (caddr subst)))))))))
(setq substitutions (cdr substitutions))))))
(provide 'auto-edit-substitute)