diff options
Diffstat (limited to 'emacs.d/nxhtml/nxhtml/nxhtml-strval.el')
-rw-r--r-- | emacs.d/nxhtml/nxhtml/nxhtml-strval.el | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/emacs.d/nxhtml/nxhtml/nxhtml-strval.el b/emacs.d/nxhtml/nxhtml/nxhtml-strval.el new file mode 100644 index 0000000..88ed1d0 --- /dev/null +++ b/emacs.d/nxhtml/nxhtml/nxhtml-strval.el @@ -0,0 +1,210 @@ +;;; 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 +;; +;; <a href="<?php title(); ?>">...</a> +;; +;; 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 + + <a href=\"<?php title(); ?>\">...</a> + +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 +<?php and ?> in the buffer while editing with something else. +The screen still shows <?php and ?> and when writing the buffer +to a file the substitutes are reverted to <?php and ?>. + +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 <? or ?>." + :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 |