Mercurial > hg > xemacs-beta
diff lisp/hm--html-menus/hm--html-indentation.el @ 98:0d2f883870bc r20-1b1
Import from CVS: tag r20-1b1
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:13:56 +0200 |
parents | 8fc7fe29b841 |
children | 4103f0995bd7 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lisp/hm--html-menus/hm--html-indentation.el Mon Aug 13 09:13:56 2007 +0200 @@ -0,0 +1,251 @@ +;;; hm--html-indentation.el +;;; v1.00; 9-Feb-1997 +;;; Copyright (C) 1997 Heiko Muenkel +;;; email: muenkel@tnt.uni-hannover.de +;;; +;;; 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 1, 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; if not, write to the Free Software +;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +;;; +;;; +;;; Description: +;;; +;;; Defines functions for the indentation. +;;; +;;; Installation: +;;; +;;; Put this file in one of your load path directories. +;;; + +(defun hm--html-point-between-strings-p (string-1 + string-2 + &optional boundary) + "Returns non nil, if the current point is between STRING-1 and STRING-2." + (when (and (re-search-backward (concat "\\(" + (regexp-quote string-1) + "\\)\\|\\(" + (regexp-quote string-2) + "\\)") + boundary + t) + (match-string 1)) + (point))) + +(defun hm--html-in-comment-p () + "Checks if the current point is in a comment block. +If this is the case, then the start point of the comment is returned. +Otherwise nil is returned." + (save-excursion + (hm--html-point-between-strings-p comment-start comment-end))) + +(defun hm--html-previous-line-start () + "Returns the start of the previous non blank line." + (save-excursion + (beginning-of-line) + (skip-chars-backward " \t\n") + (beginning-of-line) + (point))) + +(defun hm--html-look-at-comment-end-p () + "T, if the current line starts with the comment end." + (looking-at (regexp-quote comment-end))) + +(defun hm--html-column-of-previous-regexp (regexp) + "Returns the column of the start of the previous REGEXP. +It searches backward until the REGEXP is found. If no +REGEXP is found, then it returns 0." + (save-excursion + (if (re-search-backward regexp nil t) + (current-column) + 0))) + +(defun hm--html-look-at-end-tag-p () + "Returns the end tag name if the point is at the start of an end tag. +nil is returned otherwise." + (when (looking-at "\\(<[ \t\n]*/[ \t\n]*\\)\\([^ \t\n>]+\\)") + (match-string 2))) + + +(defun hm--html-previous-line-indentation () + "Returns the indentation of the previous non blank line." + (save-excursion + (beginning-of-line) + (skip-chars-backward " \t\n") + (back-to-indentation) + (current-column))) + +(defun hm--html-in-tag-p () + "Checks if the current point is in a tag. +If this is the case, then the start point of the tag is returned. +Otherwise nil is returned." + (save-excursion + (let ((start (re-search-backward "\\(<\\)\\|\\(>\\)" nil t))) + (when (match-string 1) + start)))) + +(defun hm--html-return-beginning-of-line () + "Returns the beginning of the current line." + (save-excursion + (beginning-of-line) + (point))) + +(defun hm--html-return-end-of-line () + "Returns the end of the current line." + (save-excursion + (end-of-line) + (point))) + +(defun hm--html-paramter-column-in-line-after-point (point) + "Returns the column where the second non blank text after POINT starts. +This point must be in the line with POINT otherwise it returns nil." + (save-excursion + (goto-char point) + (when (re-search-forward "<[ \t]*[^ \t]+[ \t]" + (hm--html-return-end-of-line) + t) + (when (looking-at "[^\n]") + (current-column))))) + +(defun hm--html-column-of-point (point) + "Returns the column of the POINT." + (save-excursion + (goto-char point) + (current-column))) + +(defun hm--html-search-previous-tag-in-current-line () + "Searches tags from the `(point)' to the beginning of the line. +It returns nil, if there is no tag and the tag name, if there is +a tag. The tag name contains a leading /, if it is an end tag." + (when (re-search-backward ">" (hm--html-return-beginning-of-line) t) + (when (re-search-backward + "\\(<[ \t\n]*\\(/?\\)\\([ \t\n]*[^> \t\n]+\\)[^>]*\\)" + nil + t) + (concat (match-string 2) (match-string 3))))) + +(defun hm--html-search-start-tag (tag-name until) + "Searches start tag backwards from the current point until the point UNTIL. +The name of the tag is TAG-NAME. After this function the point is at UNTIL + (then it returns nil) or at the start of the tag, then it returns t." + (if (re-search-backward (concat "\\(<[ \t\n]*\\)\\(/?\\)\\(" + tag-name + "\\)\\([^>]*>\\)") until t) + (if (string= "/" (match-string 2)) + (progn + (hm--html-search-start-tag tag-name until) + (hm--html-search-start-tag tag-name until)) + t) + (goto-char until) + nil)) + +(defun hm--html-is-one-element-tag-p (tag-name) + "Returns t, if the tag with the tag-name is a one element tag." + (assoc :hm--html-one-element-tag + (cdr (assoc* tag-name hm--html-tag-name-alist :test 'string=)))) + +(defun hm--html-calculate-indent-according-to-previous-tags () + "Calculate the indent according to the previous tags in this line. +If no tags are found, then nil is returned." + (save-excursion + (let ((tag (hm--html-search-previous-tag-in-current-line))) + (cond ((not tag) nil) + + ((eq ?/ (elt tag 0)) ; end tag found + (if (hm--html-search-start-tag + (substring tag 1) + (point-min)) + (or (hm--html-calculate-indent-according-to-previous-tags) + (progn + (backward-to-indentation 0) + (current-column))) + 0)) ; it may be that the current indentation is better here + + ((hm--html-is-one-element-tag-p tag) ; one element tag + (or (hm--html-calculate-indent-according-to-previous-tags) + (progn + (backward-to-indentation 0) + (current-column)))) + + (t ; start tag found + (+ (current-column) hm--html-inter-tag-indent)))))) + + +(defun hm--html-calculate-indent () + "Calculate the indentation of the current line." + (let ((match-point) + (tag)) + (save-excursion + (beginning-of-line) + (back-to-indentation) + (cond ((eq (count-lines (point-min) (point)) 0) 0) ; Filestart + + ((setq match-point (hm--html-in-comment-p)) ; in a comment + (if (>= match-point (hm--html-previous-line-start)) ; 1. line + (if (hm--html-look-at-comment-end-p) + (hm--html-column-of-previous-regexp + (regexp-quote comment-start)) + (+ (hm--html-column-of-previous-regexp + (regexp-quote comment-start)) + hm--html-comment-indent)) + (if (hm--html-look-at-comment-end-p) + (- (hm--html-previous-line-indentation) + hm--html-comment-indent) + (hm--html-previous-line-indentation)))) + + ((setq tag (hm--html-look-at-end-tag-p)) ; look at end tag + (hm--html-search-start-tag tag (point-min)) + (current-column)) + + ((looking-at ">") + (hm--html-column-of-previous-regexp "<")) + + ((setq match-point (hm--html-in-tag-p)) + (if (>= match-point (hm--html-previous-line-start)) ; 1. line + (or (hm--html-paramter-column-in-line-after-point match-point) + (+ (hm--html-column-of-point match-point) + hm--html-intra-tag-indent)) + (hm--html-previous-line-indentation))) + + (t (or (save-excursion ; check previous line + (skip-chars-backward " \t\n") + (hm--html-calculate-indent-according-to-previous-tags)) + (hm--html-previous-line-indentation))) + )))) + +(defun hm--html-indent-line () + "Indent the current line line." + (interactive) + (unless hm--html-disable-indentation + (indent-line-to (max 0 (hm--html-calculate-indent))))) + +;;; Indentation + +(defun hm--html-indent-region (begin end) + "Indents the region between BEGIN and END according to the major mode." + (interactive "d\nm") + (when (< end begin) + (let ((a end)) + (setq end begin) + (setq begin a))) + (save-excursion + (goto-char begin) + (let ((old-point)) + (while (and (<= (point) end) + (not (eq (point) old-point))) + (setq old-point (point)) + (indent-according-to-mode) + (forward-line) + )))) + + +(provide 'hm--html-indentation)