J'utilise emacs pour éditer mes fichiers xml (mode nxml) et les fichiers générés par la machine n'ont pas de joli formatage des balises.
J'ai cherché à imprimer le fichier entier avec indentation et à l'enregistrer, mais je n'ai pas pu trouver un moyen automatique.
Y a-t-il un moyen? Ou au moins un éditeur sur Linux qui peut le faire.
wrong type argument: stringp, nil
Vous n'avez même pas besoin d'écrire votre propre fonction - sgml-mode (un module principal de gnu emacs) a une fonction d'impression jolie intégrée appelée (sgml-pretty-print ...) qui prend les arguments de début et de fin de région.
Si vous coupez et collez du XML et que vous constatez que votre terminal coupe les lignes à des endroits arbitraires, vous pouvez utiliser cette jolie imprimante qui corrige d'abord les lignes brisées.
la source
sgml-mode
cela a pu changer avec le temps. Aujourd'hui, j'invoquaisC-x C-f foo.xml
,M-x sgml-mode
puisM-x sgml-pretty-print
et mon fichier xml suis assez sérigraphiés. (Eh bien, emacs a été suspendu pendant vingt secondes ou plus avant de terminer. C'était un fichier d'une ligne avant la jolie copie et 720 lignes après.)C-x g
pour sélectionner tout le tampon en tant que région.C-x h
et ensuiteM-x sgml-pretty-print
. Le xml sera assez formaté maintenantSi vous n'avez besoin que d'un joli retrait sans introduire de nouveaux sauts de ligne, vous pouvez appliquer la
indent-region
commande à l'ensemble du tampon avec ces frappes:C-x h C-M-\
Si vous avez également besoin d'introduire des sauts de ligne, de sorte que les balises d'ouverture et de fermeture soient sur des lignes séparées, vous pouvez utiliser la très belle fonction elisp suivante, écrite par Benjamin Ferrari . Je l'ai trouvé sur son blog et j'espère que je peux le reproduire ici:
(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!"))
Cela ne repose pas sur un outil externe comme Tidy.
la source
Emacs peut exécuter des commandes arbitraires avec M- |. Si vous avez installé xmllint:
"M- | xmllint --format -" formatera la région sélectionnée
"Cu M- | xmllint --format -" fera de même, en remplaçant la région par la sortie
la source
Merci à Tim Helmstedt ci-dessus, j'ai fait st comme ceci:
(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)))
rapide et facile. Merci beaucoup.
la source
(indent-region 0 (count-lines (point-min) (point-max)))
Pour introduire des sauts de ligne puis une jolie impression
M-x sgml-mode M-x sgml-pretty-print
la source
voici quelques modifications que j'ai apportées à la version de Benjamin Ferrari:
search-forward-regexp
n'a pas spécifié de fin, donc il fonctionnerait sur des trucs du début de la région à la fin du tampon (au lieu de la fin de la région)end
correctement, comme l'a noté Cheeso.<tag></tag>
, ce qui modifie sa valeur. Oui, techniquement, nous modifions les valeurs de tout ici, mais un début / une fin vide est beaucoup plus susceptible d'être significatif. Utilise maintenant deux recherches distinctes, légèrement plus strictes pour éviter cela.A toujours le "ne se fie pas à un rangement externe", etc. Cependant, il en a besoin
cl
pour laincf
macro.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 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!"))
la source
Une façon de faire est si vous avez quelque chose au format ci-dessous
<abc> <abc><abc> <abc></abc> </abc></abc> </abc>
Dans Emacs, essayez
M-x nxml-mode M-x replace-regexp RET > *< RET >C-q C-j< RET C-M-\ to indent
Cela indentera ci-dessus l'exemple xml en dessous
<abc> <abc> <abc> <abc> </abc> </abc> </abc> </abc>
Dans VIM, vous pouvez le faire en
:set ft=xml :%s/>\s*</>\r</g ggVG=
J'espère que cela t'aides.
la source
HTH
la source
J'ai pris la version de Jason Viers et ajouté une logique pour mettre les déclarations xmlns sur leurs propres lignes. Cela suppose que vous avez xmlns = et xmlns: sans espace blanc intermédiaire.
(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!"))
la source
Tidy ressemble à un bon mode. Doit le regarder. Je vais l'utiliser si j'ai vraiment besoin de toutes les fonctionnalités qu'il offre.
Quoi qu'il en soit, ce problème me harcelait pendant environ une semaine et je ne cherchais pas correctement. Après avoir posté, j'ai commencé à chercher et j'ai trouvé un site avec une fonction elisp qui le fait très bien. L'auteur suggère également d'utiliser Tidy.
Merci pour la réponse Marcel
(dommage que je n'ai pas assez de points pour vous upmod).Je publierai bientôt sur mon blog.Voici un article à ce sujet (avec un lien vers le site de Marcel).la source
J'utilise
xml-reformat-tags
depuis xml-parse.el . Habituellement, vous voudrez avoir le point au début du fichier lors de l'exécution de cette commande.Il est intéressant que le fichier soit incorporé dans Emacspeak . Quand j'utilisais Emacspeak au jour le jour, je pensais
xml-reformat-tags
que c'était un intégré Emacs. Un jour, je l'ai perdu et j'ai dû faire une recherche sur Internet pour cela, et je suis donc entré dans la page wiki mentionnée ci-dessus.J'attache également mon code pour démarrer xml-parse. Je ne sais pas si c'est le meilleur morceau de code Emacs, mais cela semble fonctionner pour moi.
(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)) )
la source
Si vous utilisez spacemacs , utilisez simplement la commande 'spacemacs / indent-region-or-buffer'.
M-x spacemacs/indent-region-or-buffer
la source
à partir de 2017, emacs est déjà livré avec cette capacité par défaut, mais vous devez écrire cette petite fonction dans votre
~/.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))))
alors appelle juste
M-x reformat-xml
source: https://davidcapello.com/blog/emacs/reformat-xml-on-emacs/
la source
J'ai peur que j'aime beaucoup mieux la version de Benjamin Ferrari. La jolie impression interne place toujours la balise de fin dans une nouvelle ligne après la valeur, insérant CR indésirable dans les valeurs de balise.
la source