xml emacs editor

Bonitos archivos XML de impresión en Emacs



editor (15)

  1. El modo nxml de Emacs puede funcionar en formato presentado, pero deberá dividir las líneas.
  2. Para archivos más largos que simplemente no vale la pena. Ejecute esta hoja de estilo (idealmente con Saxon, que en mi humilde opinión obtiene las sangrías de la línea a la derecha) en comparación con los archivos más largos para obtener una bonita impresión bonita. Para cualquier elemento en el que desee conservar espacios en blanco, agregue sus nombres junto a ''lista de programas'' como en ''lista de programación yourElementName''

HTH

Yo uso emacs para editar mis archivos xml (nxml-mode) y los archivos fueron generados por la máquina no tienen ningún formato bonito de las etiquetas.

He buscado imprimir bastante todo el archivo con sangría y guardarlo, pero no pude encontrar una forma automática.

¿Hay alguna manera? O al menos algún editor en Linux que pueda hacerlo.


Aquí hay algunos ajustes que hice a la versión de Benjamin Ferrari:

  • el search-forward-regexp no especificaba un final, por lo que operaría en cosas desde el principio de la región hasta el final del búfer (en lugar del final de la región)
  • Ahora los incrementos end correctamente, como señaló Cheeso.
  • insertaría una pausa entre <tag></tag> , que modifica su valor. Sí, técnicamente estamos modificando los valores de todo aquí, pero es mucho más probable que un inicio / final vacío sea significativo. Ahora usa dos búsquedas separadas, un poco más estrictas para evitar eso.

Todavía tiene "no depende de ordenamiento externo", etc. Sin embargo, requiere cl para la macro 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!"))


Emacs puede ejecutar comandos arbitrarios con M- |. Si tienes xmllint instalado:

"M- | xmllint --format -" formateará la región seleccionada

"Cu M- | xmllint --format -" hará lo mismo, reemplazando la región con la salida


Gracias a Tim Helmstedt de arriba hice esto así:

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

rapido y facil. Muchas gracias.


Me temo que me gusta la versión de Benjamin Ferrari mucho mejor. La bonita impresión interna siempre coloca la etiqueta final en una nueva línea después del valor, insertando CR no deseado en los valores de etiqueta.


Ni siquiera necesita escribir su propia función: sgml-mode (un módulo core de gnu emacs) tiene una función de impresión integrada llamada (sgml-pretty-print ...) que toma los argumentos de inicio y fin de la región.

Si está cortando y pegando xml y encuentra que su terminal está cortando las líneas en lugares arbitrarios, puede usar esta linda impresora que arregla primero las líneas quebradas.


Para introducir saltos de línea y luego impresión bonita

M-x sgml-mode M-x sgml-pretty-print


Si solo necesita sangrías bonitas sin introducir ningún salto de línea nuevo, puede aplicar el comando indent-region a todo el búfer con estas teclas:

C-x h C-M-/

Si también necesita introducir saltos de línea, para que las etiquetas de apertura y cierre estén en líneas separadas, podría usar la siguiente función de elisp muy buena, escrita por Benjamin Ferrari . Lo encontré en su blog y espero que esté bien que lo reproduzca aquí:

(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")) (indent-region begin end)) (message "Ah, much better!"))

Esto no depende de una herramienta externa como Tidy.


Si usa Spacemacs , simplemente use el comando ''spacemacs / indent-region-or-buffer''.

M-x spacemacs/indent-region-or-buffer


Tidy parece un buen modo. Debe mirarlo. Lo usaré si realmente necesito todas las características que ofrece.

De todos modos, este problema me molestaba por alrededor de una semana y no estaba buscando correctamente. Después de publicar, comencé a buscar y encontré un sitio con una función elisp que lo hace bastante bien. El autor también sugiere usar Tidy.

Gracias por responder a Marcel (lástima que no tengo suficientes puntos para animarte) .

Lo publicaré pronto en mi blog. Aquí hay una publicación al respecto (con un enlace al sitio de Marcel).


Una forma de hacerlo es: si tienes algo en el siguiente formato

<abc> <abc><abc> <abc></abc> </abc></abc> </abc>

En Emacs, prueba

M-x nxml-mode M-x replace-regexp RET > *< RET >C-q C-j< RET C-M-/ to indent

Esto sangrará el ejemplo anterior de xml a continuación

<abc> <abc> <abc> <abc> </abc> </abc> </abc> </abc>

En VIM puedes hacer esto

:set ft=xml :%s/>/s*</>/r</g ggVG=

Espero que esto ayude.



Yo uso xml-reformat-tags de xml-parse.el . Por lo general, querrá tener el punto al principio del archivo al ejecutar este comando.

Es interesante que el archivo esté incorporado en Emacspeak . Cuando usaba Emacspeak día a día, pensé que xml-reformat-tags es un built-in de Emacs. Un día lo perdí y tuve que hacer una búsqueda en Internet para eso, y así ingresé a la página wiki mencionada anteriormente.

Adjunto también mi código para iniciar xml-parse. No estoy seguro de si esta es la mejor pieza de código de Emacs, pero parece funcionar para mí.

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


a partir de 2017 emacs ya viene con esta capacidad por defecto, pero debe escribir esta pequeña función en su ~/.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))))

entonces simplemente llame a Mx reformat-xml

fuente: https://davidcapello.com/blog/emacs/reformat-xml-on-emacs/


Tomé la versión de Jason Viers y agregué la lógica para poner declaraciones xmlns en sus propias líneas. Esto supone que tiene xmlns = y xmlns: sin espacios en blanco intermedios.

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