2012-07-18 2 views
4

LaTeX 코드 정리를위한 좋은 elisp 매크로를 아는 사람이 있습니까?LaTeX 코드를 청소하기위한 Elisp 매크로

나는 다른 사람 소스의 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

아마도 하나의 regexp를 작성하여 regexp를 대체 할 수 있습니다. 그러나, 나는 이러한 조작의 논리가 꽤 털이 많음을 발견합니다. 특히 다양한 가장자리 케이스를 고려해야 할 때 그렇습니다. 예를 들어, 하나의 인수를 취하는 환경과 두 개를 취하는 환경을 처리해야합니다.

(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"))))) 

이 방법 이맥스 '내장 함수를 사용하는 장점이 많이있는 sexps을 통해 이동 : 나는이에 대한 기본 텍스트 편집 명령과 함께 간단한 regexps'에 일련의 결합 쉽게 생각 중괄호 안에 여러 중첩 된 식을 처리 할 수있는 자신 만의 regexp를 사용하는 것보다 쉽습니다.

+0

선택적 인수를 사용하면 훨씬 더 복잡해집니다. 감사. 나는 자체적 인 행에'\\\'을 설정할 수있는 매크로와 비슷한 것을 가졌으므로 접근법에서 완전히 틀리지는 않았다는 것을 알았습니다. 물론 장기적으로는 외주 자료를 고려해야합니다. – daleif

+0

섹스 힌트를 보내 주셔서 감사합니다. 그 중 하나를 모르 셨습니다 – daleif

+0

흠, 제가 필요한 건 아닙니다. say \ begin 앞에있는 테스트는 그것이 공백인지 아닌지, 뉴 라인인지를 검사해야합니다. – daleif