14159
|
1 ;;; sgml-mode.el --- SGML- and HTML-editing modes
|
809
|
2
|
20922
|
3 ;; Copyright (C) 1992, 1995, 1996, 1998 Free Software Foundation, Inc.
|
844
|
4
|
17432
|
5 ;; Author: James Clark <jjc@jclark.com>
|
23869
|
6 ;; Adapted-By: ESR, Daniel Pfeiffer <occitan@esperanto.org>,
|
17491
|
7 ;; F.Potorti@cnuce.cnr.it
|
37252
|
8 ;; Maintainer: ???
|
14159
|
9 ;; Keywords: wp, hypermedia, comm, languages
|
809
|
10
|
|
11 ;; This file is part of GNU Emacs.
|
|
12
|
|
13 ;; GNU Emacs is free software; you can redistribute it and/or modify
|
|
14 ;; it under the terms of the GNU General Public License as published by
|
12244
|
15 ;; the Free Software Foundation; either version 2, or (at your option)
|
809
|
16 ;; any later version.
|
|
17
|
|
18 ;; GNU Emacs is distributed in the hope that it will be useful,
|
|
19 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
21 ;; GNU General Public License for more details.
|
|
22
|
|
23 ;; You should have received a copy of the GNU General Public License
|
14169
|
24 ;; along with GNU Emacs; see the file COPYING. If not, write to the
|
|
25 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
26 ;; Boston, MA 02111-1307, USA.
|
809
|
27
|
|
28 ;;; Commentary:
|
|
29
|
14159
|
30 ;; Configurable major mode for editing document in the SGML standard general
|
|
31 ;; markup language. As an example contains a mode for editing the derived
|
|
32 ;; HTML hypertext markup language.
|
809
|
33
|
|
34 ;;; Code:
|
|
35
|
25175
|
36 (eval-when-compile
|
|
37 (require 'skeleton)
|
|
38 (require 'outline))
|
23726
|
39
|
17432
|
40 (defgroup sgml nil
|
|
41 "SGML editing mode"
|
|
42 :group 'languages)
|
|
43
|
17545
|
44 (defcustom sgml-transformation 'identity
|
17491
|
45 "*Default value for `skeleton-transformation' (which see) in SGML mode."
|
|
46 :type 'function
|
17530
|
47 :group 'sgml)
|
17491
|
48
|
|
49 (put 'sgml-transformation 'variable-interactive
|
|
50 "aTransformation function: ")
|
|
51
|
25175
|
52 (defcustom sgml-mode-hook nil
|
|
53 "Hook run by command `sgml-mode'.
|
|
54 `text-mode-hook' is run first."
|
|
55 :group 'sgml
|
|
56 :type 'hook)
|
|
57
|
14159
|
58 ;; As long as Emacs' syntax can't be complemented with predicates to context
|
|
59 ;; sensitively confirm the syntax of characters, we have to live with this
|
|
60 ;; kludgy kind of tradeoff.
|
16404
|
61 (defvar sgml-specials '(?\")
|
17551
|
62 "List of characters that have a special meaning for SGML mode.
|
14159
|
63 This list is used when first loading the sgml-mode library.
|
|
64 The supported characters and potential disadvantages are:
|
|
65
|
|
66 ?\\\" Makes \" in text start a string.
|
|
67 ?' Makes ' in text start a string.
|
|
68 ?- Makes -- in text start a comment.
|
|
69
|
22319
|
70 When only one of ?\\\" or ?' are included, \"'\" or '\"', as can be found in
|
14159
|
71 DTDs, start a string. To partially avoid this problem this also makes these
|
16404
|
72 self insert as named entities depending on `sgml-quick-keys'.
|
|
73
|
|
74 Including ?- has the problem of affecting dashes that have nothing to do
|
|
75 with comments, so we normally turn it off.")
|
14270
|
76
|
|
77 (defvar sgml-quick-keys nil
|
17551
|
78 "Use <, >, &, SPC and `sgml-specials' keys \"electrically\" when non-nil.
|
|
79 This takes effect when first loading the sgml-mode library.")
|
14159
|
80
|
809
|
81
|
14159
|
82 (defvar sgml-mode-map
|
|
83 (let ((map (list 'keymap (make-vector 256 nil)))
|
|
84 (menu-map (make-sparse-keymap "SGML")))
|
|
85 (define-key map "\C-c\C-i" 'sgml-tags-invisible)
|
|
86 (define-key map "/" 'sgml-slash)
|
14270
|
87 (define-key map "\C-c\C-n" 'sgml-name-char)
|
|
88 (define-key map "\C-c\C-t" 'sgml-tag)
|
14159
|
89 (define-key map "\C-c\C-a" 'sgml-attributes)
|
|
90 (define-key map "\C-c\C-b" 'sgml-skip-tag-backward)
|
|
91 (define-key map [?\C-c left] 'sgml-skip-tag-backward)
|
|
92 (define-key map "\C-c\C-f" 'sgml-skip-tag-forward)
|
|
93 (define-key map [?\C-c right] 'sgml-skip-tag-forward)
|
|
94 (define-key map "\C-c\C-d" 'sgml-delete-tag)
|
|
95 (define-key map "\C-c\^?" 'sgml-delete-tag)
|
|
96 (define-key map "\C-c?" 'sgml-tag-help)
|
|
97 (define-key map "\C-c8" 'sgml-name-8bit-mode)
|
|
98 (define-key map "\C-c\C-v" 'sgml-validate)
|
14270
|
99 (if sgml-quick-keys
|
|
100 (progn
|
|
101 (define-key map "&" 'sgml-name-char)
|
|
102 (define-key map "<" 'sgml-tag)
|
|
103 (define-key map " " 'sgml-auto-attributes)
|
|
104 (define-key map ">" 'sgml-maybe-end-tag)
|
|
105 (if (memq ?\" sgml-specials)
|
|
106 (define-key map "\"" 'sgml-name-self))
|
|
107 (if (memq ?' sgml-specials)
|
|
108 (define-key map "'" 'sgml-name-self))))
|
14159
|
109 (let ((c 127)
|
|
110 (map (nth 1 map)))
|
|
111 (while (< (setq c (1+ c)) 256)
|
|
112 (aset map c 'sgml-maybe-name-self)))
|
|
113 (define-key map [menu-bar sgml] (cons "SGML" menu-map))
|
|
114 (define-key menu-map [sgml-validate] '("Validate" . sgml-validate))
|
|
115 (define-key menu-map [sgml-name-8bit-mode]
|
|
116 '("Toggle 8 Bit Insertion" . sgml-name-8bit-mode))
|
|
117 (define-key menu-map [sgml-tags-invisible]
|
|
118 '("Toggle Tag Visibility" . sgml-tags-invisible))
|
|
119 (define-key menu-map [sgml-tag-help]
|
|
120 '("Describe Tag" . sgml-tag-help))
|
|
121 (define-key menu-map [sgml-delete-tag]
|
|
122 '("Delete Tag" . sgml-delete-tag))
|
|
123 (define-key menu-map [sgml-skip-tag-forward]
|
|
124 '("Forward Tag" . sgml-skip-tag-forward))
|
|
125 (define-key menu-map [sgml-skip-tag-backward]
|
|
126 '("Backward Tag" . sgml-skip-tag-backward))
|
|
127 (define-key menu-map [sgml-attributes]
|
|
128 '("Insert Attributes" . sgml-attributes))
|
|
129 (define-key menu-map [sgml-tag] '("Insert Tag" . sgml-tag))
|
|
130 map)
|
|
131 "Keymap for SGML mode. See also `sgml-specials'.")
|
|
132
|
809
|
133
|
14159
|
134 (defvar sgml-mode-syntax-table
|
|
135 (let ((table (copy-syntax-table text-mode-syntax-table)))
|
|
136 (modify-syntax-entry ?< "(>" table)
|
|
137 (modify-syntax-entry ?> ")<" table)
|
|
138 (if (memq ?- sgml-specials)
|
|
139 (modify-syntax-entry ?- "_ 1234" table))
|
|
140 (if (memq ?\" sgml-specials)
|
|
141 (modify-syntax-entry ?\" "\"\"" table))
|
|
142 (if (memq ?' sgml-specials)
|
|
143 (modify-syntax-entry ?\' "\"'" table))
|
|
144 table)
|
|
145 "Syntax table used in SGML mode. See also `sgml-specials'.")
|
|
146
|
|
147
|
17432
|
148 (defcustom sgml-name-8bit-mode nil
|
17551
|
149 "*When non-nil, insert 8 bit characters with their names."
|
17432
|
150 :type 'boolean
|
|
151 :group 'sgml)
|
14159
|
152
|
|
153 (defvar sgml-char-names
|
|
154 [nil nil nil nil nil nil nil nil
|
|
155 nil nil nil nil nil nil nil nil
|
|
156 nil nil nil nil nil nil nil nil
|
|
157 nil nil nil nil nil nil nil nil
|
17491
|
158 "nbsp" "excl" "quot" "num" "dollar" "percnt" "amp" "apos"
|
14159
|
159 "lpar" "rpar" "ast" "plus" "comma" "hyphen" "period" "sol"
|
|
160 nil nil nil nil nil nil nil nil
|
|
161 nil nil "colon" "semi" "lt" "eq" "gt" "quest"
|
|
162 "commat" nil nil nil nil nil nil nil
|
|
163 nil nil nil nil nil nil nil nil
|
|
164 nil nil nil nil nil nil nil nil
|
|
165 nil nil nil "lsqb" nil "rsqb" "uarr" "lowbar"
|
|
166 "lsquo" nil nil nil nil nil nil nil
|
|
167 nil nil nil nil nil nil nil nil
|
|
168 nil nil nil nil nil nil nil nil
|
|
169 nil nil nil "lcub" "verbar" "rcub" "tilde" nil
|
|
170 nil nil nil nil nil nil nil nil
|
|
171 nil nil nil nil nil nil nil nil
|
|
172 nil nil nil nil nil nil nil nil
|
|
173 nil nil nil nil nil nil nil nil
|
|
174 "nbsp" "iexcl" "cent" "pound" "curren" "yen" "brvbar" "sect"
|
|
175 "uml" "copy" "ordf" "laquo" "not" "shy" "reg" "macr"
|
|
176 "ring" "plusmn" "sup2" "sup3" "acute" "micro" "para" "middot"
|
26250
|
177 "cedil" "sup1" "ordm" "raquo" "frac14" "frac12" "frac34" "iquest"
|
14159
|
178 "Agrave" "Aacute" "Acirc" "Atilde" "Auml" "Aring" "AElig" "Ccedil"
|
|
179 "Egrave" "Eacute" "Ecirc" "Euml" "Igrave" "Iacute" "Icirc" "Iuml"
|
|
180 "ETH" "Ntilde" "Ograve" "Oacute" "Ocirc" "Otilde" "Ouml" nil
|
|
181 "Oslash" "Ugrave" "Uacute" "Ucirc" "Uuml" "Yacute" "THORN" "szlig"
|
|
182 "agrave" "aacute" "acirc" "atilde" "auml" "aring" "aelig" "ccedil"
|
|
183 "egrave" "eacute" "ecirc" "euml" "igrave" "iacute" "icirc" "iuml"
|
|
184 "eth" "ntilde" "ograve" "oacute" "ocirc" "otilde" "ouml" "divide"
|
|
185 "oslash" "ugrave" "uacute" "ucirc" "uuml" "yacute" "thorn" "yuml"]
|
|
186 "Vector of symbolic character names without `&' and `;'.")
|
|
187
|
|
188
|
25052
|
189 ;; nsgmls is a free SGML parser in the SP suite available from
|
|
190 ;; ftp.jclark.com and otherwise packaged for GNU systems.
|
14159
|
191 ;; Its error messages can be parsed by next-error.
|
|
192 ;; The -s option suppresses output.
|
|
193
|
25052
|
194 (defcustom sgml-validate-command "nsgmls -s" ; replaced old `sgmls'
|
809
|
195 "*The command to validate an SGML document.
|
|
196 The file name of current buffer file name will be appended to this,
|
17432
|
197 separated by a space."
|
|
198 :type 'string
|
25175
|
199 :version "21.1"
|
17432
|
200 :group 'sgml)
|
809
|
201
|
|
202 (defvar sgml-saved-validate-command nil
|
|
203 "The command last used to validate in this buffer.")
|
|
204
|
|
205
|
14159
|
206 ;;; I doubt that null end tags are used much for large elements,
|
|
207 ;;; so use a small distance here.
|
17432
|
208 (defcustom sgml-slash-distance 1000
|
17551
|
209 "*If non-nil, is the maximum distance to search for matching `/'."
|
17432
|
210 :type '(choice (const nil) integer)
|
|
211 :group 'sgml)
|
809
|
212
|
|
213 (defconst sgml-start-tag-regex
|
|
214 "<[A-Za-z]\\([-.A-Za-z0-9= \n\t]\\|\"[^\"]*\"\\|'[^']*'\\)*"
|
|
215 "Regular expression that matches a non-empty start tag.
|
17551
|
216 Any terminating `>' or `/' is not matched.")
|
809
|
217
|
14159
|
218
|
21780
5dc3fe7cd300
(sgml-font-lock-keywords-1): Copy initialization from sgml-font-lock-keywords.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
219 ;; internal
|
5dc3fe7cd300
(sgml-font-lock-keywords-1): Copy initialization from sgml-font-lock-keywords.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
220 (defconst sgml-font-lock-keywords-1
|
23726
|
221 '(("<\\([!?][a-z][-.a-z0-9]*\\)" 1 font-lock-keyword-face)
|
|
222 ("<\\(/?[a-z][-.a-z0-9]*\\)" 1 font-lock-function-name-face)
|
|
223 ("[&%][a-z][-.a-z0-9]*;?" . font-lock-variable-name-face)
|
22319
|
224 ("<! *--.*-- *>" . font-lock-comment-face)))
|
21780
5dc3fe7cd300
(sgml-font-lock-keywords-1): Copy initialization from sgml-font-lock-keywords.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
225
|
5dc3fe7cd300
(sgml-font-lock-keywords-1): Copy initialization from sgml-font-lock-keywords.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
226 (defconst sgml-font-lock-keywords-2 ())
|
5dc3fe7cd300
(sgml-font-lock-keywords-1): Copy initialization from sgml-font-lock-keywords.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
227
|
5dc3fe7cd300
(sgml-font-lock-keywords-1): Copy initialization from sgml-font-lock-keywords.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
228 ;; for font-lock, but must be defvar'ed after
|
5dc3fe7cd300
(sgml-font-lock-keywords-1): Copy initialization from sgml-font-lock-keywords.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
229 ;; sgml-font-lock-keywords-1 and sgml-font-lock-keywords-2 above
|
5dc3fe7cd300
(sgml-font-lock-keywords-1): Copy initialization from sgml-font-lock-keywords.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
230 (defvar sgml-font-lock-keywords sgml-font-lock-keywords-1
|
14159
|
231 "*Rules for highlighting SGML code. See also `sgml-tag-face-alist'.")
|
|
232
|
|
233 ;; internal
|
|
234 (defvar sgml-face-tag-alist ()
|
|
235 "Alist of face and tag name for facemenu.")
|
|
236
|
|
237 (defvar sgml-tag-face-alist ()
|
|
238 "Tag names and face or list of faces to fontify with when invisible.
|
|
239 When `font-lock-maximum-decoration' is 1 this is always used for fontifying.
|
|
240 When more these are fontified together with `sgml-font-lock-keywords'.")
|
|
241
|
|
242
|
|
243 (defvar sgml-display-text ()
|
|
244 "Tag names as lowercase symbols, and display string when invisible.")
|
|
245
|
|
246 ;; internal
|
|
247 (defvar sgml-tags-invisible nil)
|
|
248
|
|
249
|
17432
|
250 (defcustom sgml-tag-alist
|
14270
|
251 '(("![" ("ignore" t) ("include" t))
|
|
252 ("!attlist")
|
14159
|
253 ("!doctype")
|
|
254 ("!element")
|
|
255 ("!entity"))
|
|
256 "*Alist of tag names for completing read and insertion rules.
|
|
257 This alist is made up as
|
|
258
|
|
259 ((\"tag\" . TAGRULE)
|
|
260 ...)
|
809
|
261
|
14159
|
262 TAGRULE is a list of optionally `t' (no endtag) or `\\n' (separate endtag by
|
|
263 newlines) or a skeleton with `nil', `t' or `\\n' in place of the interactor
|
|
264 followed by an ATTRIBUTERULE (for an always present attribute) or an
|
|
265 attribute alist.
|
|
266
|
|
267 The attribute alist is made up as
|
|
268
|
|
269 ((\"attribute\" . ATTRIBUTERULE)
|
|
270 ...)
|
|
271
|
|
272 ATTRIBUTERULE is a list of optionally `t' (no value when no input) followed by
|
17432
|
273 an optional alist of possible values."
|
|
274 :type '(repeat (cons (string :tag "Tag Name")
|
|
275 (repeat :tag "Tag Rule" sexp)))
|
|
276 :group 'sgml)
|
809
|
277
|
17432
|
278 (defcustom sgml-tag-help
|
14159
|
279 '(("!" . "Empty declaration for comment")
|
|
280 ("![" . "Embed declarations with parser directive")
|
|
281 ("!attlist" . "Tag attributes declaration")
|
|
282 ("!doctype" . "Document type (DTD) declaration")
|
|
283 ("!element" . "Tag declaration")
|
|
284 ("!entity" . "Entity (macro) declaration"))
|
17432
|
285 "*Alist of tag name and short description."
|
|
286 :type '(repeat (cons (string :tag "Tag Name")
|
|
287 (string :tag "Description")))
|
|
288 :group 'sgml)
|
14159
|
289
|
23726
|
290 (defvar v2) ; free for skeleton
|
|
291
|
14159
|
292 (defun sgml-mode-common (sgml-tag-face-alist sgml-display-text)
|
|
293 "Common code for setting up `sgml-mode' and derived modes.
|
21780
5dc3fe7cd300
(sgml-font-lock-keywords-1): Copy initialization from sgml-font-lock-keywords.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
294 SGML-TAG-FACE-ALIST is used for calculating `sgml-font-lock-keywords-2'.
|
14159
|
295 SGML-DISPLAY-TEXT sets up alternate text for when tags are invisible (see
|
|
296 varables of same name)."
|
|
297 (setq local-abbrev-table text-mode-abbrev-table)
|
|
298 (set-syntax-table sgml-mode-syntax-table)
|
|
299 (make-local-variable 'indent-line-function)
|
|
300 (make-local-variable 'paragraph-start)
|
|
301 (make-local-variable 'paragraph-separate)
|
21971
23bf812d4937
(sgml-mode-common): Make local binding from adaptive-fill-regexp.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
302 (make-local-variable 'adaptive-fill-regexp)
|
14159
|
303 (make-local-variable 'sgml-saved-validate-command)
|
|
304 (make-local-variable 'comment-start)
|
|
305 (make-local-variable 'comment-end)
|
|
306 (make-local-variable 'comment-indent-function)
|
|
307 (make-local-variable 'comment-indent-function)
|
|
308 (make-local-variable 'sgml-tags-invisible)
|
|
309 (make-local-variable 'skeleton-transformation)
|
|
310 (make-local-variable 'skeleton-further-elements)
|
|
311 (make-local-variable 'skeleton-end-hook)
|
|
312 (make-local-variable 'font-lock-defaults)
|
|
313 (make-local-variable 'sgml-font-lock-keywords-1)
|
21780
5dc3fe7cd300
(sgml-font-lock-keywords-1): Copy initialization from sgml-font-lock-keywords.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
314 (make-local-variable 'sgml-font-lock-keywords-2)
|
14159
|
315 (make-local-variable 'facemenu-add-face-function)
|
|
316 (make-local-variable 'facemenu-end-add-face)
|
|
317 ;;(make-local-variable 'facemenu-remove-face-function)
|
|
318 (and sgml-tag-face-alist
|
|
319 (not (assq 1 sgml-tag-face-alist))
|
|
320 (nconc sgml-tag-face-alist
|
|
321 `((1 (,(concat "<\\("
|
|
322 (mapconcat 'car sgml-tag-face-alist "\\|")
|
|
323 "\\)\\([ \t].+\\)?>\\(.+\\)</\\1>")
|
20922
|
324 3 (cdr (assoc (downcase (match-string 1))
|
|
325 ',sgml-tag-face-alist)))))))
|
14159
|
326 (setq indent-line-function 'indent-relative-maybe
|
|
327 ;; A start or end tag by itself on a line separates a paragraph.
|
|
328 ;; This is desirable because SGML discards a newline that appears
|
|
329 ;; immediately after a start tag or immediately before an end tag.
|
19483
51345fa7e08b
(sgml-mode-common): Set paragraph-start like paragraph-separate.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
330 paragraph-separate "[ \t]*$\\|\
|
51345fa7e08b
(sgml-mode-common): Set paragraph-start like paragraph-separate.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
331 \[ \t]*</?\\([A-Za-z]\\([-.A-Za-z0-9= \t\n]\\|\"[^\"]*\"\\|'[^']*'\\)*\\)?>$"
|
51345fa7e08b
(sgml-mode-common): Set paragraph-start like paragraph-separate.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
332 paragraph-start "[ \t]*$\\|\
|
27683
|
333 \[ \t]*</?\\([A-Za-z]\\([-.A-Za-z0-9= \t\n]\\|\"[^\"]*\"\\|'[^']*'\\)*\\)?>"
|
19483
51345fa7e08b
(sgml-mode-common): Set paragraph-start like paragraph-separate.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
334 adaptive-fill-regexp "[ \t]*"
|
14159
|
335 comment-start "<!-- "
|
|
336 comment-end " -->"
|
|
337 comment-indent-function 'sgml-comment-indent
|
17491
|
338 skeleton-transformation sgml-transformation
|
14159
|
339 skeleton-further-elements '((completion-ignore-case t))
|
|
340 skeleton-end-hook (lambda ()
|
|
341 (or (eolp)
|
|
342 (not (or (eq v2 '\n)
|
|
343 (eq (car-safe v2) '\n)))
|
|
344 (newline-and-indent)))
|
21780
5dc3fe7cd300
(sgml-font-lock-keywords-1): Copy initialization from sgml-font-lock-keywords.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
345 sgml-font-lock-keywords-2 (append
|
5dc3fe7cd300
(sgml-font-lock-keywords-1): Copy initialization from sgml-font-lock-keywords.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
346 sgml-font-lock-keywords-1
|
5dc3fe7cd300
(sgml-font-lock-keywords-1): Copy initialization from sgml-font-lock-keywords.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
347 (cdr (assq 1 sgml-tag-face-alist)))
|
14159
|
348 font-lock-defaults '((sgml-font-lock-keywords
|
21780
5dc3fe7cd300
(sgml-font-lock-keywords-1): Copy initialization from sgml-font-lock-keywords.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
349 sgml-font-lock-keywords-1
|
5dc3fe7cd300
(sgml-font-lock-keywords-1): Copy initialization from sgml-font-lock-keywords.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
350 sgml-font-lock-keywords-2)
|
14159
|
351 nil
|
|
352 t)
|
17433
|
353 facemenu-add-face-function 'sgml-mode-facemenu-add-face-function)
|
36609
|
354 ;; This will allow existing comments within declarations to be
|
|
355 ;; recognized.
|
|
356 (set (make-local-variable 'comment-start-skip) "\\(?:<!\\)?--[ \t]*")
|
|
357 (set (make-local-variable 'comment-end-skip) "[ \t]*--\\([ \t\n]*>\\)?")
|
|
358 (dolist (pair sgml-display-text)
|
|
359 (put (car pair) 'before-string (cdr pair))))
|
809
|
360
|
14159
|
361
|
17433
|
362 (defun sgml-mode-facemenu-add-face-function (face end)
|
|
363 (if (setq face (cdr (assq face sgml-face-tag-alist)))
|
|
364 (progn
|
|
365 (setq face (funcall skeleton-transformation face))
|
|
366 (setq facemenu-end-add-face (concat "</" face ">"))
|
|
367 (concat "<" face ">"))
|
|
368 (error "Face not configured for %s mode." mode-name)))
|
|
369
|
|
370
|
14159
|
371 ;;;###autoload
|
36609
|
372 (defun sgml-mode ()
|
14159
|
373 "Major mode for editing SGML documents.
|
|
374 Makes > match <. Makes / blink matching /.
|
14270
|
375 Keys <, &, SPC within <>, \" and ' can be electric depending on
|
|
376 `sgml-quick-keys'.
|
14159
|
377
|
17551
|
378 An argument of N to a tag-inserting command means to wrap it around
|
|
379 the next N words. In Transient Mark mode, when the mark is active,
|
|
380 N defaults to -1, which means to wrap it around the current region.
|
17491
|
381
|
17545
|
382 If you like upcased tags, put (setq sgml-transformation 'upcase) in
|
17551
|
383 your `.emacs' file.
|
14159
|
384
|
|
385 Use \\[sgml-validate] to validate your document with an SGML parser.
|
17491
|
386
|
|
387 Do \\[describe-variable] sgml- SPC to see available variables.
|
|
388 Do \\[describe-key] on the following bindings to discover what they do.
|
14159
|
389 \\{sgml-mode-map}"
|
|
390 (interactive)
|
22772
|
391 (kill-all-local-variables)
|
|
392 (setq mode-name "SGML"
|
|
393 major-mode 'sgml-mode)
|
14159
|
394 (sgml-mode-common sgml-tag-face-alist sgml-display-text)
|
20394
|
395 ;; Set imenu-generic-expression here, rather than in sgml-mode-common,
|
|
396 ;; because this definition probably is not useful in HTML mode.
|
|
397 (make-local-variable 'imenu-generic-expression)
|
|
398 (setq imenu-generic-expression
|
|
399 "<!\\(element\\|entity\\)[ \t\n]+%?[ \t\n]*\\([A-Za-z][-A-Za-z.0-9]*\\)")
|
14159
|
400 (use-local-map sgml-mode-map)
|
22772
|
401 (run-hooks 'text-mode-hook 'sgml-mode-hook))
|
14159
|
402
|
|
403
|
|
404 (defun sgml-comment-indent ()
|
36609
|
405 (if (looking-at "--") comment-column 0))
|
14159
|
406
|
|
407
|
809
|
408
|
|
409 (defun sgml-slash (arg)
|
17551
|
410 "Insert `/' and display any previous matching `/'.
|
|
411 Two `/'s are treated as matching if the first `/' ends a net-enabling
|
|
412 start tag, and the second `/' is the corresponding null end tag."
|
809
|
413 (interactive "p")
|
|
414 (insert-char ?/ arg)
|
|
415 (if (> arg 0)
|
|
416 (let ((oldpos (point))
|
|
417 (blinkpos)
|
|
418 (level 0))
|
|
419 (save-excursion
|
|
420 (save-restriction
|
|
421 (if sgml-slash-distance
|
|
422 (narrow-to-region (max (point-min)
|
|
423 (- (point) sgml-slash-distance))
|
|
424 oldpos))
|
|
425 (if (and (re-search-backward sgml-start-tag-regex (point-min) t)
|
|
426 (eq (match-end 0) (1- oldpos)))
|
|
427 ()
|
|
428 (goto-char (1- oldpos))
|
|
429 (while (and (not blinkpos)
|
|
430 (search-backward "/" (point-min) t))
|
|
431 (let ((tagend (save-excursion
|
|
432 (if (re-search-backward sgml-start-tag-regex
|
|
433 (point-min) t)
|
|
434 (match-end 0)
|
|
435 nil))))
|
|
436 (if (eq tagend (point))
|
|
437 (if (eq level 0)
|
|
438 (setq blinkpos (point))
|
|
439 (setq level (1- level)))
|
|
440 (setq level (1+ level)))))))
|
|
441 (if blinkpos
|
|
442 (progn
|
|
443 (goto-char blinkpos)
|
|
444 (if (pos-visible-in-window-p)
|
|
445 (sit-for 1)
|
|
446 (message "Matches %s"
|
|
447 (buffer-substring (progn
|
|
448 (beginning-of-line)
|
|
449 (point))
|
|
450 (1+ blinkpos))))))))))
|
|
451
|
14159
|
452
|
|
453 (defun sgml-name-char (&optional char)
|
|
454 "Insert a symbolic character name according to `sgml-char-names'.
|
|
455 8 bit chars may be inserted with the meta key as in M-SPC for no break space,
|
|
456 or M-- for a soft hyphen."
|
|
457 (interactive "*")
|
|
458 (insert ?&)
|
|
459 (or char
|
17500
|
460 (setq char (read-quoted-char "Enter char or octal number")))
|
14159
|
461 (delete-backward-char 1)
|
|
462 (insert char)
|
|
463 (undo-boundary)
|
|
464 (delete-backward-char 1)
|
|
465 (insert ?&
|
|
466 (or (aref sgml-char-names char)
|
|
467 (format "#%d" char))
|
|
468 ?\;))
|
|
469
|
|
470
|
|
471 (defun sgml-name-self ()
|
|
472 "Insert a symbolic character name according to `sgml-char-names'."
|
|
473 (interactive "*")
|
|
474 (sgml-name-char last-command-char))
|
|
475
|
|
476
|
|
477 (defun sgml-maybe-name-self ()
|
|
478 "Insert a symbolic character name according to `sgml-char-names'."
|
|
479 (interactive "*")
|
|
480 (if sgml-name-8bit-mode
|
|
481 (sgml-name-char last-command-char)
|
|
482 (self-insert-command 1)))
|
|
483
|
|
484
|
|
485 (defun sgml-name-8bit-mode ()
|
|
486 "Toggle insertion of 8 bit characters."
|
|
487 (interactive)
|
17545
|
488 (setq sgml-name-8bit-mode (not sgml-name-8bit-mode))
|
23652
|
489 (message "sgml name 8 bit mode is now %s"
|
17545
|
490 (if sgml-name-8bit-mode "ON" "OFF")))
|
14159
|
491
|
|
492
|
17551
|
493 ;; When an element of a skeleton is a string "str", it is passed
|
|
494 ;; through skeleton-transformation and inserted. If "str" is to be
|
|
495 ;; inserted literally, one should obtain it as the return value of a
|
|
496 ;; function, e.g. (identity "str").
|
14159
|
497
|
|
498 (define-skeleton sgml-tag
|
17551
|
499 "Prompt for a tag and insert it, optionally with attributes.
|
|
500 Completion and configuration are done according to `sgml-tag-alist'.
|
17545
|
501 If you like tags and attributes in uppercase do \\[set-variable]
|
17551
|
502 skeleton-transformation RET upcase RET, or put this in your `.emacs':
|
|
503 (setq sgml-transformation 'upcase)"
|
37252
|
504 (funcall skeleton-transformation
|
|
505 (completing-read "Tag: " sgml-tag-alist))
|
36609
|
506 ?< str |
|
17545
|
507 (("") -1 '(undo-boundary) (identity "<")) | ; see comment above
|
36609
|
508 `(("") '(setq v2 (sgml-attributes ,str t)) ?>
|
|
509 (if (string= "![" ,str)
|
|
510 (prog1 '(("") " [ " _ " ]]")
|
|
511 (backward-char))
|
|
512 (if (or (eq v2 t)
|
|
513 (string-match "^[/!?]" ,str))
|
|
514 ()
|
|
515 (if (symbolp v2)
|
37252
|
516 ;; We go use `identity' to prevent skeleton from passing
|
|
517 ;; `str' through skeleton-transformation a second time.
|
|
518 '(("") v2 _ v2 "</" (identity ',str) ?>)
|
36609
|
519 (if (eq (car v2) t)
|
|
520 (cons '("") (cdr v2))
|
|
521 (append '(("") (car v2))
|
|
522 (cdr v2)
|
37252
|
523 '(resume: (car v2) _ "</" (identity ',str) ?>))))))))
|
14159
|
524
|
|
525 (autoload 'skeleton-read "skeleton")
|
|
526
|
17545
|
527 (defun sgml-attributes (tag &optional quiet)
|
17551
|
528 "When at top level of a tag, interactively insert attributes.
|
17545
|
529
|
17551
|
530 Completion and configuration of TAG are done according to `sgml-tag-alist'.
|
|
531 If QUIET, do not print a message when there are no attributes for TAG."
|
14159
|
532 (interactive (list (save-excursion (sgml-beginning-of-tag t))))
|
17545
|
533 (or (stringp tag) (error "Wrong context for adding attribute"))
|
|
534 (if tag
|
14159
|
535 (let ((completion-ignore-case t)
|
17545
|
536 (alist (cdr (assoc (downcase tag) sgml-tag-alist)))
|
14159
|
537 car attribute i)
|
|
538 (if (or (symbolp (car alist))
|
|
539 (symbolp (car (car alist))))
|
|
540 (setq car (car alist)
|
|
541 alist (cdr alist)))
|
|
542 (or quiet
|
|
543 (message "No attributes configured."))
|
|
544 (if (stringp (car alist))
|
|
545 (progn
|
17545
|
546 (insert (if (eq (preceding-char) ? ) "" ? )
|
|
547 (funcall skeleton-transformation (car alist)))
|
14159
|
548 (sgml-value alist))
|
|
549 (setq i (length alist))
|
|
550 (while (> i 0)
|
|
551 (insert ? )
|
|
552 (insert (funcall skeleton-transformation
|
|
553 (setq attribute
|
|
554 (skeleton-read '(completing-read
|
17545
|
555 "Attribute: "
|
14159
|
556 alist)))))
|
|
557 (if (string= "" attribute)
|
|
558 (setq i 0)
|
20922
|
559 (sgml-value (assoc (downcase attribute) alist))
|
14159
|
560 (setq i (1- i))))
|
|
561 (if (eq (preceding-char) ? )
|
|
562 (delete-backward-char 1)))
|
|
563 car)))
|
|
564
|
|
565 (defun sgml-auto-attributes (arg)
|
17551
|
566 "Self insert the character typed; at top level of tag, prompt for attributes.
|
|
567 With prefix argument, only self insert."
|
14159
|
568 (interactive "*P")
|
|
569 (let ((point (point))
|
|
570 tag)
|
|
571 (if (or arg
|
|
572 (not sgml-tag-alist) ; no message when nothing configured
|
|
573 (symbolp (setq tag (save-excursion (sgml-beginning-of-tag t))))
|
|
574 (eq (aref tag 0) ?/))
|
|
575 (self-insert-command (prefix-numeric-value arg))
|
|
576 (sgml-attributes tag)
|
|
577 (setq last-command-char ? )
|
|
578 (or (> (point) point)
|
|
579 (self-insert-command 1)))))
|
|
580
|
|
581
|
|
582 (defun sgml-tag-help (&optional tag)
|
17551
|
583 "Display description of tag TAG. If TAG is omitted, use the tag at point."
|
14159
|
584 (interactive)
|
|
585 (or tag
|
|
586 (save-excursion
|
|
587 (if (eq (following-char) ?<)
|
|
588 (forward-char))
|
|
589 (setq tag (sgml-beginning-of-tag))))
|
|
590 (or (stringp tag)
|
|
591 (error "No tag selected"))
|
|
592 (setq tag (downcase tag))
|
14328
|
593 (message "%s"
|
20922
|
594 (or (cdr (assoc (downcase tag) sgml-tag-help))
|
14159
|
595 (and (eq (aref tag 0) ?/)
|
20922
|
596 (cdr (assoc (downcase (substring tag 1)) sgml-tag-help)))
|
14159
|
597 "No description available")))
|
|
598
|
|
599
|
|
600 (defun sgml-maybe-end-tag ()
|
|
601 "Name self unless in position to end a tag."
|
|
602 (interactive)
|
|
603 (or (condition-case nil
|
|
604 (save-excursion (up-list -1))
|
|
605 (error
|
|
606 (sgml-name-self)
|
|
607 t))
|
|
608 (condition-case nil
|
|
609 (progn
|
|
610 (save-excursion (up-list 1))
|
|
611 (sgml-name-self))
|
|
612 (error (self-insert-command 1)))))
|
|
613
|
|
614
|
|
615 (defun sgml-skip-tag-backward (arg)
|
|
616 "Skip to beginning of tag or matching opening tag if present.
|
17551
|
617 With prefix argument ARG, repeat this ARG times."
|
14159
|
618 (interactive "p")
|
|
619 (while (>= arg 1)
|
|
620 (search-backward "<" nil t)
|
|
621 (if (looking-at "</\\([^ \n\t>]+\\)")
|
|
622 ;; end tag, skip any nested pairs
|
|
623 (let ((case-fold-search t)
|
|
624 (re (concat "</?" (regexp-quote (match-string 1)))))
|
|
625 (while (and (re-search-backward re nil t)
|
|
626 (eq (char-after (1+ (point))) ?/))
|
|
627 (forward-char 1)
|
|
628 (sgml-skip-tag-backward 1))))
|
|
629 (setq arg (1- arg))))
|
|
630
|
|
631 (defun sgml-skip-tag-forward (arg &optional return)
|
|
632 "Skip to end of tag or matching closing tag if present.
|
17551
|
633 With prefix argument ARG, repeat this ARG times.
|
14159
|
634 Return t iff after a closing tag."
|
|
635 (interactive "p")
|
|
636 (setq return t)
|
|
637 (while (>= arg 1)
|
|
638 (skip-chars-forward "^<>")
|
|
639 (if (eq (following-char) ?>)
|
|
640 (up-list -1))
|
|
641 (if (looking-at "<\\([^/ \n\t>]+\\)")
|
|
642 ;; start tag, skip any nested same pairs _and_ closing tag
|
|
643 (let ((case-fold-search t)
|
|
644 (re (concat "</?" (regexp-quote (match-string 1))))
|
|
645 point close)
|
|
646 (forward-list 1)
|
|
647 (setq point (point))
|
|
648 (while (and (re-search-forward re nil t)
|
|
649 (not (setq close
|
|
650 (eq (char-after (1+ (match-beginning 0))) ?/)))
|
|
651 (not (up-list -1))
|
|
652 (sgml-skip-tag-forward 1))
|
|
653 (setq close nil))
|
|
654 (if close
|
|
655 (up-list 1)
|
|
656 (goto-char point)
|
|
657 (setq return)))
|
|
658 (forward-list 1))
|
|
659 (setq arg (1- arg)))
|
|
660 return)
|
|
661
|
|
662 (defun sgml-delete-tag (arg)
|
|
663 "Delete tag on or after cursor, and matching closing or opening tag.
|
17551
|
664 With prefix argument ARG, repeat this ARG times."
|
14159
|
665 (interactive "p")
|
|
666 (while (>= arg 1)
|
|
667 (save-excursion
|
|
668 (let* (close open)
|
14270
|
669 (if (looking-at "[ \t\n]*<")
|
14159
|
670 ;; just before tag
|
|
671 (if (eq (char-after (match-end 0)) ?/)
|
|
672 ;; closing tag
|
|
673 (progn
|
|
674 (setq close (point))
|
|
675 (goto-char (match-end 0))))
|
|
676 ;; on tag?
|
|
677 (or (save-excursion (setq close (sgml-beginning-of-tag)
|
|
678 close (and (stringp close)
|
|
679 (eq (aref close 0) ?/)
|
|
680 (point))))
|
|
681 ;; not on closing tag
|
|
682 (let ((point (point)))
|
|
683 (sgml-skip-tag-backward 1)
|
|
684 (if (or (not (eq (following-char) ?<))
|
|
685 (save-excursion
|
|
686 (forward-list 1)
|
|
687 (<= (point) point)))
|
|
688 (error "Not on or before tag")))))
|
|
689 (if close
|
|
690 (progn
|
|
691 (sgml-skip-tag-backward 1)
|
|
692 (setq open (point))
|
|
693 (goto-char close)
|
|
694 (kill-sexp 1))
|
|
695 (setq open (point))
|
|
696 (sgml-skip-tag-forward 1)
|
|
697 (backward-list)
|
|
698 (forward-char)
|
|
699 (if (eq (aref (sgml-beginning-of-tag) 0) ?/)
|
|
700 (kill-sexp 1)))
|
|
701 (goto-char open)
|
|
702 (kill-sexp 1)))
|
|
703 (setq arg (1- arg))))
|
17491
|
704
|
|
705 ;; Put read-only last to enable setting this even when read-only enabled.
|
|
706 (or (get 'sgml-tag 'invisible)
|
|
707 (setplist 'sgml-tag
|
|
708 (append '(invisible t
|
|
709 intangible t
|
|
710 point-entered sgml-point-entered
|
|
711 rear-nonsticky t
|
|
712 read-only t)
|
|
713 (symbol-plist 'sgml-tag))))
|
14159
|
714
|
|
715 (defun sgml-tags-invisible (arg)
|
|
716 "Toggle visibility of existing tags."
|
|
717 (interactive "P")
|
|
718 (let ((modified (buffer-modified-p))
|
|
719 (inhibit-read-only t)
|
17491
|
720 ;; This is needed in case font lock gets called,
|
|
721 ;; since it moves point and might call sgml-point-entered.
|
|
722 (inhibit-point-motion-hooks t)
|
14159
|
723 symbol)
|
|
724 (save-excursion
|
17491
|
725 (goto-char (point-min))
|
14159
|
726 (if (setq sgml-tags-invisible
|
|
727 (if arg
|
|
728 (>= (prefix-numeric-value arg) 0)
|
|
729 (not sgml-tags-invisible)))
|
|
730 (while (re-search-forward "<\\([!/?A-Za-z][-A-Za-z0-9]*\\)"
|
|
731 nil t)
|
|
732 (setq symbol (intern-soft (downcase (match-string 1))))
|
|
733 (goto-char (match-beginning 0))
|
|
734 (and (get symbol 'before-string)
|
|
735 (not (overlays-at (point)))
|
|
736 (overlay-put (make-overlay (point)
|
|
737 (match-beginning 1))
|
|
738 'category symbol))
|
17491
|
739 (put-text-property (point)
|
|
740 (progn (forward-list) (point))
|
14159
|
741 'category 'sgml-tag))
|
17491
|
742 (let ((pos (point)))
|
|
743 (while (< (setq pos (next-overlay-change pos)) (point-max))
|
|
744 (delete-overlay (car (overlays-at pos)))))
|
14159
|
745 (remove-text-properties (point-min) (point-max)
|
|
746 '(category sgml-tag intangible t))))
|
|
747 (set-buffer-modified-p modified)
|
|
748 (run-hooks 'sgml-tags-invisible-hook)
|
|
749 (message "")))
|
|
750
|
|
751 (defun sgml-point-entered (x y)
|
|
752 ;; Show preceding or following hidden tag, depending of cursor direction.
|
|
753 (let ((inhibit-point-motion-hooks t))
|
|
754 (save-excursion
|
|
755 (message "Invisible tag: %s"
|
|
756 (buffer-substring
|
|
757 (point)
|
|
758 (if (or (and (> x y)
|
|
759 (not (eq (following-char) ?<)))
|
|
760 (and (< x y)
|
|
761 (eq (preceding-char) ?>)))
|
|
762 (backward-list)
|
|
763 (forward-list)))))))
|
17491
|
764
|
14159
|
765 (autoload 'compile-internal "compile")
|
|
766
|
809
|
767 (defun sgml-validate (command)
|
|
768 "Validate an SGML document.
|
|
769 Runs COMMAND, a shell command, in a separate process asynchronously
|
17551
|
770 with output going to the buffer `*compilation*'.
|
809
|
771 You can then use the command \\[next-error] to find the next error message
|
|
772 and move to the line in the SGML document that caused it."
|
|
773 (interactive
|
|
774 (list (read-string "Validate command: "
|
|
775 (or sgml-saved-validate-command
|
|
776 (concat sgml-validate-command
|
|
777 " "
|
|
778 (let ((name (buffer-file-name)))
|
|
779 (and name
|
|
780 (file-name-nondirectory name))))))))
|
|
781 (setq sgml-saved-validate-command command)
|
23970
|
782 (save-some-buffers (not compilation-ask-about-save) nil)
|
3121
|
783 (compile-internal command "No more errors"))
|
809
|
784
|
14159
|
785
|
|
786 (defun sgml-beginning-of-tag (&optional top-level)
|
|
787 "Skip to beginning of tag and return its name.
|
17551
|
788 If this can't be done, return t."
|
14159
|
789 (or (if top-level
|
|
790 (condition-case nil
|
|
791 (up-list -1)
|
|
792 (error t))
|
|
793 (>= (point)
|
|
794 (if (search-backward "<" nil t)
|
|
795 (save-excursion
|
|
796 (forward-list)
|
|
797 (point))
|
|
798 0)))
|
|
799 (if (looking-at "<[!?/]?[[A-Za-z][A-Za-z0-9]*")
|
|
800 (buffer-substring-no-properties
|
|
801 (1+ (point))
|
|
802 (match-end 0))
|
|
803 t)))
|
|
804
|
|
805 (defun sgml-value (alist)
|
17551
|
806 "Interactively insert value taken from attributerule ALIST.
|
|
807 See `sgml-tag-alist' for info about attributerules.."
|
14159
|
808 (setq alist (cdr alist))
|
|
809 (if (stringp (car alist))
|
|
810 (insert "=\"" (car alist) ?\")
|
|
811 (if (eq (car alist) t)
|
|
812 (if (cdr alist)
|
|
813 (progn
|
|
814 (insert "=\"")
|
|
815 (setq alist (skeleton-read '(completing-read
|
17545
|
816 "Value: " (cdr alist))))
|
14159
|
817 (if (string< "" alist)
|
17491
|
818 (insert alist ?\")
|
14159
|
819 (delete-backward-char 2))))
|
|
820 (insert "=\"")
|
|
821 (if alist
|
17491
|
822 (insert (skeleton-read '(completing-read "Value: " alist))))
|
14159
|
823 (insert ?\"))))
|
|
824
|
|
825 (provide 'sgml-mode)
|
|
826
|
25175
|
827 (defcustom html-mode-hook nil
|
|
828 "Hook run by command `html-mode'.
|
|
829 `text-mode-hook' and `sgml-mode-hook' are run first."
|
|
830 :group 'sgml
|
|
831 :type 'hook
|
|
832 :options '(html-autoview-mode))
|
|
833
|
14270
|
834 (defvar html-quick-keys sgml-quick-keys
|
14377
|
835 "Use C-c X combinations for quick insertion of frequent tags when non-nil.
|
14270
|
836 This defaults to `sgml-quick-keys'.
|
14159
|
837 This takes effect when first loading the library.")
|
|
838
|
|
839 (defvar html-mode-map
|
37252
|
840 (let ((map (make-sparse-keymap))
|
14159
|
841 (menu-map (make-sparse-keymap "HTML")))
|
37252
|
842 (set-keymap-parent map sgml-mode-map)
|
15437
|
843 (define-key map "\C-c6" 'html-headline-6)
|
|
844 (define-key map "\C-c5" 'html-headline-5)
|
|
845 (define-key map "\C-c4" 'html-headline-4)
|
|
846 (define-key map "\C-c3" 'html-headline-3)
|
|
847 (define-key map "\C-c2" 'html-headline-2)
|
|
848 (define-key map "\C-c1" 'html-headline-1)
|
14270
|
849 (define-key map "\C-c\r" 'html-paragraph)
|
|
850 (define-key map "\C-c\n" 'html-line)
|
|
851 (define-key map "\C-c\C-c-" 'html-horizontal-rule)
|
15437
|
852 (define-key map "\C-c\C-co" 'html-ordered-list)
|
|
853 (define-key map "\C-c\C-cu" 'html-unordered-list)
|
14270
|
854 (define-key map "\C-c\C-cr" 'html-radio-buttons)
|
|
855 (define-key map "\C-c\C-cc" 'html-checkboxes)
|
|
856 (define-key map "\C-c\C-cl" 'html-list-item)
|
|
857 (define-key map "\C-c\C-ch" 'html-href-anchor)
|
|
858 (define-key map "\C-c\C-cn" 'html-name-anchor)
|
|
859 (define-key map "\C-c\C-ci" 'html-image)
|
14159
|
860 (if html-quick-keys
|
|
861 (progn
|
|
862 (define-key map "\C-c-" 'html-horizontal-rule)
|
15437
|
863 (define-key map "\C-co" 'html-ordered-list)
|
|
864 (define-key map "\C-cu" 'html-unordered-list)
|
14159
|
865 (define-key map "\C-cr" 'html-radio-buttons)
|
14270
|
866 (define-key map "\C-cc" 'html-checkboxes)
|
14159
|
867 (define-key map "\C-cl" 'html-list-item)
|
|
868 (define-key map "\C-ch" 'html-href-anchor)
|
|
869 (define-key map "\C-cn" 'html-name-anchor)
|
|
870 (define-key map "\C-ci" 'html-image)))
|
|
871 (define-key map "\C-c\C-s" 'html-autoview-mode)
|
|
872 (define-key map "\C-c\C-v" 'browse-url-of-buffer)
|
|
873 (define-key map [menu-bar html] (cons "HTML" menu-map))
|
|
874 (define-key menu-map [html-autoview-mode]
|
|
875 '("Toggle Autoviewing" . html-autoview-mode))
|
|
876 (define-key menu-map [browse-url-of-buffer]
|
|
877 '("View Buffer Contents" . browse-url-of-buffer))
|
|
878 (define-key menu-map [nil] '("--"))
|
15437
|
879 ;;(define-key menu-map "6" '("Heading 6" . html-headline-6))
|
|
880 ;;(define-key menu-map "5" '("Heading 5" . html-headline-5))
|
|
881 ;;(define-key menu-map "4" '("Heading 4" . html-headline-4))
|
|
882 (define-key menu-map "3" '("Heading 3" . html-headline-3))
|
|
883 (define-key menu-map "2" '("Heading 2" . html-headline-2))
|
|
884 (define-key menu-map "1" '("Heading 1" . html-headline-1))
|
14159
|
885 (define-key menu-map "l" '("Radio Buttons" . html-radio-buttons))
|
14270
|
886 (define-key menu-map "c" '("Checkboxes" . html-checkboxes))
|
14159
|
887 (define-key menu-map "l" '("List Item" . html-list-item))
|
15437
|
888 (define-key menu-map "u" '("Unordered List" . html-unordered-list))
|
|
889 (define-key menu-map "o" '("Ordered List" . html-ordered-list))
|
14270
|
890 (define-key menu-map "-" '("Horizontal Rule" . html-horizontal-rule))
|
14159
|
891 (define-key menu-map "\n" '("Line Break" . html-line))
|
|
892 (define-key menu-map "\r" '("Paragraph" . html-paragraph))
|
|
893 (define-key menu-map "i" '("Image" . html-image))
|
|
894 (define-key menu-map "h" '("Href Anchor" . html-href-anchor))
|
|
895 (define-key menu-map "n" '("Name Anchor" . html-name-anchor))
|
|
896 map)
|
|
897 "Keymap for commands for use in HTML mode.")
|
|
898
|
|
899
|
|
900 (defvar html-face-tag-alist
|
|
901 '((bold . "b")
|
|
902 (italic . "i")
|
|
903 (underline . "u")
|
|
904 (modeline . "rev"))
|
|
905 "Value of `sgml-face-tag-alist' for HTML mode.")
|
|
906
|
|
907 (defvar html-tag-face-alist
|
|
908 '(("b" . bold)
|
|
909 ("big" . bold)
|
|
910 ("blink" . highlight)
|
|
911 ("cite" . italic)
|
|
912 ("em" . italic)
|
|
913 ("h1" bold underline)
|
|
914 ("h2" bold-italic underline)
|
|
915 ("h3" italic underline)
|
|
916 ("h4" . underline)
|
|
917 ("h5" . underline)
|
|
918 ("h6" . underline)
|
|
919 ("i" . italic)
|
|
920 ("rev" . modeline)
|
|
921 ("s" . underline)
|
|
922 ("small" . default)
|
|
923 ("strong" . bold)
|
|
924 ("title" bold underline)
|
|
925 ("tt" . default)
|
|
926 ("u" . underline)
|
|
927 ("var" . italic))
|
|
928 "Value of `sgml-tag-face-alist' for HTML mode.")
|
|
929
|
|
930
|
|
931 (defvar html-display-text
|
|
932 '((img . "[/]")
|
|
933 (hr . "----------")
|
|
934 (li . "o "))
|
|
935 "Value of `sgml-display-text' for HTML mode.")
|
22629
|
936
|
|
937 ;; should code exactly HTML 3 here when that is finished
|
14159
|
938 (defvar html-tag-alist
|
17545
|
939 (let* ((1-7 '(("1") ("2") ("3") ("4") ("5") ("6") ("7")))
|
|
940 (1-9 '(,@1-7 ("8") ("9")))
|
14159
|
941 (align '(("align" ("left") ("center") ("right"))))
|
|
942 (valign '(("top") ("middle") ("bottom") ("baseline")))
|
|
943 (rel '(("next") ("previous") ("parent") ("subdocument") ("made")))
|
|
944 (href '("href" ("ftp:") ("file:") ("finger:") ("gopher:") ("http:")
|
|
945 ("mailto:") ("news:") ("rlogin:") ("telnet:") ("tn3270:")
|
14270
|
946 ("wais:") ("/cgi-bin/")))
|
14159
|
947 (name '("name"))
|
|
948 (link `(,href
|
|
949 ("rel" ,@rel)
|
|
950 ("rev" ,@rel)
|
|
951 ("title")))
|
17545
|
952 (list '((nil \n ( "List item: "
|
|
953 "<li>" str \n))))
|
14159
|
954 (cell `(t
|
|
955 ,align
|
|
956 ("valign" ,@valign)
|
|
957 ("colspan" ,@1-9)
|
|
958 ("rowspan" ,@1-9)
|
|
959 ("nowrap" t))))
|
|
960 ;; put ,-expressions first, else byte-compile chokes (as of V19.29)
|
|
961 ;; and like this it's more efficient anyway
|
|
962 `(("a" ,name ,@link)
|
|
963 ("base" t ,@href)
|
|
964 ("dir" ,@list)
|
17545
|
965 ("font" nil "size" ("-1") ("+1") ("-2") ("+2") ,@1-7)
|
14270
|
966 ("form" (\n _ \n "<input type=\"submit\" value=\"\">")
|
|
967 ("action" ,@(cdr href)) ("method" ("get") ("post")))
|
14159
|
968 ("h1" ,@align)
|
|
969 ("h2" ,@align)
|
|
970 ("h3" ,@align)
|
|
971 ("h4" ,@align)
|
|
972 ("h5" ,@align)
|
|
973 ("h6" ,@align)
|
|
974 ("hr" t ("size" ,@1-9) ("width") ("noshade" t) ,@align)
|
|
975 ("img" t ("align" ,@valign ("texttop") ("absmiddle") ("absbottom"))
|
|
976 ("src") ("alt") ("width" "1") ("height" "1")
|
|
977 ("border" "1") ("vspace" "1") ("hspace" "1") ("ismap" t))
|
|
978 ("input" t ("size" ,@1-9) ("maxlength" ,@1-9) ("checked" t) ,name
|
14270
|
979 ("type" ("text") ("password") ("checkbox") ("radio")
|
|
980 ("submit") ("reset"))
|
14159
|
981 ("value"))
|
|
982 ("link" t ,@link)
|
|
983 ("menu" ,@list)
|
17545
|
984 ("ol" ,@list ("type" ("A") ("a") ("I") ("i") ("1")))
|
14159
|
985 ("p" t ,@align)
|
|
986 ("select" (nil \n
|
|
987 ("Text: "
|
|
988 "<option>" str \n))
|
|
989 ,name ("size" ,@1-9) ("multiple" t))
|
|
990 ("table" (nil \n
|
|
991 ((completing-read "Cell kind: " '(("td") ("th"))
|
|
992 nil t "t")
|
|
993 "<tr><" str ?> _ \n))
|
|
994 ("border" t ,@1-9) ("width" "10") ("cellpadding"))
|
|
995 ("td" ,@cell)
|
|
996 ("textarea" ,name ("rows" ,@1-9) ("cols" ,@1-9))
|
|
997 ("th" ,@cell)
|
17545
|
998 ("ul" ,@list ("type" ("disc") ("circle") ("square")))
|
14159
|
999
|
|
1000 ,@sgml-tag-alist
|
|
1001
|
|
1002 ("abbrev")
|
|
1003 ("acronym")
|
|
1004 ("address")
|
|
1005 ("array" (nil \n
|
|
1006 ("Item: " "<item>" str \n))
|
|
1007 "align")
|
|
1008 ("au")
|
|
1009 ("b")
|
|
1010 ("big")
|
|
1011 ("blink")
|
|
1012 ("blockquote" \n)
|
|
1013 ("body" \n ("background" ".gif") ("bgcolor" "#") ("text" "#")
|
|
1014 ("link" "#") ("alink" "#") ("vlink" "#"))
|
|
1015 ("box" (nil _ "<over>" _))
|
|
1016 ("br" t ("clear" ("left") ("right")))
|
|
1017 ("caption" ("valign" ("top") ("bottom")))
|
|
1018 ("center" \n)
|
|
1019 ("cite")
|
|
1020 ("code" \n)
|
|
1021 ("dd" t)
|
|
1022 ("del")
|
|
1023 ("dfn")
|
|
1024 ("dl" (nil \n
|
|
1025 ( "Term: "
|
|
1026 "<dt>" str "<dd>" _ \n)))
|
|
1027 ("dt" (t _ "<dd>"))
|
|
1028 ("em")
|
17545
|
1029 ;("fn" "id" "fn") ; ???
|
14159
|
1030 ("head" \n)
|
|
1031 ("html" (\n
|
|
1032 "<head>\n"
|
|
1033 "<title>" (setq str (read-input "Title: ")) "</title>\n"
|
24413
|
1034 "</head>\n"
|
14159
|
1035 "<body>\n<h1>" str "</h1>\n" _
|
|
1036 "\n<address>\n<a href=\"mailto:"
|
14518
|
1037 user-mail-address
|
24413
|
1038 "\">" (user-full-name) "</a>\n</address>\n"
|
|
1039 "</body>"
|
|
1040 ))
|
14159
|
1041 ("i")
|
|
1042 ("ins")
|
|
1043 ("isindex" t ("action") ("prompt"))
|
|
1044 ("kbd")
|
|
1045 ("lang")
|
|
1046 ("li" t)
|
|
1047 ("math" \n)
|
|
1048 ("nobr")
|
|
1049 ("option" t ("value") ("label") ("selected" t))
|
|
1050 ("over" t)
|
|
1051 ("person")
|
|
1052 ("pre" \n)
|
|
1053 ("q")
|
|
1054 ("rev")
|
|
1055 ("s")
|
|
1056 ("samp")
|
|
1057 ("small")
|
|
1058 ("strong")
|
|
1059 ("sub")
|
|
1060 ("sup")
|
|
1061 ("title")
|
|
1062 ("tr" t)
|
|
1063 ("tt")
|
|
1064 ("u")
|
|
1065 ("var")
|
|
1066 ("wbr" t)))
|
|
1067 "*Value of `sgml-tag-alist' for HTML mode.")
|
|
1068
|
|
1069 (defvar html-tag-help
|
|
1070 `(,@sgml-tag-help
|
|
1071 ("a" . "Anchor of point or link elsewhere")
|
|
1072 ("abbrev" . "?")
|
|
1073 ("acronym" . "?")
|
|
1074 ("address" . "Formatted mail address")
|
|
1075 ("array" . "Math array")
|
|
1076 ("au" . "?")
|
|
1077 ("b" . "Bold face")
|
|
1078 ("base" . "Base address for URLs")
|
|
1079 ("big" . "Font size")
|
|
1080 ("blink" . "Blinking text")
|
|
1081 ("blockquote" . "Indented quotation")
|
|
1082 ("body" . "Document body")
|
|
1083 ("box" . "Math fraction")
|
|
1084 ("br" . "Line break")
|
|
1085 ("caption" . "Table caption")
|
|
1086 ("center" . "Centered text")
|
|
1087 ("changed" . "Change bars")
|
|
1088 ("cite" . "Citation of a document")
|
|
1089 ("code" . "Formatted source code")
|
|
1090 ("dd" . "Definition of term")
|
|
1091 ("del" . "?")
|
|
1092 ("dfn" . "?")
|
|
1093 ("dir" . "Directory list (obsolete)")
|
|
1094 ("dl" . "Definition list")
|
|
1095 ("dt" . "Term to be definined")
|
|
1096 ("em" . "Emphasised")
|
|
1097 ("embed" . "Embedded data in foreign format")
|
|
1098 ("fig" . "Figure")
|
|
1099 ("figa" . "Figure anchor")
|
|
1100 ("figd" . "Figure description")
|
|
1101 ("figt" . "Figure text")
|
17545
|
1102 ;("fn" . "?") ; ???
|
14159
|
1103 ("font" . "Font size")
|
|
1104 ("form" . "Form with input fields")
|
|
1105 ("group" . "Document grouping")
|
|
1106 ("h1" . "Most important section headline")
|
|
1107 ("h2" . "Important section headline")
|
|
1108 ("h3" . "Section headline")
|
|
1109 ("h4" . "Minor section headline")
|
|
1110 ("h5" . "Unimportant section headline")
|
|
1111 ("h6" . "Least important section headline")
|
|
1112 ("head" . "Document header")
|
|
1113 ("hr" . "Horizontal rule")
|
|
1114 ("html" . "HTML Document")
|
|
1115 ("i" . "Italic face")
|
|
1116 ("img" . "Graphic image")
|
|
1117 ("input" . "Form input field")
|
|
1118 ("ins" . "?")
|
|
1119 ("isindex" . "Input field for index search")
|
|
1120 ("kbd" . "Keybard example face")
|
|
1121 ("lang" . "Natural language")
|
|
1122 ("li" . "List item")
|
|
1123 ("link" . "Link relationship")
|
|
1124 ("math" . "Math formula")
|
|
1125 ("menu" . "Menu list (obsolete)")
|
|
1126 ("mh" . "Form mail header")
|
|
1127 ("nextid" . "Allocate new id")
|
|
1128 ("nobr" . "Text without line break")
|
|
1129 ("ol" . "Ordered list")
|
|
1130 ("option" . "Selection list item")
|
|
1131 ("over" . "Math fraction rule")
|
|
1132 ("p" . "Paragraph start")
|
|
1133 ("panel" . "Floating panel")
|
|
1134 ("person" . "?")
|
|
1135 ("pre" . "Preformatted fixed width text")
|
|
1136 ("q" . "?")
|
|
1137 ("rev" . "Reverse video")
|
|
1138 ("s" . "?")
|
|
1139 ("samp" . "Sample text")
|
|
1140 ("select" . "Selection list")
|
|
1141 ("small" . "Font size")
|
|
1142 ("sp" . "Nobreak space")
|
|
1143 ("strong" . "Standout text")
|
|
1144 ("sub" . "Subscript")
|
|
1145 ("sup" . "Superscript")
|
|
1146 ("table" . "Table with rows and columns")
|
|
1147 ("tb" . "Table vertical break")
|
|
1148 ("td" . "Table data cell")
|
|
1149 ("textarea" . "Form multiline edit area")
|
|
1150 ("th" . "Table header cell")
|
|
1151 ("title" . "Document title")
|
|
1152 ("tr" . "Table row separator")
|
|
1153 ("tt" . "Typewriter face")
|
|
1154 ("u" . "Underlined text")
|
|
1155 ("ul" . "Unordered list")
|
|
1156 ("var" . "Math variable face")
|
|
1157 ("wbr" . "Enable <br> within <nobr>"))
|
|
1158 "*Value of `sgml-tag-help' for HTML mode.")
|
22629
|
1159
|
14159
|
1160 ;;;###autoload
|
|
1161 (defun html-mode ()
|
|
1162 "Major mode based on SGML mode for editing HTML documents.
|
23652
|
1163 This allows inserting skeleton constructs used in hypertext documents with
|
14270
|
1164 completion. See below for an introduction to HTML. Use
|
|
1165 \\[browse-url-of-buffer] to see how this comes out. See also `sgml-mode' on
|
|
1166 which this is based.
|
14159
|
1167
|
14270
|
1168 Do \\[describe-variable] html- SPC and \\[describe-variable] sgml- SPC to see available variables.
|
14159
|
1169
|
|
1170 To write fairly well formatted pages you only need to know few things. Most
|
|
1171 browsers have a function to read the source code of the page being seen, so
|
|
1172 you can imitate various tricks. Here's a very short HTML primer which you
|
|
1173 can also view with a browser to see what happens:
|
|
1174
|
|
1175 <title>A Title Describing Contents</title> should be on every page. Pages can
|
|
1176 have <h1>Very Major Headlines</h1> through <h6>Very Minor Headlines</h6>
|
|
1177 <hr> Parts can be separated with horizontal rules.
|
|
1178
|
|
1179 <p>Paragraphs only need an opening tag. Line breaks and multiple spaces are
|
|
1180 ignored unless the text is <pre>preformatted.</pre> Text can be marked as
|
|
1181 <b>bold</b>, <i>italic</i> or <u>underlined</u> using the normal M-g or
|
|
1182 Edit/Text Properties/Face commands.
|
|
1183
|
|
1184 Pages can have <a name=\"SOMENAME\">named points</a> and can link other points
|
|
1185 to them with <a href=\"#SOMENAME\">see also somename</a>. In the same way <a
|
|
1186 href=\"URL\">see also URL</a> where URL is a filename relative to current
|
17551
|
1187 directory, or absolute as in `http://www.cs.indiana.edu/elisp/w3/docs.html'.
|
14159
|
1188
|
|
1189 Images in many formats can be inlined with <img src=\"URL\">.
|
|
1190
|
17551
|
1191 If you mainly create your own documents, `sgml-specials' might be
|
|
1192 interesting. But note that some HTML 2 browsers can't handle `''.
|
|
1193 To work around that, do:
|
|
1194 (eval-after-load \"sgml-mode\" '(aset sgml-char-names ?' nil))
|
14159
|
1195
|
|
1196 \\{html-mode-map}"
|
|
1197 (interactive)
|
22772
|
1198 (kill-all-local-variables)
|
|
1199 (setq mode-name "HTML"
|
|
1200 major-mode 'html-mode)
|
14159
|
1201 (sgml-mode-common html-tag-face-alist html-display-text)
|
|
1202 (use-local-map html-mode-map)
|
|
1203 (make-local-variable 'sgml-tag-alist)
|
|
1204 (make-local-variable 'sgml-face-tag-alist)
|
|
1205 (make-local-variable 'sgml-tag-help)
|
|
1206 (make-local-variable 'outline-regexp)
|
|
1207 (make-local-variable 'outline-heading-end-regexp)
|
|
1208 (make-local-variable 'outline-level)
|
16914
|
1209 (make-local-variable 'sentence-end)
|
|
1210 (setq sentence-end
|
24463
|
1211 (if sentence-end-double-space
|
|
1212 "[.?!][]\"')}]*\\(<[^>]*>\\)*\\($\\| $\\|\t\\| \\)[ \t\n]*"
|
|
1213
|
|
1214 "[.?!][]\"')}]*\\(<[^>]*>\\)*\\($\\| \\|\t\\)[ \t\n]*"))
|
22772
|
1215 (setq sgml-tag-alist html-tag-alist
|
14159
|
1216 sgml-face-tag-alist html-face-tag-alist
|
|
1217 sgml-tag-help html-tag-help
|
|
1218 outline-regexp "^.*<[Hh][1-6]\\>"
|
|
1219 outline-heading-end-regexp "</[Hh][1-6]>"
|
|
1220 outline-level (lambda ()
|
|
1221 (char-after (1- (match-end 0)))))
|
22629
|
1222 (setq imenu-create-index-function 'html-imenu-index)
|
|
1223 (make-local-variable 'imenu-sort-function)
|
|
1224 (setq imenu-sort-function nil) ; sorting the menu defeats the purpose
|
22772
|
1225 (run-hooks 'text-mode-hook 'sgml-mode-hook 'html-mode-hook))
|
22629
|
1226
|
|
1227 (defvar html-imenu-regexp
|
|
1228 "\\s-*<h\\([1-9]\\)[^\n<>]*>\\(<[^\n<>]*>\\)*\\s-*\\([^\n<>]*\\)"
|
|
1229 "*A regular expression matching a head line to be added to the menu.
|
|
1230 The first `match-string' should be a number from 1-9.
|
|
1231 The second `match-string' matches extra tags and is ignored.
|
|
1232 The third `match-string' will be the used in the menu.")
|
14159
|
1233
|
22629
|
1234 (defun html-imenu-index ()
|
|
1235 "Return an table of contents for an HTML buffer for use with Imenu."
|
|
1236 (let (toc-index)
|
|
1237 (save-excursion
|
|
1238 (goto-char (point-min))
|
|
1239 (while (re-search-forward html-imenu-regexp nil t)
|
|
1240 (setq toc-index
|
|
1241 (cons (cons (concat (make-string
|
|
1242 (* 2 (1- (string-to-number (match-string 1))))
|
|
1243 ?\ )
|
|
1244 (match-string 3))
|
|
1245 (save-excursion (beginning-of-line) (point)))
|
|
1246 toc-index))))
|
|
1247 (nreverse toc-index)))
|
14159
|
1248
|
22629
|
1249 (defun html-autoview-mode (&optional arg)
|
25175
|
1250 "Toggle automatic viewing via `browse-url-of-buffer' upon saving buffer.
|
22629
|
1251 With positive prefix ARG always turns viewing on, with negative ARG always off.
|
|
1252 Can be used as a value for `html-mode-hook'."
|
|
1253 (interactive "P")
|
|
1254 (if (setq arg (if arg
|
|
1255 (< (prefix-numeric-value arg) 0)
|
|
1256 (and (boundp 'after-save-hook)
|
|
1257 (memq 'browse-url-of-buffer after-save-hook))))
|
|
1258 (setq after-save-hook (delq 'browse-url-of-buffer after-save-hook))
|
|
1259 (add-hook 'after-save-hook 'browse-url-of-buffer nil t))
|
|
1260 (message "Autoviewing turned %s."
|
|
1261 (if arg "off" "on")))
|
|
1262
|
14159
|
1263 (define-skeleton html-href-anchor
|
|
1264 "HTML anchor tag with href attribute."
|
17491
|
1265 "URL: "
|
|
1266 '(setq input "http:")
|
|
1267 "<a href=\"" str "\">" _ "</a>")
|
14159
|
1268
|
|
1269 (define-skeleton html-name-anchor
|
|
1270 "HTML anchor tag with name attribute."
|
17491
|
1271 "Name: "
|
|
1272 "<a name=\"" str "\">" _ "</a>")
|
14159
|
1273
|
15437
|
1274 (define-skeleton html-headline-1
|
|
1275 "HTML level 1 headline tags."
|
|
1276 nil
|
|
1277 "<h1>" _ "</h1>")
|
|
1278
|
|
1279 (define-skeleton html-headline-2
|
|
1280 "HTML level 2 headline tags."
|
|
1281 nil
|
|
1282 "<h2>" _ "</h2>")
|
|
1283
|
|
1284 (define-skeleton html-headline-3
|
|
1285 "HTML level 3 headline tags."
|
|
1286 nil
|
|
1287 "<h3>" _ "</h3>")
|
|
1288
|
|
1289 (define-skeleton html-headline-4
|
|
1290 "HTML level 4 headline tags."
|
|
1291 nil
|
|
1292 "<h4>" _ "</h4>")
|
|
1293
|
|
1294 (define-skeleton html-headline-5
|
|
1295 "HTML level 5 headline tags."
|
|
1296 nil
|
|
1297 "<h5>" _ "</h5>")
|
|
1298
|
|
1299 (define-skeleton html-headline-6
|
|
1300 "HTML level 6 headline tags."
|
|
1301 nil
|
|
1302 "<h6>" _ "</h6>")
|
14159
|
1303
|
|
1304 (define-skeleton html-horizontal-rule
|
|
1305 "HTML horizontal rule tag."
|
|
1306 nil
|
|
1307 "<hr>" \n)
|
|
1308
|
|
1309 (define-skeleton html-image
|
|
1310 "HTML image tag."
|
|
1311 nil
|
17491
|
1312 "<img src=\"" _ "\">")
|
14159
|
1313
|
|
1314 (define-skeleton html-line
|
|
1315 "HTML line break tag."
|
|
1316 nil
|
|
1317 "<br>" \n)
|
|
1318
|
15437
|
1319 (define-skeleton html-ordered-list
|
|
1320 "HTML ordered list tags."
|
|
1321 nil
|
17491
|
1322 "<ol>" \n
|
14159
|
1323 "<li>" _ \n
|
15437
|
1324 "</ol>")
|
|
1325
|
|
1326 (define-skeleton html-unordered-list
|
|
1327 "HTML unordered list tags."
|
|
1328 nil
|
17491
|
1329 "<ul>" \n
|
15437
|
1330 "<li>" _ \n
|
|
1331 "</ul>")
|
14159
|
1332
|
|
1333 (define-skeleton html-list-item
|
|
1334 "HTML list item tag."
|
|
1335 nil
|
|
1336 (if (bolp) nil '\n)
|
|
1337 "<li>")
|
|
1338
|
|
1339 (define-skeleton html-paragraph
|
|
1340 "HTML paragraph tag."
|
|
1341 nil
|
|
1342 (if (bolp) nil ?\n)
|
|
1343 \n "<p>")
|
|
1344
|
14270
|
1345 (define-skeleton html-checkboxes
|
|
1346 "Group of connected checkbox inputs."
|
|
1347 nil
|
17491
|
1348 '(setq v1 nil
|
|
1349 v2 nil)
|
|
1350 ("Value: "
|
17545
|
1351 "<input type=\"" (identity "checkbox") ; see comment above about identity
|
17491
|
1352 "\" name=\"" (or v1 (setq v1 (skeleton-read "Name: ")))
|
14270
|
1353 "\" value=\"" str ?\"
|
17491
|
1354 (if (y-or-n-p "Set \"checked\" attribute? ")
|
|
1355 (funcall skeleton-transformation " checked")) ">"
|
|
1356 (skeleton-read "Text: " (capitalize str))
|
|
1357 (or v2 (setq v2 (if (y-or-n-p "Newline after text? ")
|
|
1358 (funcall skeleton-transformation "<br>")
|
|
1359 "")))
|
|
1360 \n))
|
14270
|
1361
|
14159
|
1362 (define-skeleton html-radio-buttons
|
|
1363 "Group of connected radio button inputs."
|
|
1364 nil
|
17491
|
1365 '(setq v1 nil
|
|
1366 v2 (cons nil nil))
|
|
1367 ("Value: "
|
17545
|
1368 "<input type=\"" (identity "radio") ; see comment above about identity
|
17491
|
1369 "\" name=\"" (or (car v2) (setcar v2 (skeleton-read "Name: ")))
|
14159
|
1370 "\" value=\"" str ?\"
|
17491
|
1371 (if (and (not v1) (setq v1 (y-or-n-p "Set \"checked\" attribute? ")))
|
|
1372 (funcall skeleton-transformation " checked") ">")
|
|
1373 (skeleton-read "Text: " (capitalize str))
|
|
1374 (or (cdr v2) (setcdr v2 (if (y-or-n-p "Newline after text? ")
|
|
1375 (funcall skeleton-transformation "<br>")
|
|
1376 "")))
|
|
1377 \n))
|
14159
|
1378
|
809
|
1379 ;;; sgml-mode.el ends here
|