2012-07-18 85 views
4

有谁知道一些很好的elisp宏来清理LaTeX代码?Elisp宏清理LaTeX代码

我做了很多其他民族来源的LaTeX编辑的,我想,因为不是每个人都致以组的清理工具,组织他们的代码的方式,我喜欢它;-)

其中特别会很有趣,在缓冲区上运行函数X并获得所有LaTeX环境(\ begin {...}和\ end {...}对),这些都有助于代码的可读性。

我可以自己试试,但希望听到关于编程这种功能的最佳实践的建议,例如,它当然不应该引入自己的空白行。

意见建议?

编辑:对于档案,这里是我现在的版本根据给出的答案(假定使用auctex)。这或多或少符合我目前的需求。我添加了y或n测试只是为了能够检测到我没有想到的角落案例。

(defun enviro-split() 
    "Find begin and end macros, and put them on their own line." 
    (interactive) 
    (save-excursion 
(beginning-of-buffer) 

;; loop over document looking for begin and end macros 
(while (re-search-forward "\\\\\\(begin\\|end\\)" nil t) 
    (catch 'continue 

    ; if the line is a pure comment, then goto next 
    (if (TeX-in-commented-line) 
    (throw 'continue nil) 
    ) 
    ;; when you find one, back up to the beginning of the macro 
    (search-backward "\\") 

    ;; If it's not at the beginning of the line, add a newline 
    (when (not (looking-back "^[ \t]*")) 
     (if (y-or-n-p "newline?") 
     (insert "\n") 
    ) 
    ) 

    ;; move over the arguments, one or two pairs of matching braces 
    (search-forward "{")  ; start of the argument 
    (forward-char -1) 
    (forward-sexp)   ; move over the argument 
    (if (looking-at "[ \t]*{") ; is there a second argument? 
    (forward-sexp) 
    )    ; move over it if so 
    (if (looking-at "[ \t]*\\[") ; is there a second argument? 
    (forward-sexp) 
    )    ; move over it if so 
    (when (looking-at (concat "[ \t]*" (regexp-quote TeX-esc) "label")) 
     (goto-char (match-end 0)) 
     (forward-sexp) 
    ) 

    (if (looking-at (concat "[ \t]*%")) 
    (throw 'continue nil) 
    ) 

    ;; If there is anything other than whitespace following the macro, 
    ;; insert a newline 
    (if (not (looking-at "\\s *$")) 
    ;;(insert "\n") 
    (if (y-or-n-p "newline (a)?") 
     (insert "\n") 
    ) 
    ) 
    ) ; end catch 'continue 
) 
(LaTeX-fill-buffer 'left) 
) 
) 

回答

1

你或许可以处理一个正则表达式并为此做一个正则表达式替换。但是,我发现这些操作的逻辑变得非常多毛,特别是当您想要考虑各种边缘情况时。在你的例子中,你需要处理一些采用一个参数的环境,而另一些采取两个。我认为这是比较容易为这个结合了一系列基本的文本编辑命令简单的正则表达式的:

(defun enviro-split() 
    "Find begin and end macros, and put them on their own line." 
    (interactive) 
    (save-excursion 
    (beginning-of-buffer) 

    ;; loop over document looking for begin and end macros 
    (while (re-search-forward "\\\\\\(begin\\|end\\)" nil t) 

     ;; when you find one, back up to the beginning of the macro 
     (search-backward "\\") 

     ;; If it's not at the beginning of the line, add a newline 
     (when (not (looking-at "^")) 
     (insert "\n")) 

     ;; move over the arguments, one or two pairs of matching braces 
     (search-forward "{")    ; start of the argument 
     (forward-char -1) 
     (forward-sexp)     ; move over the argument 
     (if (looking-at "\\s *{")   ; is there a second argument? 
      (forward-sexp))    ; move over it if so 

     ;; If there is anything other than whitespace following the macro, 
     ;; insert a newline 
     (if (not (looking-at "\\s *$")) 
      (insert "\n"))))) 

这种方法使用Emacs内置的功能优势,用于移动在sexps,这是更比想出自己的正则表达式更容易,它可以处理大括号内的多个可能嵌套的表达式。

+0

使用可选参数会变得更加复杂。谢谢。我有类似的宏,它可以根据自己的行来设置'\',很高兴看到我在这个方法中并没有完全错误。当然,从长远来看,还需要考虑注释数据。 – daleif 2012-07-20 09:22:18

+0

也谢谢你的性别提示,不知道那一个 – daleif 2012-07-20 09:25:48

+0

嗯,这不是我所需要的。在\ begin前面看的测试应该测试一下,看它是否只有空白,如果不是,换行。 – daleif 2012-07-20 10:02:17