我已经为第11.4节(循环练习)中的练习编写了这个解决方案:
(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)))))))))
虽然它正在发挥作用,但对我来说感觉很复杂。我想知道如何简化这段代码。我也对其他可能的改进感兴趣。
修改
泰勒的回答很棒。随着范围的缩小,我可以编写更简洁,更清晰的版本:(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))))))))
答案 0 :(得分:3)
要注意的一件事是缩小范围。你可以使用缩小来绕过你正在做的很多弹跳。
(mark-paragraph)
(narrow-to-region)
将函数的范围限制为当前段落并将点移动到开头。然后,您可以开始向前搜索,而无需担心移过当前段落。当你完成后,
(widen)
恢复要查看的其余缓冲区。
答案 1 :(得分:2)
您可以将search-forward
和buffer-substring
替换为re-search-forward
和match-string
(注意:未经测试):
(while (re-search-forward "@dfn{\\([^}]+\\)}" nil t)
(save-excursion
(goto-char (point-min))
(insert "\n@cindex " (match-string 1))
(while (> (line-number-at-pos) 2) (join-line))
(narrow-to-region (line-end-position) (point-max))))