I programmed this solution for the exercise from section 11.4 (Looping Exercise):
(defun texinfo-index-dfns-in-par () "Create an index entry at the beginning of the paragraph for every '@dfn'." (interactive) (save-excursion (forward-paragraph) (let ((bound (point))) (backward-paragraph) (let ((insert-here (point))) (while (search-forward "@dfn{" bound t) (let* ((start (point)) (end (1- (search-forward "}" bound))) (dfn (buffer-substring start end))) (save-excursion (goto-char insert-here) (newline) (setq insert-here (point)) (insert "@cindex " dfn) (while (< insert-here (line-beginning-position)) (join-line)) (end-of-line) (setq insert-here (point)) (forward-paragraph) (setq bound (point)))))))))
Despite the fact that it works, it seems to me that it is too confused. I would like to know how this code can be simplified. I am also interested in other possible improvements.
Edit:
Tyler's answer was wonderful. With narrowing, I could write a much shorter and cleaner version:
(defun texinfo-index-dfns-in-par () "Create an index entry at the beginning of the paragraph for every '@dfn'." (interactive) (save-excursion (mark-paragraph) (save-restriction (narrow-to-region (point) (mark)) (while (search-forward "@dfn{" nil t) (let ((start (point)) (end (1- (search-forward "}")))) (save-excursion (goto-char (point-min)) (insert "\ n@cindex " (buffer-substring start end)) (while (> (line-number-at-pos) 2) (join-line)) (narrow-to-region (line-end-position) (point-max))))))))
source share