Полезный сниппет для определения кодиро вки xml

Yuri Karaban <[email protected]> Sat, 09 Oct 2004 19:16:51 +0300
Newsgroups gmane.emacs.xemacs.user.russian
Message-ID <[email protected]>
Вот сделал себе фичу, чтобы xml автоматом детектился (правда пока
только если в самом начале "<?xml"). И буффер открывался в соотвествии
с кодировкой которая указана в аттрибутом encoding. Удобно :) теперь и
windows-1251 и utf-8 xml-и для меня прозрачно открыватеся.

Вот, может кому-то понадобится (на всякий случай напоминаю чтобы
работал utf-8 нужно (require 'un-define)).

Вот собственно сам сниппет:
--------------[Cut]--------------------
(defun detect-xml nil
  "Detect if file is xml"
  (save-excursion
    (beginning-of-buffer)
    (let ((pos (search-forward "<?xml" nil t)))
      (when (and pos (= pos 6))
	(set-xml-coding-system)
	(xml-mode)))))

(defun set-xml-coding-system nil
  "Recode xml buffer to match coding system, specified in xml encoding tag"
  (save-excursion
    (beginning-of-buffer)
    (let ((xml-start (search-forward "<?xml" nil t)))
      (when xml-start
	(let ((xml-end (search-forward "?>" nil t)))
	  (when xml-end
	    (save-restriction
	      (narrow-to-region xml-start (- xml-end 2)) ; length of "?>"
	      (beginning-of-buffer)
	      (when (search-forward-regexp " +encoding=\"\\([^\"]+\\)\"" nil t)
		(recode-buffer (find-coding-system (intern (downcase (match-string 1)))))))))))))

(defun recode-buffer (encoding)
  "Recode buffer with ENCODING if encoding is nil do nothing"
  (when encoding
    (let ((old-buf (current-buffer)))
      (with-temp-buffer
	(let ((new-buf (current-buffer)))
	  (set-buffer-file-coding-system 'binary)
	  (insert-file-contents-literally (buffer-file-name old-buf))
	  (decode-coding-region (point-min) (point-max) encoding)	      
	  (set-buffer old-buf)
	  (erase-buffer)
	  (set-buffer-file-coding-system encoding)
	  (insert-buffer new-buf)
	  (set-buffer-modified-p nil))))))

(add-hook 'find-file-hooks 'detect-xml)