;;; nxhtml-strval.el --- ;; ;; Author: Lennart Borgman (lennart O borgman A gmail O com) ;; Created: Wed Jun 06 12:42:09 2007 (defconst nxhtml-strval:version "0.3") ;;Version: ;; LXast-Updated: Sun Jun 10 14:52:50 2007 (7200 +0200) ;; URL: ;; Keywords: ;; Compatibility: ;; ;; FXeatures that might be required by this library: ;; ;; None ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; Commentary: ;; ;; This is a workaround for a problem caused by that the parser from ;; `nxml-mode' parses the whole buffer. This workaround handles things ;; like ;; ;; ... ;; ;; where the string value is not valid XHTML (because of the <). When ;; the minor mode `nxhtml-strval-mode' is on this construct will be ;; replaced by text that are valid XHTML. When writing to file or ;; copying/yanking this will be replaced with the intended text. ;; ;; For a long term solution the parser should be broken up, see also ;; ;; http://sourceforge.net/mailarchive/forum.php?thread_name=4638A428.9010408%40pareto.nl&forum_name=cedet-devel ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; Change log: ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the GNU General Public License as ;; published by the Free Software Foundation; either version 2, or ;; (at your option) any later version. ;; ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;; General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with this program; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth ;; Floor, Boston, MA 02110-1301, USA. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; Code: (define-minor-mode nxhtml-strval-mode "Handle some useful, but not XHTML compliant attribute values. This is mainly for PHP and similar. Things like \">... may be very useful in PHP. However the string value is not valid XHTML (because of the <). This makes it difficult to use XHTML completion and validation. This minor mode tries to take care of that by substituting the in the buffer while editing with something else. The screen still shows and when writing the buffer to a file the substitutes are reverted to . Note that this is a workaround. See the comments in the source file. There are several \(I hope minor) problems with it. For example is the buffer marked as modified when turning on/off this minor mode. IMPORTANT: Do not edit the replaced string ." :lighter nil :gropu 'nxhtml (if nxhtml-strval-mode (nxhtml-strval-mode-turn-on) (nxhtml-strval-mode-turn-off))) (put 'nxhtml-strval-mode 'permanent-local t) (defcustom nxhtml-strval-replface 'nxhtml-strval-replface "Face used to mark replaced characters in strings." :type 'face :group 'nxhtml) (defface nxhtml-strval-replface '((t :inherit font-lock-warning-face)) "Default face used to mark replaced characters in strings." :group 'nxhtml) (defun nxthml-strval-add-ovl (start end) (let ((ovl (make-overlay start end nil t nil))) (overlay-put ovl 'nxhtml-strval t) (overlay-put ovl 'face font-lock-warning-face))) ;;(overlay-put ovl 'face 'highlight))) (defun nxhtml-strval-remove-all-ovls () (remove-overlays (point-min) (point-max) 'nxhtml-strval t)) (defun nxhtml-strval-replace-match () (let ((s (compose-string "{" nil nil ?<))) (replace-match s t t nil 1)) (put-text-property (1- (point)) (point) 'font-lock-face 'font-lock-warning-face) (put-text-property (1- (point)) (point) 'nxhtml-strval-> t) (nxthml-strval-add-ovl (1- (point)) (point)) (let ((s (compose-string "}" nil nil ?>))) (replace-match s t t nil 2)) (nxthml-strval-add-ovl (1- (point)) (point)) (put-text-property (1- (point)) (point) 'font-lock-face 'font-lock-warning-face) (put-text-property (1- (point)) (point) 'nxhtml-strval-> nil)) (defun nxhtml-strval-revert-match () (replace-match "<" t t nil 1) (put-text-property (1- (point)) (point) 'font-lock-face nil) (put-text-property (1- (point)) (point) 'nxhtml-strval-> nil) (replace-match ">" t t nil 2) (put-text-property (1- (point)) (point) 'font-lock-face nil) (put-text-property (1- (point)) (point) 'nxhtml-strval-> nil)) (defconst nxhtml-strval-on-re "\"\\(<\\)[^>]*\\(>\\)\"") (defconst nxhtml-strval-off-re "\"\\({\\)[^>]*\\(}\\)\"") (defun nxhtml-strval-mode-turn-on () (unless (derived-mode-p 'nxml-mode 'php-mode) (error "%s is not derived from nxml-mode" major-mode)) (add-hook 'write-contents-functions 'nxhtml-strval-write-contents nil t) (make-local-variable 'buffer-substring-filters) (add-to-list 'buffer-substring-filters 'nxhtml-strval-buffer-substring-filter) (nxhtml-strval-replace-values) (add-hook 'after-change-functions 'nxhtml-strval-after-change nil t)) (defun nxhtml-strval-replace-values () (save-excursion (save-match-data (save-restriction (widen) (goto-char (point-min)) (while (re-search-forward nxhtml-strval-on-re nil t) (nxhtml-strval-replace-match)))))) (defun nxhtml-strval-mode-turn-off () (remove-hook 'after-change-functions 'nxhtml-strval-after-change t) (nxhtml-strval-revert-values) (remove-hook 'write-contents-functions 'nxhtml-strval-write-contents t) (kill-local-variable 'buffer-substring-filters)) (defun nxhtml-strval-revert-values () (save-excursion (save-match-data (save-restriction (widen) (goto-char (point-min)) (while (re-search-forward nxhtml-strval-off-re nil t) (nxhtml-strval-revert-match)) (nxhtml-strval-remove-all-ovls))))) (defun nxhtml-strval-write-contents () (let ((nxhtml-strval-no-after-change t)) ;;(setq write-contents-functions (delq 'nxhtml-strval-write-contents write-contents-functions)) (remove-hook 'write-contents-functions 'nxhtml-strval-write-contents t) (undo-boundary) (nxhtml-strval-revert-values) ;;(write-file (buffer-file-name)) (save-buffer) ;; Fix-me: undo ;;(nxhtml-strval-replace-values) (undo-start) (undo-more 1) (add-hook 'write-contents-functions 'nxhtml-strval-write-contents nil t) (set-buffer-modified-p nil) t)) ;;; Clip board etc. (defun nxhtml-strval-buffer-substring-filter (orig-str) (let ((str (replace-regexp-in-string "\"{" "\"<" orig-str))) (setq str (replace-regexp-in-string "}\"" ">\"" str)) str )) ;;; Changes ; after-change-functions (defun nxhtml-strval-after-change (beg end len) (unless (and (boundp 'nxhtml-strval-no-after-change) nxhtml-strval-no-after-change) (let ((here (point)) (new-beg beg) (new-end end)) (goto-char beg) (setq new-beg (line-beginning-position)) (goto-char end) (setq new-end (line-end-position)) ;; Fix-me: examine old replacements here (remove-text-properties new-beg new-end '(nxhtml-strval-< nxhtml-strval->)) (goto-char new-beg) (while (re-search-forward nxhtml-strval-on-re new-end t) (nxhtml-strval-replace-match)) (goto-char here) ))) (provide 'nxhtml-strval) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; nxhtml-strval.el ends here