Mercurial > hg > xemacs-beta
comparison 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 |
comparison
equal
deleted
inserted
replaced
97:498bf5da1c90 | 98:0d2f883870bc |
---|---|
1 ;;; hm--html-indentation.el | |
2 ;;; v1.00; 9-Feb-1997 | |
3 ;;; Copyright (C) 1997 Heiko Muenkel | |
4 ;;; email: muenkel@tnt.uni-hannover.de | |
5 ;;; | |
6 ;;; This program is free software; you can redistribute it and/or modify | |
7 ;;; it under the terms of the GNU General Public License as published by | |
8 ;;; the Free Software Foundation; either version 1, or (at your option) | |
9 ;;; any later version. | |
10 ;;; | |
11 ;;; This program is distributed in the hope that it will be useful, | |
12 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 ;;; GNU General Public License for more details. | |
15 ;;; | |
16 ;;; You should have received a copy of the GNU General Public License | |
17 ;;; along with this program; if not, write to the Free Software | |
18 ;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
19 ;;; | |
20 ;;; | |
21 ;;; Description: | |
22 ;;; | |
23 ;;; Defines functions for the indentation. | |
24 ;;; | |
25 ;;; Installation: | |
26 ;;; | |
27 ;;; Put this file in one of your load path directories. | |
28 ;;; | |
29 | |
30 (defun hm--html-point-between-strings-p (string-1 | |
31 string-2 | |
32 &optional boundary) | |
33 "Returns non nil, if the current point is between STRING-1 and STRING-2." | |
34 (when (and (re-search-backward (concat "\\(" | |
35 (regexp-quote string-1) | |
36 "\\)\\|\\(" | |
37 (regexp-quote string-2) | |
38 "\\)") | |
39 boundary | |
40 t) | |
41 (match-string 1)) | |
42 (point))) | |
43 | |
44 (defun hm--html-in-comment-p () | |
45 "Checks if the current point is in a comment block. | |
46 If this is the case, then the start point of the comment is returned. | |
47 Otherwise nil is returned." | |
48 (save-excursion | |
49 (hm--html-point-between-strings-p comment-start comment-end))) | |
50 | |
51 (defun hm--html-previous-line-start () | |
52 "Returns the start of the previous non blank line." | |
53 (save-excursion | |
54 (beginning-of-line) | |
55 (skip-chars-backward " \t\n") | |
56 (beginning-of-line) | |
57 (point))) | |
58 | |
59 (defun hm--html-look-at-comment-end-p () | |
60 "T, if the current line starts with the comment end." | |
61 (looking-at (regexp-quote comment-end))) | |
62 | |
63 (defun hm--html-column-of-previous-regexp (regexp) | |
64 "Returns the column of the start of the previous REGEXP. | |
65 It searches backward until the REGEXP is found. If no | |
66 REGEXP is found, then it returns 0." | |
67 (save-excursion | |
68 (if (re-search-backward regexp nil t) | |
69 (current-column) | |
70 0))) | |
71 | |
72 (defun hm--html-look-at-end-tag-p () | |
73 "Returns the end tag name if the point is at the start of an end tag. | |
74 nil is returned otherwise." | |
75 (when (looking-at "\\(<[ \t\n]*/[ \t\n]*\\)\\([^ \t\n>]+\\)") | |
76 (match-string 2))) | |
77 | |
78 | |
79 (defun hm--html-previous-line-indentation () | |
80 "Returns the indentation of the previous non blank line." | |
81 (save-excursion | |
82 (beginning-of-line) | |
83 (skip-chars-backward " \t\n") | |
84 (back-to-indentation) | |
85 (current-column))) | |
86 | |
87 (defun hm--html-in-tag-p () | |
88 "Checks if the current point is in a tag. | |
89 If this is the case, then the start point of the tag is returned. | |
90 Otherwise nil is returned." | |
91 (save-excursion | |
92 (let ((start (re-search-backward "\\(<\\)\\|\\(>\\)" nil t))) | |
93 (when (match-string 1) | |
94 start)))) | |
95 | |
96 (defun hm--html-return-beginning-of-line () | |
97 "Returns the beginning of the current line." | |
98 (save-excursion | |
99 (beginning-of-line) | |
100 (point))) | |
101 | |
102 (defun hm--html-return-end-of-line () | |
103 "Returns the end of the current line." | |
104 (save-excursion | |
105 (end-of-line) | |
106 (point))) | |
107 | |
108 (defun hm--html-paramter-column-in-line-after-point (point) | |
109 "Returns the column where the second non blank text after POINT starts. | |
110 This point must be in the line with POINT otherwise it returns nil." | |
111 (save-excursion | |
112 (goto-char point) | |
113 (when (re-search-forward "<[ \t]*[^ \t]+[ \t]" | |
114 (hm--html-return-end-of-line) | |
115 t) | |
116 (when (looking-at "[^\n]") | |
117 (current-column))))) | |
118 | |
119 (defun hm--html-column-of-point (point) | |
120 "Returns the column of the POINT." | |
121 (save-excursion | |
122 (goto-char point) | |
123 (current-column))) | |
124 | |
125 (defun hm--html-search-previous-tag-in-current-line () | |
126 "Searches tags from the `(point)' to the beginning of the line. | |
127 It returns nil, if there is no tag and the tag name, if there is | |
128 a tag. The tag name contains a leading /, if it is an end tag." | |
129 (when (re-search-backward ">" (hm--html-return-beginning-of-line) t) | |
130 (when (re-search-backward | |
131 "\\(<[ \t\n]*\\(/?\\)\\([ \t\n]*[^> \t\n]+\\)[^>]*\\)" | |
132 nil | |
133 t) | |
134 (concat (match-string 2) (match-string 3))))) | |
135 | |
136 (defun hm--html-search-start-tag (tag-name until) | |
137 "Searches start tag backwards from the current point until the point UNTIL. | |
138 The name of the tag is TAG-NAME. After this function the point is at UNTIL | |
139 (then it returns nil) or at the start of the tag, then it returns t." | |
140 (if (re-search-backward (concat "\\(<[ \t\n]*\\)\\(/?\\)\\(" | |
141 tag-name | |
142 "\\)\\([^>]*>\\)") until t) | |
143 (if (string= "/" (match-string 2)) | |
144 (progn | |
145 (hm--html-search-start-tag tag-name until) | |
146 (hm--html-search-start-tag tag-name until)) | |
147 t) | |
148 (goto-char until) | |
149 nil)) | |
150 | |
151 (defun hm--html-is-one-element-tag-p (tag-name) | |
152 "Returns t, if the tag with the tag-name is a one element tag." | |
153 (assoc :hm--html-one-element-tag | |
154 (cdr (assoc* tag-name hm--html-tag-name-alist :test 'string=)))) | |
155 | |
156 (defun hm--html-calculate-indent-according-to-previous-tags () | |
157 "Calculate the indent according to the previous tags in this line. | |
158 If no tags are found, then nil is returned." | |
159 (save-excursion | |
160 (let ((tag (hm--html-search-previous-tag-in-current-line))) | |
161 (cond ((not tag) nil) | |
162 | |
163 ((eq ?/ (elt tag 0)) ; end tag found | |
164 (if (hm--html-search-start-tag | |
165 (substring tag 1) | |
166 (point-min)) | |
167 (or (hm--html-calculate-indent-according-to-previous-tags) | |
168 (progn | |
169 (backward-to-indentation 0) | |
170 (current-column))) | |
171 0)) ; it may be that the current indentation is better here | |
172 | |
173 ((hm--html-is-one-element-tag-p tag) ; one element tag | |
174 (or (hm--html-calculate-indent-according-to-previous-tags) | |
175 (progn | |
176 (backward-to-indentation 0) | |
177 (current-column)))) | |
178 | |
179 (t ; start tag found | |
180 (+ (current-column) hm--html-inter-tag-indent)))))) | |
181 | |
182 | |
183 (defun hm--html-calculate-indent () | |
184 "Calculate the indentation of the current line." | |
185 (let ((match-point) | |
186 (tag)) | |
187 (save-excursion | |
188 (beginning-of-line) | |
189 (back-to-indentation) | |
190 (cond ((eq (count-lines (point-min) (point)) 0) 0) ; Filestart | |
191 | |
192 ((setq match-point (hm--html-in-comment-p)) ; in a comment | |
193 (if (>= match-point (hm--html-previous-line-start)) ; 1. line | |
194 (if (hm--html-look-at-comment-end-p) | |
195 (hm--html-column-of-previous-regexp | |
196 (regexp-quote comment-start)) | |
197 (+ (hm--html-column-of-previous-regexp | |
198 (regexp-quote comment-start)) | |
199 hm--html-comment-indent)) | |
200 (if (hm--html-look-at-comment-end-p) | |
201 (- (hm--html-previous-line-indentation) | |
202 hm--html-comment-indent) | |
203 (hm--html-previous-line-indentation)))) | |
204 | |
205 ((setq tag (hm--html-look-at-end-tag-p)) ; look at end tag | |
206 (hm--html-search-start-tag tag (point-min)) | |
207 (current-column)) | |
208 | |
209 ((looking-at ">") | |
210 (hm--html-column-of-previous-regexp "<")) | |
211 | |
212 ((setq match-point (hm--html-in-tag-p)) | |
213 (if (>= match-point (hm--html-previous-line-start)) ; 1. line | |
214 (or (hm--html-paramter-column-in-line-after-point match-point) | |
215 (+ (hm--html-column-of-point match-point) | |
216 hm--html-intra-tag-indent)) | |
217 (hm--html-previous-line-indentation))) | |
218 | |
219 (t (or (save-excursion ; check previous line | |
220 (skip-chars-backward " \t\n") | |
221 (hm--html-calculate-indent-according-to-previous-tags)) | |
222 (hm--html-previous-line-indentation))) | |
223 )))) | |
224 | |
225 (defun hm--html-indent-line () | |
226 "Indent the current line line." | |
227 (interactive) | |
228 (unless hm--html-disable-indentation | |
229 (indent-line-to (max 0 (hm--html-calculate-indent))))) | |
230 | |
231 ;;; Indentation | |
232 | |
233 (defun hm--html-indent-region (begin end) | |
234 "Indents the region between BEGIN and END according to the major mode." | |
235 (interactive "d\nm") | |
236 (when (< end begin) | |
237 (let ((a end)) | |
238 (setq end begin) | |
239 (setq begin a))) | |
240 (save-excursion | |
241 (goto-char begin) | |
242 (let ((old-point)) | |
243 (while (and (<= (point) end) | |
244 (not (eq (point) old-point))) | |
245 (setq old-point (point)) | |
246 (indent-according-to-mode) | |
247 (forward-line) | |
248 )))) | |
249 | |
250 | |
251 (provide 'hm--html-indentation) |