From 600285f9e52466ee8ccd0e30935fece9abbb9715 Mon Sep 17 00:00:00 2001 From: Daniel Borchmann Date: Wed, 21 Nov 2018 14:29:49 +0100 Subject: [PATCH] [Utils] Improve XML pretty printer --- site-lisp/db-utils.el | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/site-lisp/db-utils.el b/site-lisp/db-utils.el index 0a1ccc6..6080889 100644 --- a/site-lisp/db-utils.el +++ b/site-lisp/db-utils.el @@ -236,17 +236,36 @@ are assumed to be of the form *.crt." (defun db/pretty-print-xml () "Stupid function to pretty print XML content in current buffer." + ;; We assume that < and > only occur as XML tag delimiters, not in strings; + ;; this function is not Unicode-safe (interactive) + (unless (eq major-mode 'nxml-mode) - (require 'nxml-mode) - (nxml-mode)) + (require 'nxml-mode) + (nxml-mode)) + (save-mark-and-excursion + + ;; First make it all into one line (goto-char (point-min)) - (while (re-search-forward "\n[[:space:]]*" nil 'no-error) - (replace-match "")) + (while (re-search-forward "\n[\t ]*" nil 'no-error) + ;; In case there was a space, we have to keep at least one as a separator + (if (save-match-data (looking-back "[\t ]")) + (replace-match " ") + (replace-match ""))) + + ;; Next break between tags (goto-char (point-min)) - (while (re-search-forward ">[[:space:]]*<" nil 'no-error) + (while (re-search-forward ">[\t ]*<" nil 'no-error) (replace-match ">\n<")) + + ;; Move opening and closing tags to same line in case there’s nothing in + ;; between + (goto-char (point-min)) + (while (re-search-forward "<\\([^>]*\\)>\n" nil 'no-error) + (replace-match "<\\1>")) + + ;; Indent (mark-whole-buffer) (indent-region (point-min) (point-max))))