emacs를 사용하여 내 xml 파일 (nxml-mode)을 편집하고 컴퓨터에서 생성 된 파일에는 태그의 형식이 예쁘지 않습니다.
들여 쓰기로 전체 파일을 인쇄하고 저장하는 방법을 검색했지만 자동 방법을 찾을 수 없었습니다.
방법이 있습니까? 또는 그것을 할 수있는 리눅스에서 적어도 일부 편집기.
답변:
sgml-mode (gnu emacs 코어 모듈)에는 영역 시작 및 끝 인수를받는 (sgml-pretty-print ...)라는 예쁜 인쇄 기능이 내장되어 있습니다.
xml을 자르고 붙여넣고 터미널이 임의의 위치에서 줄을 자르는 것을 발견하면 먼저 끊어진 줄을 수정 하는이 예쁜 프린터 를 사용할 수 있습니다 .
sgml-mode
시간이 지남에 따라 어떻게 바뀌 었는지 잘 모르겠습니다 . 오늘은 호출 C-x C-f foo.xml
, M-x sgml-mode
다음, M-x sgml-pretty-print
나의 XML 파일은 꽤 인쇄되었다. (. 음 이십 초 이상 교수형 이맥스 완료하기 전에이 후 한 줄의 예쁜 인쇄하기 전에 파일 720 줄을이었다.)
C-x g
전체 버퍼를 영역으로 선택 해야 했습니다.
C-x h
를 선택한 다음 M-x sgml-pretty-print
. XML은 이제 꽤 형식화 될 것입니다
새로운 줄 바꿈없이 들여 쓰기 만 필요한 경우 indent-region
다음 키 입력으로 전체 버퍼에 명령을 적용 할 수 있습니다 .
C-x h
C-M-\
또한 여는 태그와 닫는 태그가 별도의 줄에 있도록 줄 바꿈을 도입해야하는 경우 Benjamin Ferrari가 작성한 다음과 같은 매우 멋진 elisp 함수를 사용할 수 있습니다 . 나는 그의 블로그에서 그것을 찾았고 여기에서 그것을 재현해도 좋기를 바랍니다.
(defun bf-pretty-print-xml-region (begin end)
"Pretty format XML markup in region. You need to have nxml-mode
http://www.emacswiki.org/cgi-bin/wiki/NxmlMode installed to do
this. The function inserts linebreaks to separate tags that have
nothing but whitespace between them. It then indents the markup
by using nxml's indentation rules."
(interactive "r")
(save-excursion
(nxml-mode)
(goto-char begin)
(while (search-forward-regexp "\>[ \\t]*\<" nil t)
(backward-char) (insert "\n") (setq end (1+ end)))
(indent-region begin end))
(message "Ah, much better!"))
이것은 Tidy와 같은 외부 도구에 의존하지 않습니다.
위의 Tim Helmstedt 덕분에 다음과 같이 st를 만들었습니다.
(defun nxml-pretty-format ()
(interactive)
(save-excursion
(shell-command-on-region (point-min) (point-max) "xmllint --format -" (buffer-name) t)
(nxml-mode)
(indent-region begin end)))
빠르고 쉽습니다. 감사합니다.
(indent-region 0 (count-lines (point-min) (point-max)))
줄 바꿈 도입 후 예쁜 인쇄
M-x sgml-mode
M-x sgml-pretty-print
Benjamin Ferrari의 버전에 대한 몇 가지 변경 사항은 다음과 같습니다.
search-forward-regexp
는 버퍼의 끝 부분의 시작에서 물건에서 작동 할 수 있도록, 끝을 지정하지 않았다 (대신 지역의 말)end
Cheeso가 언급했듯이 제대로 증가 합니다.<tag></tag>
값을 수정합니다. 예, 기술적으로 여기에서 모든 값을 수정하고 있지만 빈 시작 / 끝이 훨씬 더 중요합니다. 이제이를 방지하기 위해 약간 더 엄격한 두 개의 개별 검색을 사용합니다.여전히 "외부 정리에 의존하지 않음"등이 있습니다. 그러나 매크로 가 필요 cl
합니다 incf
.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; pretty print xml region
(defun pretty-print-xml-region (begin end)
"Pretty format XML markup in region. You need to have nxml-mode
http://www.emacswiki.org/cgi-bin/wiki/NxmlMode installed to do
this. The function inserts linebreaks to separate tags that have
nothing but whitespace between them. It then indents the markup
by using nxml's indentation rules."
(interactive "r")
(save-excursion
(nxml-mode)
(goto-char begin)
;; split <foo><foo> or </foo><foo>, but not <foo></foo>
(while (search-forward-regexp ">[ \t]*<[^/]" end t)
(backward-char 2) (insert "\n") (incf end))
;; split <foo/></foo> and </foo></foo>
(goto-char begin)
(while (search-forward-regexp "<.*?/.*?>[ \t]*<" end t)
(backward-char) (insert "\n") (incf end))
(indent-region begin end nil)
(normal-mode))
(message "All indented!"))
한 가지 방법은 아래 형식의 것이 있으면
<abc> <abc><abc> <abc></abc> </abc></abc> </abc>
Emacs에서
M-x nxml-mode
M-x replace-regexp RET > *< RET >C-q C-j< RET
C-M-\ to indent
위의 xml 예제를 아래로 들여 씁니다.
<abc>
<abc>
<abc>
<abc>
</abc>
</abc>
</abc>
</abc>
VIM에서는 다음과 같이 할 수 있습니다.
:set ft=xml
:%s/>\s*</>\r</g
ggVG=
도움이 되었기를 바랍니다.
나는했다 제이슨 Viers '버전 자신의 라인에서의 xmlns 선언을 넣어 및 로직을 추가. 여기에서는 공백없이 xmlns = 및 xmlns :가 있다고 가정합니다.
(defun cheeso-pretty-print-xml-region (begin end)
"Pretty format XML markup in region. You need to have nxml-mode
http://www.emacswiki.org/cgi-bin/wiki/NxmlMode installed to do
this. The function inserts linebreaks to separate tags that have
nothing but whitespace between them. It then indents the markup
by using nxml's indentation rules."
(interactive "r")
(save-excursion
(nxml-mode)
;; split <foo><bar> or </foo><bar>, but not <foo></foo>
(goto-char begin)
(while (search-forward-regexp ">[ \t]*<[^/]" end t)
(backward-char 2) (insert "\n") (incf end))
;; split <foo/></foo> and </foo></foo>
(goto-char begin)
(while (search-forward-regexp "<.*?/.*?>[ \t]*<" end t)
(backward-char) (insert "\n") (incf end))
;; put xml namespace decls on newline
(goto-char begin)
(while (search-forward-regexp "\\(<\\([a-zA-Z][-:A-Za-z0-9]*\\)\\|['\"]\\) \\(xmlns[=:]\\)" end t)
(goto-char (match-end 0))
(backward-char 6) (insert "\n") (incf end))
(indent-region begin end nil)
(normal-mode))
(message "All indented!"))
xml-parse.elxml-reformat-tags
에서 사용 합니다. 일반적으로이 명령을 실행할 때 파일 시작 부분에 위치를 지정하려고합니다.
파일이 Emacspeak에 통합되어 있다는 것이 흥미 롭습니다 . Emacspeak를 매일 사용했을 때 xml-reformat-tags
Emacs가 내장되어 있다고 생각했습니다 . 어느 날 나는 그것을 잃어 버리고 그것을 위해 인터넷 검색을해야했고, 따라서 위에서 언급 한 위키 페이지에 들어갔다.
xml-parse를 시작하는 코드도 첨부하고 있습니다. 이것이 Emacs 코드의 가장 좋은 부분인지 확실하지 않지만 나를 위해 작동하는 것 같습니다.
(if (file-exists-p "~/.emacs.d/packages/xml-parse.el")
(let ((load-path load-path))
(add-to-list 'load-path "~/.emacs.d/packages")
(require 'xml-parse))
)
2017 년부터 emacs에는 이미이 기능이 기본으로 제공되지만이 작은 함수를 다음과 ~/.emacs.d/init.el
같이 작성해야합니다 .
(require 'sgml-mode)
(defun reformat-xml ()
(interactive)
(save-excursion
(sgml-pretty-print (point-min) (point-max))
(indent-region (point-min) (point-max))))
그럼 그냥 전화 해 M-x reformat-xml
출처 : https://davidcapello.com/blog/emacs/reformat-xml-on-emacs/
Benjamin Ferrari 버전이 훨씬 더 마음에 들어요. 내부 pretty print는 항상 값 뒤에 새 줄에 끝 태그를 배치하여 태그 값에 원하지 않는 CR을 삽입합니다.
wrong type argument: stringp, nil