Mercurial > hg > xemacs-beta
comparison lisp/w3/w3-draw.el @ 70:131b0175ea99 r20-0b30
Import from CVS: tag r20-0b30
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:02:59 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
69:804d1389bcd6 | 70:131b0175ea99 |
---|---|
1 ;;; w3-draw.el --- Emacs-W3 drawing functions for new display engine | |
2 ;; Author: wmperry | |
3 ;; Created: 1996/08/25 17:12:32 | |
4 ;; Version: 1.17 | |
5 ;; Keywords: faces, help, hypermedia | |
6 | |
7 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
8 ;;; Copyright (c) 1993 - 1996 by William M. Perry (wmperry@cs.indiana.edu) | |
9 ;;; | |
10 ;;; This file is not part of GNU Emacs, but the same permissions apply. | |
11 ;;; | |
12 ;;; GNU Emacs is free software; you can redistribute it and/or modify | |
13 ;;; it under the terms of the GNU General Public License as published by | |
14 ;;; the Free Software Foundation; either version 2, or (at your option) | |
15 ;;; any later version. | |
16 ;;; | |
17 ;;; GNU Emacs is distributed in the hope that it will be useful, | |
18 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 ;;; GNU General Public License for more details. | |
21 ;;; | |
22 ;;; You should have received a copy of the GNU General Public License | |
23 ;;; along with GNU Emacs; see the file COPYING. If not, write to | |
24 ;;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | |
25 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
26 | |
27 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
28 ;;; This function will take a stream of HTML from w3-parse-buffer | |
29 ;;; and draw it out | |
30 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
31 | |
32 (require 'w3-vars) | |
33 (require 'w3-imap) | |
34 (require 'w3-widget) | |
35 (require 'widget) | |
36 (require 'cl) | |
37 | |
38 (if (featurep 'mule) (fset 'string-width 'length)) | |
39 | |
40 (defmacro w3-get-state (tag) | |
41 (or (symbolp tag) | |
42 (error "Bad argument: %s" tag)) | |
43 (let ((index (length (memq tag w3-state-locator-variable)))) | |
44 (` (aref w3-state-vector (, index))))) | |
45 (put 'w3-get-state 'edebug-form-spec '(symbolp)) | |
46 | |
47 (defmacro w3-put-state (tag val) | |
48 (or (symbolp tag) | |
49 (error "Bad argument: %s" tag)) | |
50 (let ((index (length (memq tag w3-state-locator-variable)))) | |
51 (` (aset w3-state-vector (, index) (, val))))) | |
52 (put 'w3-put-state 'edebug-form-spec '(symbolp form)) | |
53 | |
54 (defsubst w3-push-alignment (align) | |
55 (if align | |
56 (w3-put-state :align (cons (cons tag align) (w3-get-state :align))))) | |
57 | |
58 (defsubst w3-pop-alignment () | |
59 (let ((flubber (memq (assq tag (w3-get-state :align)) | |
60 (w3-get-state :align)))) | |
61 (cond | |
62 ((null flubber) nil) | |
63 ((cdr flubber) | |
64 (w3-put-state :align (cdr flubber))) | |
65 (t (w3-put-state :align nil))))) | |
66 | |
67 (defsubst w3-current-alignment () | |
68 (cdr-safe (car-safe (w3-get-state :align)))) | |
69 | |
70 (defconst w3-fill-prefixes-vector | |
71 (let ((len 0) | |
72 (prefix-vector (make-vector 80 nil))) | |
73 (while (< len 80) | |
74 (aset prefix-vector len (make-string len ? )) | |
75 (setq len (1+ len))) | |
76 prefix-vector)) | |
77 | |
78 (defsubst w3-set-fill-prefix-length (len) | |
79 (setq fill-prefix (if (< len (- (or w3-strict-width (window-width)) 4)) | |
80 (if (< len 80) | |
81 (aref w3-fill-prefixes-vector len) | |
82 (make-string len ? )) | |
83 (url-warn | |
84 'html | |
85 "Runaway indentation! Too deep for window width!") | |
86 fill-prefix))) | |
87 | |
88 (defsubst w3-get-default-style-info (info) | |
89 (and w3-current-stylesheet | |
90 (or | |
91 ;; Check for tag/id|name first! | |
92 (cdr-safe (assq info | |
93 (cdr-safe | |
94 (assoc (or (cdr-safe (assq 'id args)) | |
95 (cdr-safe (assq 'name args))) | |
96 (cdr-safe | |
97 (assq tag w3-current-stylesheet)))))) | |
98 | |
99 ;; Check for tag/class next | |
100 (cdr-safe (assq info | |
101 (cdr-safe | |
102 (assoc (cdr-safe (assq 'class args)) | |
103 (cdr-safe | |
104 (assq tag w3-current-stylesheet)))))) | |
105 | |
106 ;; Then for global stuff with 'class' | |
107 (cdr-safe (assq info | |
108 (cdr-safe | |
109 (assoc (cdr-safe (assq 'class args)) | |
110 (cdr-safe | |
111 (assq 'doc w3-current-stylesheet)))))) | |
112 | |
113 ;; Fall back on the default styles for just this tag. | |
114 (cdr-safe (assq info | |
115 (cdr-safe | |
116 (assq 'internal | |
117 (cdr-safe | |
118 (assq tag w3-current-stylesheet))))))))) | |
119 | |
120 (defsubst w3-normalize-color (color) | |
121 (cond | |
122 ((valid-color-name-p color) | |
123 color) | |
124 ((valid-color-name-p (concat "#" color)) | |
125 (concat "#" color)) | |
126 ((string-match "[ \t\r\n]" color) | |
127 (w3-normalize-color | |
128 (mapconcat (function (lambda (x) (if (memq x '(?\t ?\r ?\n ? )) "" | |
129 (char-to-string x)))) color ""))) | |
130 ((valid-color-name-p (font-normalize-color color)) | |
131 (font-normalize-color color)) | |
132 (t | |
133 (w3-warn 'html (format "Bad color specification: %s" color)) | |
134 nil))) | |
135 | |
136 (defun w3-pause () | |
137 (cond | |
138 (w3-running-FSF19 (sit-for 0)) | |
139 (w3-running-xemacs | |
140 (if (and (not (sit-for 0)) (input-pending-p)) | |
141 (condition-case () | |
142 (dispatch-event (next-command-event)) | |
143 (error nil)))) | |
144 (t (sit-for 0)))) | |
145 | |
146 (defvar w3-end-tags | |
147 '((/ul . ul) | |
148 (/lit . lit) | |
149 (/li . li) | |
150 (/h1 . h1) | |
151 (/h2 . h2) | |
152 (/h3 . h3) | |
153 (/h4 . h4) | |
154 (/h5 . h5) | |
155 (/h6 . h6) | |
156 (/font0 . font0) | |
157 (/font1 . font1) | |
158 (/font2 . font2) | |
159 (/font3 . font3) | |
160 (/font4 . font4) | |
161 (/font5 . font5) | |
162 (/font6 . font6) | |
163 (/font7 . font7) | |
164 (/ol . ol) | |
165 (/dl . dl) | |
166 (/menu . menu) | |
167 (/dir . dir) | |
168 (/a . a))) | |
169 | |
170 (defvar w3-face-cache nil | |
171 "Cache for w3-face-for-element") | |
172 | |
173 (defsubst w3-voice-for-element () | |
174 (let ((temporary-voice (w3-get-default-style-info 'voice-spec))) | |
175 (and temporary-voice (cons tag temporary-voice)))) | |
176 | |
177 (defsubst w3-face-for-element () | |
178 (let* ((font-spec (w3-get-default-style-info 'font-spec)) | |
179 (foreground (w3-get-default-style-info 'color)) | |
180 (background (w3-get-default-style-info 'background)) | |
181 ;;(pixmap (w3-get-default-style-info 'pixmap)) | |
182 (descr (list font-spec foreground background)) | |
183 (face (cdr-safe (assoc descr w3-face-cache)))) | |
184 (if (or face (not (or foreground background font-spec))) | |
185 nil ; Do nothing, we got it already | |
186 (setq face (intern (format "%s" descr))) | |
187 (cond | |
188 ((not (fboundp 'make-face)) nil) ; Do nothing | |
189 ((and (fboundp 'face-property) ; XEmacs 19.14 | |
190 (not (get 'face-property 'sysdep-defined-this))) | |
191 (setq face (make-face face | |
192 "An Emacs-W3 face... don't edit by hand." t))) | |
193 (t (make-face face))) | |
194 | |
195 (and font-spec (set-face-font face font-spec)) | |
196 (and foreground (set-face-foreground face foreground)) | |
197 (and background (set-face-background face background)) | |
198 ;(set-face-background-pixmap face pixmap) | |
199 (setq w3-face-cache (cons (cons descr face) w3-face-cache))) | |
200 (cons tag face))) | |
201 | |
202 (defun w3-handle-single-tag (tag &optional args) | |
203 (save-excursion | |
204 (and w3-draw-buffer (set-buffer w3-draw-buffer)) | |
205 (let ((opos (point)) | |
206 (id (and (listp args) | |
207 (or (cdr-safe (assq 'name args)) | |
208 (cdr-safe (assq 'id args)))))) | |
209 | |
210 ;; This allows _ANY_ tag, whether it is known or not, to be | |
211 ;; the target of a # reference in a URL | |
212 (if id | |
213 (progn | |
214 (setq w3-id-positions (cons | |
215 (cons (intern id) | |
216 (set-marker (make-marker) | |
217 (point-max))) | |
218 w3-id-positions)))) | |
219 | |
220 (if (and (listp args) (cdr-safe (assq 'style args))) | |
221 (let ((unique-id (or id (url-create-unique-id))) | |
222 (sheet "")) | |
223 (setq sheet (format "%s.%s { %s }\n" tag unique-id | |
224 (cdr-safe (assq 'style args))) | |
225 args (cons (cons 'id unique-id) args)) | |
226 | |
227 (w3-handle-style (list (cons 'data sheet) | |
228 (cons 'notation "css"))))) | |
229 (goto-char (point-max)) | |
230 (if (and (w3-get-state :next-break) | |
231 (not (memq tag | |
232 '(p h1 h2 h3 h4 h5 h6 ol ul dl menu dir pre)))) | |
233 (w3-handle-p)) | |
234 (w3-put-state :next-break nil) | |
235 (setq w3-current-formatter (get tag 'w3-formatter)) | |
236 (cond | |
237 ((eq 'w3-handle-text w3-current-formatter) | |
238 (w3-handle-text args)) | |
239 (t | |
240 (let ((data-before nil) | |
241 (data-after nil)) | |
242 (if (and (not (eq tag 'text)) w3-current-stylesheet) | |
243 (progn | |
244 (setq data-before (w3-get-default-style-info | |
245 'insert.before)) | |
246 (let ((tag (cdr-safe (assq tag w3-end-tags)))) | |
247 (setq data-after (and tag | |
248 (w3-get-default-style-info | |
249 'insert.after)))))) | |
250 (if data-before (w3-handle-text data-before)) | |
251 (setq w3-current-formatter (get tag 'w3-formatter)) | |
252 (cond | |
253 ((eq w3-current-formatter 'ack) nil) | |
254 ((null w3-current-formatter) (w3-handle-unknown-tag tag args)) | |
255 (t (funcall w3-current-formatter args))) | |
256 (if data-after (w3-handle-text data-after))))) | |
257 (if (not (eq tag 'text)) | |
258 (setq w3-last-tag tag)) | |
259 (goto-char opos)))) | |
260 | |
261 | |
262 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
263 ;;; Set up basic fonts/stuff | |
264 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
265 | |
266 (defun w3-init-state () | |
267 ;; Reset the state of an HTML drawing buffer | |
268 (setq w3-state-vector (copy-sequence w3-state-vector)) | |
269 (setq w3-current-stylesheet (copy-tree w3-user-stylesheet)) | |
270 (let* ((tag 'html) | |
271 (args nil) | |
272 (face (cdr (w3-face-for-element)))) | |
273 (if (not face) | |
274 (setq tag 'body | |
275 face (cdr (w3-face-for-element)))) | |
276 (and face | |
277 (if (not (fboundp 'valid-specifier-locale-p)) | |
278 nil | |
279 (w3-my-safe-copy-face face 'default (current-buffer))))) | |
280 (setq w3-form-labels nil) | |
281 (make-local-variable 'w3-image-widgets-waiting) | |
282 (make-local-variable 'w3-active-voices) | |
283 (make-local-variable 'inhibit-read-only) | |
284 (setq w3-image-widgets-waiting nil | |
285 inhibit-read-only t) | |
286 (if (not (get 'w3-state 'init)) (w3-draw-setup)) | |
287 (fillarray w3-state-vector 0) | |
288 (w3-put-state :bogus nil) ; Make all fake ones return nil | |
289 (w3-put-state :text-mangler nil) ; Any text mangling routine | |
290 (w3-put-state :next-break nil) ; Next item needs a paragraph break | |
291 (w3-put-state :background nil) ; Netscapism - gag | |
292 (w3-put-state :table nil) ; Table args | |
293 (w3-put-state :figdata nil) ; Data for <fig> tag | |
294 (w3-put-state :figalt nil) ; Alt data for <fig> tag | |
295 (w3-put-state :pre-start nil) ; Where current <pre> seg starts | |
296 (w3-put-state :zone nil) ; Zone of current href? | |
297 (w3-put-state :center nil) ; netscape tag | |
298 (w3-put-state :select nil) ; Data for current select field | |
299 (w3-put-state :options nil) ; Options in current select field | |
300 (w3-put-state :nofill nil) ; non-nil if in pre or xmp | |
301 (w3-put-state :nowrap nil) ; non-nil if in <p nowrap> | |
302 (w3-put-state :href nil) ; Current link destination | |
303 (w3-put-state :name nil) ; Current link ID tag | |
304 (w3-put-state :image nil) ; Current image destination | |
305 (w3-put-state :form nil) ; Current form information | |
306 (w3-put-state :optarg nil) ; Option arguments | |
307 (w3-put-state :w3-graphic nil) ; Image stuff for non-xemacs | |
308 (w3-put-state :lists '()) ; Types of list currently in. | |
309 (w3-put-state :align nil) ; Current alignment of paragraphs | |
310 (w3-put-state :title nil) ; Whether we can have a title or not | |
311 (w3-put-state :seen-this-url nil) ; whether we have seen this url or not | |
312 (w3-put-state :needspace 'never) ; Spacing info | |
313 (setq w3-active-faces nil) ; Face attributes to use | |
314 (setq w3-active-voices nil) ; voice attributes to use | |
315 ) | |
316 | |
317 (defun w3-draw-setup () | |
318 (put 'w3-state 'init t) | |
319 (w3-init-state)) | |
320 | |
321 | |
322 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
323 ;;; Mapping HTML tags to functions | |
324 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
325 (put 'lit 'w3-formatter 'w3-handle-pre) | |
326 (put '/lit 'w3-formatter 'w3-handle-/pre) | |
327 (put 'li 'w3-formatter 'w3-handle-list-item) | |
328 (put 'ul 'w3-formatter 'w3-handle-list-opening) | |
329 (put 'ol 'w3-formatter 'w3-handle-list-opening) | |
330 (put 'dl 'w3-formatter 'w3-handle-list-opening) | |
331 (put '/dl 'w3-formatter 'w3-handle-list-ending) | |
332 (put '/ul 'w3-formatter 'w3-handle-list-ending) | |
333 (put '/ol 'w3-formatter 'w3-handle-list-ending) | |
334 (put 'menu 'w3-formatter 'w3-handle-list-opening) | |
335 (put '/menu 'w3-formatter 'w3-handle-list-ending) | |
336 (put 'dir 'w3-formatter 'w3-handle-list-opening) | |
337 (put '/dir 'w3-formatter 'w3-handle-list-ending) | |
338 (put 'dt 'w3-formatter 'w3-handle-table-term) | |
339 (put 'dd 'w3-formatter 'w3-handle-table-definition) | |
340 (put 'a 'w3-formatter 'w3-handle-hyperlink) | |
341 (put '/a 'w3-formatter 'w3-handle-hyperlink-end) | |
342 (put 'h1 'w3-formatter 'w3-handle-header) | |
343 (put 'h2 'w3-formatter 'w3-handle-header) | |
344 (put 'h3 'w3-formatter 'w3-handle-header) | |
345 (put 'h4 'w3-formatter 'w3-handle-header) | |
346 (put 'h5 'w3-formatter 'w3-handle-header) | |
347 (put 'h6 'w3-formatter 'w3-handle-header) | |
348 (put '/h1 'w3-formatter 'w3-handle-header-end) | |
349 (put '/h2 'w3-formatter 'w3-handle-header-end) | |
350 (put '/h3 'w3-formatter 'w3-handle-header-end) | |
351 (put '/h4 'w3-formatter 'w3-handle-header-end) | |
352 (put '/h5 'w3-formatter 'w3-handle-header-end) | |
353 (put '/h6 'w3-formatter 'w3-handle-header-end) | |
354 (put 'img 'w3-formatter 'w3-handle-image) | |
355 (put 'kill_sgml 'w3-formatter 'w3-handle-kill-sgml) | |
356 | |
357 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
358 ;;; The main drawing routines | |
359 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
360 (defun w3-handle-unknown-tag (tag args) | |
361 ;; A generic formatter for an unkown HTML tag. This will only be | |
362 ;; called if a formatter was not found in TAGs property list. | |
363 ;; If a function named `w3-handle-TAG' is defined, then it will be | |
364 ;; stored in TAGs property list, so it will be found next time | |
365 ;; the tag is run across. | |
366 | |
367 (let ((handler (intern-soft (concat "w3-handle-" (symbol-name tag)))) | |
368 (end-tag-p (= (string-to-char (symbol-name tag)) ?/))) | |
369 | |
370 ;; This stores the info in w3-end-tags for future use by the display | |
371 ;; engine. | |
372 (if end-tag-p | |
373 (setq w3-end-tags (cons (cons tag | |
374 (intern (substring (symbol-name tag) | |
375 1))) | |
376 w3-end-tags))) | |
377 | |
378 ;; For proper use of stylesheets, if no tag is found, then we should | |
379 ;; at least call w3-handle-emphasis | |
380 (cond | |
381 ((and handler (fboundp handler)) | |
382 (put tag 'w3-formatter handler) | |
383 (funcall handler args)) | |
384 (end-tag-p | |
385 (put tag 'w3-formatter 'w3-handle-emphasis-end) | |
386 (w3-handle-emphasis-end args)) | |
387 (t | |
388 (put tag 'w3-formatter 'w3-handle-emphasis) | |
389 (w3-handle-emphasis args))))) | |
390 | |
391 (defun w3-handle-text (&optional args) | |
392 ;; This is the main workhorse of the display engine. | |
393 ;; It will figure out how a chunk of text should be displayed and | |
394 ;; put all the necessary extents/overlays/regions around it." | |
395 (or args (error "Impossible")) | |
396 (if (string= args "") | |
397 (w3-put-state :needspace nil) | |
398 (let ((st (point)) | |
399 (mangler (w3-get-state :text-mangler)) | |
400 (sym nil)) | |
401 (insert args) | |
402 ;;(goto-char st) | |
403 (cond ((w3-get-state :nofill) | |
404 (goto-char st) | |
405 (if (not (search-forward "\n" nil t)) | |
406 (subst-char-in-region st (point-max) ?\r ?\n) | |
407 (subst-char-in-region st (point-max) ?\r ? )) | |
408 (goto-char (point-max))) | |
409 (t | |
410 (goto-char st) | |
411 (while (re-search-forward | |
412 " [ \t\n\r]+\\|[\t\n\r][ \t\n\r]*" | |
413 nil 'move) | |
414 (replace-match " ")) | |
415 (goto-char st) | |
416 (if (and (= ? (following-char)) | |
417 (or (bolp) | |
418 (eq 'never (w3-get-state :needspace)))) | |
419 (delete-char 1)) | |
420 (goto-char (point-max)))) | |
421 (and mangler w3-delimit-emphasis | |
422 (fboundp mangler) (funcall mangler st (point))) | |
423 (let ((faces nil) | |
424 (todo w3-active-faces) | |
425 (voices w3-active-voices) | |
426 (val nil) | |
427 (cur nil)) | |
428 (while todo | |
429 (setq cur (car todo) | |
430 todo (cdr todo)) | |
431 (cond | |
432 ((symbolp cur) | |
433 nil) | |
434 ((listp (cdr-safe cur)) | |
435 (let ((x (cdr cur))) | |
436 (while x | |
437 (if (not (memq (car x) faces)) | |
438 (setq faces (cons (car x) faces))) | |
439 (setq x (cdr x))))) | |
440 ((and (consp cur) (not (memq (cdr cur) faces))) | |
441 (setq faces (cons (cdr cur) faces))) | |
442 (t nil))) | |
443 (add-text-properties st (point) (list 'face faces)) | |
444 (if (car voices) | |
445 (add-text-properties st (point) (list 'personality (cdar voices)))) | |
446 ) | |
447 (if (not (memq (char-after (1- (point))) '(? ?.))) | |
448 (w3-put-state :needspace t)) | |
449 ))) | |
450 | |
451 (defun w3-handle-plaintext (&optional args) | |
452 (let ((x (w3-get-state :nofill))) | |
453 (w3-put-state :nofill t) | |
454 (and args (cdr-safe (assq 'data args)) | |
455 (w3-handle-text (cdr-safe (assq 'data args)))) | |
456 (setq w3-last-fill-pos (point)))) | |
457 | |
458 (defun w3-handle-/plaintext (&optional args) | |
459 (w3-put-state :nofill nil)) | |
460 | |
461 | |
462 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
463 ;;; Paragraph breaks, and other things that can cause linebreaks and | |
464 ;;; alignment changes. | |
465 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
466 (defun w3-handle-header (&optional args) | |
467 ;; Handle the creation of a header (of any level). Causes a full | |
468 ;; paragraph break. | |
469 (w3-handle-emphasis args) | |
470 (let ((name (or (cdr-safe (assq 'name args)) | |
471 (cdr-safe (assq 'id args)))) | |
472 (align (cdr-safe (assq 'align args))) | |
473 (mangler (nth 2 (cdr-safe (assq tag w3-header-chars-assoc))))) | |
474 (w3-handle-p) | |
475 (if align | |
476 (setq align (intern (downcase align))) | |
477 (setq align (w3-get-default-style-info 'align))) | |
478 (let ((tag 'p)) | |
479 (w3-pop-alignment)) | |
480 (w3-push-alignment align) | |
481 (w3-put-state :text-mangler mangler) | |
482 (if name (w3-put-state :name name)))) | |
483 | |
484 (defun w3-handle-header-end (&optional args) | |
485 ;; Handle the closing of a header (of any level). Causes a full | |
486 ;; paragraph break. | |
487 (w3-handle-emphasis-end) | |
488 (let ((mangler (w3-get-state :text-mangler))) | |
489 (and mangler (funcall mangler nil nil t))) | |
490 (w3-put-state :text-mangler nil) | |
491 (goto-char (point-max)) | |
492 (w3-handle-p) | |
493 (let* ((info (car-safe (w3-get-state :lists))) | |
494 (type (and info (car-safe info)))) | |
495 (if (and type fill-prefix) | |
496 (insert fill-prefix (cond | |
497 ((memq type '(ol dl)) " ") | |
498 (t " "))))) | |
499 (let ((tag (cdr-safe (assoc tag w3-end-tags)))) | |
500 (w3-pop-alignment))) | |
501 | |
502 (defun w3-handle-pre (&optional args) | |
503 ;; Marks the start of a preformatted section of text. No paragraph | |
504 ;; filling should be done from this point until a matching /pre has | |
505 ;; been encountered. | |
506 (w3-handle-p) | |
507 (w3-put-state :nofill t) | |
508 (w3-put-state :needspace t) | |
509 (w3-put-state :pre-start (set-marker (make-marker) (point))) | |
510 ) | |
511 | |
512 (defun w3-handle-xmp (&optional args) | |
513 ;; Marks the start of a preformatted section of text. No paragraph | |
514 ;; filling should be done from this point until a matching /pre has | |
515 ;; been encountered. | |
516 (w3-handle-p) | |
517 (w3-put-state :nofill t) | |
518 (w3-put-state :needspace t) | |
519 (w3-put-state :pre-start (set-marker (make-marker) (point))) | |
520 (if (and args (cdr-safe (assq 'data args))) | |
521 (progn | |
522 (w3-handle-text (cdr-safe (assq 'data args))) | |
523 (w3-handle-/xmp)))) | |
524 | |
525 (defun w3-handle-/pre (&optional args) | |
526 (if (not (w3-get-state :nofill)) | |
527 (w3-handle-p) | |
528 (w3-put-state :nofill nil) | |
529 (let* ((info (car-safe (w3-get-state :lists))) | |
530 (type (and info (car-safe info))) | |
531 (st (w3-get-state :pre-start))) | |
532 (if (not (bolp)) (insert "\n")) | |
533 (if (and type fill-prefix st) | |
534 (progn | |
535 (save-excursion | |
536 (goto-char st) | |
537 (while (re-search-forward "^" nil t) | |
538 (insert fill-prefix (cond | |
539 ((memq type '(ol dl)) " ") | |
540 (t " "))))) | |
541 (setq w3-last-fill-pos (point)) | |
542 (insert fill-prefix (cond | |
543 ((memq type '(ol dl)) " ") | |
544 (t " ")))) | |
545 (setq w3-last-fill-pos (point)))) | |
546 (let ((tag 'p)) | |
547 (w3-handle-p)) | |
548 (setq w3-active-faces nil) | |
549 (w3-put-state :pre-start nil))) | |
550 | |
551 (fset 'w3-handle-/xmp 'w3-handle-/pre) | |
552 | |
553 (defun w3-handle-blockquote (&optional args) | |
554 ;; Start a section of quoted text. This is done by causing the text | |
555 ;; to be indented from the right and left margins. Nested | |
556 ;; blockquotes will cause further indentation. | |
557 (let ((align (or (w3-get-default-style-info 'align) 'indent))) | |
558 (w3-handle-p) | |
559 (w3-push-alignment align)) | |
560 (w3-put-state :fillcol fill-column) | |
561 (setq fill-column (max (- (or fill-column | |
562 (1- (or w3-strict-width (window-width)))) 8) | |
563 10))) | |
564 | |
565 (defun w3-handle-/blockquote (&optional args) | |
566 (w3-handle-paragraph) | |
567 (let ((tag (cdr-safe (assoc tag w3-end-tags)))) | |
568 (w3-pop-alignment)) | |
569 (setq fill-column (or (w3-get-state :fillcol) (1- (or w3-strict-width | |
570 (window-width))))) | |
571 (w3-put-state :fillcol nil)) | |
572 | |
573 (defun w3-handle-align (&optional args) | |
574 ;; Cause a single line break (like <BR>) and replace the current | |
575 ;; alignment. | |
576 (let ((align (intern (or (cdr-safe (assq 'role args)) | |
577 (cdr-safe (assq 'align args)) | |
578 (cdr-safe (assq 'style args)))))) | |
579 (w3-handle-paragraph) | |
580 (w3-push-alignment align))) | |
581 | |
582 (defun w3-handle-/align (&optional args) | |
583 (w3-handle-paragraph) | |
584 (w3-pop-alignment)) | |
585 | |
586 (defun w3-handle-hr (&optional args) | |
587 ;; Cause a line break and insert a horizontal rule across the page. | |
588 (w3-handle-paragraph) | |
589 (let* ((perc (or (cdr-safe (assq 'width args)) | |
590 (w3-get-default-style-info 'width) | |
591 "100%")) | |
592 (old-align (w3-current-alignment)) | |
593 (talign (or (cdr-safe (assq 'textalign args)) | |
594 (cdr-safe (assq 'text-align args)) | |
595 (w3-get-default-style-info 'textalign) | |
596 (w3-get-default-style-info 'text-align) | |
597 (and old-align (symbol-name old-align)) | |
598 "center")) | |
599 (text (cdr-safe (assq 'label args))) | |
600 (align (or (cdr-safe (assq 'align args)) | |
601 (w3-get-default-style-info 'align) | |
602 old-align | |
603 'center)) | |
604 (rule nil) | |
605 (width nil)) | |
606 (if (stringp talign) | |
607 (setq talign (intern (downcase talign)))) | |
608 (if (stringp align) | |
609 (setq align (intern (downcase align)))) | |
610 (w3-push-alignment align) | |
611 | |
612 (setq perc (min (string-to-int perc) 100) | |
613 width (/ (* (- (or w3-strict-width | |
614 (window-width)) | |
615 w3-right-border) perc) 100)) | |
616 (if text | |
617 (cond | |
618 ((>= (length text) width) | |
619 (setq rule (concat "-" text "-"))) | |
620 ((eq talign 'right) | |
621 (setq rule (concat (make-string (- width 1 (length text)) | |
622 w3-horizontal-rule-char) | |
623 text "-"))) | |
624 ((eq talign 'center) | |
625 (let ((half (make-string (/ (- width (length text)) 2) | |
626 w3-horizontal-rule-char))) | |
627 (setq rule (concat half text half)))) | |
628 ((eq talign 'left) | |
629 (setq rule (concat "-" text (make-string (- width 1 | |
630 (length text)) | |
631 w3-horizontal-rule-char))))) | |
632 (setq rule (make-string width w3-horizontal-rule-char))) | |
633 (w3-handle-text rule) | |
634 (condition-case () | |
635 (w3-handle-paragraph) | |
636 (error nil)) | |
637 (w3-pop-alignment) | |
638 (setq w3-last-fill-pos (point)) | |
639 (let* ((info (car-safe (w3-get-state :lists))) | |
640 (type (and info (car-safe info))) | |
641 (cur (w3-current-alignment))) | |
642 (cond | |
643 ;;((eq cur 'indent) | |
644 ;;(insert (make-string w3-indent-level ? ))) | |
645 ((and type fill-prefix (eq w3-last-tag 'dt)) | |
646 (insert fill-prefix)) | |
647 ((and type fill-prefix) | |
648 (insert fill-prefix (if (eq type 'ol) " " " "))) | |
649 (t nil))))) | |
650 | |
651 (defun w3-handle-/p (&optional args) | |
652 ;; Marks the end of a paragraph. Only causes a paragraph break if | |
653 ;; it is not followed by another paragraph or similar markup | |
654 ;; (headers, list openings, etc) that will already cause a new | |
655 ;; paragraph to be started. | |
656 (w3-handle-emphasis-end) | |
657 (let ((tag (cdr-safe (assoc tag w3-end-tags)))) | |
658 (w3-handle-p) | |
659 (w3-pop-alignment))) | |
660 | |
661 (defun w3-handle-p (&optional args) | |
662 (if (or (not (memq w3-last-tag '(li tr td th dt dd))) | |
663 (memq tag '(ol ul dl menu dir))) | |
664 (let ((name (or (cdr-safe (assq 'name args)) | |
665 (cdr-safe (assq 'id args)))) | |
666 (align (cdr-safe (assoc 'align args)))) | |
667 (w3-handle-emphasis-end) | |
668 (w3-handle-emphasis args) | |
669 (w3-handle-paragraph) | |
670 (w3-put-state :nowrap (assq 'nowrap args)) | |
671 (setq align (if align | |
672 (intern (downcase align)) | |
673 (w3-get-default-style-info 'align))) | |
674 (and (eq tag 'p) (progn | |
675 (w3-pop-alignment) | |
676 (w3-push-alignment align))) | |
677 (if (not (bobp)) | |
678 (progn | |
679 (insert (cond | |
680 ((and (eolp) (bolp)) "\n") | |
681 ((eolp) "\n\n") | |
682 (t "\n"))) | |
683 (setq w3-last-fill-pos (point)) | |
684 (cond | |
685 ((null fill-prefix)) | |
686 ((string= fill-prefix "")) | |
687 ((eq (car (car (w3-get-state :lists))) 'ol) | |
688 (insert fill-prefix " ")) | |
689 (t (insert fill-prefix " "))))) | |
690 (if name (w3-put-state :name name))))) | |
691 | |
692 (defun w3-handle-br (&optional args) | |
693 ;; Cause a single line break. | |
694 ;; The alignment will only effect the chunk of text (generally to | |
695 ;; the last <br> or <p> tag) immediately before the <br>. After | |
696 ;; that, the alignment will revert to the containers alignment. | |
697 (w3-handle-paragraph) | |
698 (let* ((info (car-safe (w3-get-state :lists))) | |
699 (type (and info (car-safe info))) | |
700 (cur (w3-current-alignment))) | |
701 (cond | |
702 ;;((eq cur 'indent) | |
703 ;;(insert (make-string w3-indent-level ? ))) | |
704 ((and type fill-prefix (eq w3-last-tag 'dt)) | |
705 (insert fill-prefix)) | |
706 ((and type fill-prefix) | |
707 (insert fill-prefix (if (eq type 'ol) " " " "))) | |
708 (t nil)))) | |
709 | |
710 (defun w3-handle-paragraph (&optional args) | |
711 (if (not (bobp)) | |
712 (let ((align (w3-current-alignment)) | |
713 (fill-prefix fill-prefix)) | |
714 (cond | |
715 ((eq align 'indent) | |
716 (w3-set-fill-prefix-length | |
717 (+ (length fill-prefix);; works even if fill-prefix is nil | |
718 w3-indent-level))) | |
719 ((null fill-prefix) | |
720 (setq fill-prefix "")) | |
721 ((string= fill-prefix "")) | |
722 ((eq (car (car (w3-get-state :lists))) 'ol) | |
723 (w3-set-fill-prefix-length (+ 4 (length fill-prefix)))) | |
724 (t | |
725 (w3-set-fill-prefix-length (+ 2 (length fill-prefix))))) | |
726 (if (eq align 'indent) | |
727 (progn | |
728 (goto-char w3-last-fill-pos) | |
729 (insert fill-prefix) | |
730 (goto-char (point-max)))) | |
731 (if (and (> (current-column) fill-column) | |
732 (not (w3-get-state :nowrap)) | |
733 (not (w3-get-state :nofill))) | |
734 (fill-region-as-paragraph w3-last-fill-pos (point) | |
735 (eq align 'justify))) | |
736 (if (not w3-last-fill-pos) | |
737 (setq w3-last-fill-pos (point-min))) | |
738 (goto-char (point-max)) | |
739 (skip-chars-backward " \t\n") | |
740 (delete-region (point) (point-max)) | |
741 (if (< w3-last-fill-pos (point)) | |
742 (cond | |
743 ((or (eq align 'center) (w3-get-state :center)) | |
744 (center-region w3-last-fill-pos (point))) | |
745 ((eq align 'right) | |
746 (let ((x (point))) | |
747 (catch 'fill-exit | |
748 (save-excursion | |
749 (goto-char w3-last-fill-pos) | |
750 (while (re-search-forward "$" x t) | |
751 (if (/= (current-column) fill-column) | |
752 (let ((buff (- fill-column (current-column)))) | |
753 (beginning-of-line) | |
754 (setq x (+ x buff)) | |
755 (if (> buff 0) | |
756 (insert (make-string buff ? ))) | |
757 (end-of-line)) | |
758 (end-of-line)) | |
759 (if (eobp) (throw 'fill-exit t)) | |
760 (condition-case () | |
761 (forward-char 1) | |
762 (error (throw 'fill-exit t)))))))))) | |
763 (insert "\n") | |
764 (setq w3-last-fill-pos (point)) | |
765 (w3-put-state :needspace 'never)))) | |
766 | |
767 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
768 ;;; List handling code | |
769 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
770 (defun w3-handle-list-ending (&optional args) | |
771 ;; Handles all the list terminators (/ol /ul /dl). | |
772 ;; This just fills the last paragrpah, then reduces the depth in | |
773 ;; `w3-state' and truncates `fill-prefix'" | |
774 (w3-handle-paragraph) | |
775 (w3-put-state :depth (max 0 (1- (w3-get-state :depth)))) | |
776 (w3-put-state :next-break t) | |
777 (w3-set-fill-prefix-length (* (w3-get-state :depth) w3-indent-level)) | |
778 (w3-put-state :lists (cdr (w3-get-state :lists))) | |
779 (if (/= 0 (length fill-prefix)) | |
780 (insert fill-prefix " "))) | |
781 | |
782 (defun w3-handle-list-opening (&optional args) | |
783 ;; Handles all the list openers (ol ul dl). | |
784 ;; This just fills the last paragraph, then increases the depth in | |
785 ;; `w3-state' and adds to `fill-prefix' | |
786 (w3-handle-p) | |
787 (let ((style (and (not (assq 'style args)) | |
788 (w3-get-default-style-info 'style)))) | |
789 (if style | |
790 (setq args (cons (cons 'style style) args)))) | |
791 ;; Default VALUE attribute for OL is 1. | |
792 (if (eq tag 'ol) | |
793 (or (assq 'value args) | |
794 (setq args (cons (cons 'value 1) args)))) | |
795 (w3-put-state :depth (1+ (w3-get-state :depth))) | |
796 (w3-set-fill-prefix-length (* (w3-get-state :depth) w3-indent-level)) | |
797 (insert "\n\n" fill-prefix " ") | |
798 (w3-put-state :lists (cons (cons tag (copy-alist args)) | |
799 (w3-get-state :lists)))) | |
800 | |
801 (defun w3-handle-table-definition (&optional args) | |
802 (w3-handle-paragraph) | |
803 (insert fill-prefix " ")) | |
804 | |
805 (defun w3-handle-table-term (&optional args) | |
806 (w3-handle-paragraph) | |
807 (insert "\n" fill-prefix)) | |
808 | |
809 (defun w3-handle-list-item (&optional args) | |
810 (w3-handle-paragraph) | |
811 (let* ((info (car (w3-get-state :lists))) | |
812 (type (car info)) | |
813 (endr (or (nth (1- (or (w3-get-state :depth) 1)) | |
814 (cdr (or (assoc type w3-list-chars-assoc) | |
815 (car w3-list-chars-assoc)))) | |
816 "*"))) | |
817 (setq info (cdr info)) | |
818 (cond | |
819 ((assq 'plain info) | |
820 ;; We still need to indent from the left margin for lists without | |
821 ;; bullets. This is especially important with nested lists. | |
822 ;; Question: Do we want this to be equivalent to replacing the | |
823 ;; bullet by a space (" ") or by indenting so that the text starts | |
824 ;; where the bullet would have been? I've chosen the latter after | |
825 ;; looking at both kinds of output. | |
826 (insert fill-prefix)) | |
827 ((eq type 'ol) | |
828 (let ((next (or (assq 'seqnum info) (assq 'value info))) | |
829 (type (cdr-safe (assq 'style info))) | |
830 (uppr (assq 'upper info)) | |
831 (tokn nil)) | |
832 (if (stringp (cdr next)) (setcdr next (string-to-int (cdr next)))) | |
833 (cond | |
834 ((or (assq 'roman info) | |
835 (member type '("i" "I"))) | |
836 (setq tokn (concat | |
837 (w3-pad-string (w3-decimal-to-roman (cdr next)) 3 ? | |
838 'left) | |
839 endr))) | |
840 ((or (assq 'arabic info) | |
841 (member type '("a" "A"))) | |
842 (setq tokn (concat (w3-pad-string | |
843 (w3-decimal-to-alpha (cdr next)) 3 ? 'left) | |
844 endr))) | |
845 (t | |
846 (setq tokn (concat (w3-pad-string (int-to-string (cdr next)) | |
847 2 ? 'left) | |
848 endr)))) | |
849 (if (assq 'uppercase info) | |
850 (setq tokn (upcase tokn))) | |
851 (insert fill-prefix tokn " ") | |
852 (setcdr next (1+ (cdr next))) | |
853 (w3-put-state :needspace 'never))) | |
854 (t | |
855 (insert fill-prefix endr " "))))) | |
856 | |
857 (defun w3-pad-string (str len pad side) | |
858 ;; Pads a string STR to a certain length LEN, using fill character | |
859 ;; PAD by concatenating PAD to SIDE of the string. | |
860 (let ((strlen (length str))) | |
861 (cond | |
862 ((>= strlen len) str) | |
863 ((eq side 'right) (concat str (make-string (- len strlen) pad))) | |
864 ((eq side 'left) (concat (make-string (- len strlen) pad) str))))) | |
865 | |
866 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
867 ;;; Routines to handle character-level formatting | |
868 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
869 (defun w3-handle-q (&optional args) | |
870 (w3-handle-emphasis) | |
871 (w3-handle-text (or (w3-get-default-style-info 'startquote) "\""))) | |
872 | |
873 (defun w3-handle-/q (&optional args) | |
874 (let ((tag (cdr-safe (assoc tag w3-end-tags)))) | |
875 (w3-handle-text (or (w3-get-default-style-info 'endquote) "\""))) | |
876 (w3-handle-emphasis-end)) | |
877 | |
878 (defun w3-handle-emphasis (&optional args) | |
879 ;; Generic handler for character-based emphasis. Increments the state | |
880 ;; of TAG (which must be bound by the calling procedure). This | |
881 ;; checks all the various stylesheet mechanisms that may cause an | |
882 ;; alignment shift as well. | |
883 (let ((align (or (w3-get-default-style-info 'align) | |
884 (and (eq tag 'address) w3-right-justify-address 'right)))) | |
885 (if (and align (not (memq tag '(h1 h2 h3 h4 h5 h6)))) | |
886 (progn | |
887 (w3-handle-paragraph) | |
888 (w3-push-alignment align)))) | |
889 (let* ((spec (and w3-delimit-emphasis (assoc tag w3-style-tags-assoc))) | |
890 (class (cdr-safe (assq 'class args))) | |
891 (face (w3-face-for-element)) | |
892 (voice (w3-voice-for-element)) | |
893 (beg (and spec (car (cdr spec))))) | |
894 (if spec | |
895 (insert beg)) | |
896 (if voice | |
897 (setq w3-active-voices (cons voice w3-active-voices))) | |
898 (if face | |
899 (setq w3-active-faces (cons face w3-active-faces))))) | |
900 | |
901 (defun w3-handle-emphasis-end (&optional args) | |
902 ;; Generic handler for ending character-based emphasis. Decrements | |
903 ;; the state of TAG (which must be bound by the calling procedure). | |
904 ;; Stylesheet mechanisms may cause arbitrary alignment changes. | |
905 (let* ((tag (cdr-safe (assq tag w3-end-tags))) | |
906 (spec (and w3-delimit-emphasis (assq tag w3-style-tags-assoc))) | |
907 (end (and spec (cdr (cdr spec))))) | |
908 (if (assq tag w3-active-voices) | |
909 (setq w3-active-voices (cdr (memq (assq tag w3-active-voices) | |
910 w3-active-voices))) | |
911 (setq w3-active-voices (delq tag w3-active-voices))) | |
912 (if (assq tag w3-active-faces) | |
913 (setq w3-active-faces (cdr (memq (assq tag w3-active-faces) | |
914 w3-active-faces))) | |
915 (setq w3-active-faces (delq tag w3-active-faces))) | |
916 (if spec (insert end)) | |
917 (if (eq tag 'address) | |
918 (progn | |
919 (w3-handle-paragraph) | |
920 (w3-pop-alignment))))) | |
921 | |
922 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
923 ;;; HTML 3.0 compliance | |
924 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
925 (defun w3-handle-math (&optional args) | |
926 (w3-handle-br) | |
927 (w3-handle-text "[START MATH - Not Implemented (Yet)]") | |
928 (w3-handle-br)) | |
929 | |
930 (defun w3-handle-/math (&optional args) | |
931 (w3-handle-br) | |
932 (w3-handle-text "[END MATH]") | |
933 (w3-handle-br)) | |
934 | |
935 (defun w3-handle-tr (&optional args) | |
936 (w3-handle-br)) | |
937 | |
938 (defun w3-handle-/tr (&optional args) | |
939 (w3-handle-br)) | |
940 | |
941 (defun w3-handle-td (&optional args) | |
942 (w3-handle-text " | ")) | |
943 | |
944 (defun w3-handle-/td (&optional args) | |
945 (w3-handle-text " | ")) | |
946 | |
947 (defun w3-handle-th (&optional args) | |
948 (w3-handle-text " | ")) | |
949 | |
950 (defun w3-handle-/th (&optional args) | |
951 (w3-handle-text " | ")) | |
952 | |
953 (defun w3-handle-table (&optional args) | |
954 (w3-handle-br)) | |
955 | |
956 (defun w3-handle-/table (&optional args) | |
957 (w3-handle-br)) | |
958 | |
959 (defun w3-handle-div (&optional args) | |
960 (let ((align (cdr-safe (assq 'align args)))) | |
961 (w3-handle-emphasis args) | |
962 (w3-handle-paragraph) | |
963 (setq align (and align (intern (downcase align)))) | |
964 (w3-push-alignment align))) | |
965 | |
966 (defun w3-handle-/div (&optional args) | |
967 (w3-handle-emphasis-end) | |
968 (let ((tag (cdr-safe (assq tag w3-end-tags)))) | |
969 (w3-handle-paragraph) | |
970 (w3-pop-alignment))) | |
971 | |
972 (defun w3-handle-note (&optional args) | |
973 (w3-handle-emphasis) | |
974 (w3-handle-paragraph) | |
975 (let ((align (or (w3-get-default-style-info 'align) 'indent))) | |
976 (w3-push-alignment align)) | |
977 (w3-handle-text (concat (or (cdr-safe (assq 'role args)) "CAUTION") ":"))) | |
978 | |
979 (defun w3-handle-/note (&optional args) | |
980 (w3-handle-paragraph) | |
981 (w3-handle-emphasis-end) | |
982 (let ((tag (cdr-safe (assoc tag w3-end-tags)))) | |
983 (w3-pop-alignment))) | |
984 | |
985 (defun w3-handle-fig (&optional args) | |
986 (w3-put-state :figdata args) | |
987 (w3-put-state :figalt (set-marker (make-marker) (point))) | |
988 ) | |
989 | |
990 (defun w3-handle-caption (&optional args) | |
991 ) | |
992 | |
993 (defun w3-handle-/caption (&optional args) | |
994 ) | |
995 | |
996 (defun w3-handle-/fig (&optional args) | |
997 (let* ((data (w3-get-state :figdata)) | |
998 (src (cdr-safe (assq 'src data))) | |
999 (aln (cdr-safe (assq 'align data))) | |
1000 (alt (if (w3-get-state :figalt) | |
1001 (prog1 | |
1002 (buffer-substring (w3-get-state :figalt) (point)) | |
1003 (delete-region (w3-get-state :figalt) (point))))) | |
1004 (ack nil)) | |
1005 (setq w3-last-fill-pos (point)) | |
1006 (if (not src) | |
1007 (w3-warn 'html "Malformed <fig> tag.") | |
1008 (setq ack (list (cons 'src src) | |
1009 (cons 'alt alt) | |
1010 (cons 'align aln))) | |
1011 (w3-handle-pre nil) | |
1012 (w3-handle-image ack) | |
1013 (w3-handle-/pre nil)))) | |
1014 | |
1015 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
1016 ;;; Netscape Compatibility | |
1017 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
1018 ; For some reason netscape treats </br> like <br> - ugh. | |
1019 (fset 'w3-handle-/br 'w3-handle-br) | |
1020 | |
1021 (defun w3-create-blank-pixmap (width height) | |
1022 (let ((retval | |
1023 (concat "/* XPM */\n" | |
1024 "static char *pixmap[] = {\n" | |
1025 ;;"/* width height num_colors chars_per_pixel */\n" | |
1026 (format "\" %d %d 2 1\",\n" width height) | |
1027 ;;"/* colors */\n" | |
1028 "\". c #000000 s background\",\n" | |
1029 "\"# c #FFFFFF s foreground\",\n" | |
1030 ;;"/* pixels /*\n" | |
1031 )) | |
1032 (line (concat "\"" (make-string width ?.) "\""))) | |
1033 (while (/= 1 height) | |
1034 (setq retval (concat retval line ",\n") | |
1035 height (1- height))) | |
1036 (concat retval line "\n};"))) | |
1037 | |
1038 (defun w3-handle-spacer (&optional args) | |
1039 (let ((type (cdr-safe (assq 'type args))) | |
1040 (size (cdr-safe (assq 'size args))) | |
1041 (w (or (cdr-safe (assq 'width args)) 1)) | |
1042 (h (or (cdr-safe (assq 'height args)) 1)) | |
1043 (align (cdr-safe (assq 'align args))) | |
1044 (glyph nil)) | |
1045 (condition-case () | |
1046 (setq glyph (make-glyph | |
1047 (vector 'xpm :data (w3-create-blank-pixmap w h)))) | |
1048 (error nil)) | |
1049 ) | |
1050 ) | |
1051 | |
1052 (defun w3-handle-font (&optional args) | |
1053 (let* ((sizearg (cdr-safe (assq 'size args))) | |
1054 (sizenum (cond | |
1055 ((null sizearg) nil) | |
1056 ((= ?+ (string-to-char sizearg)) | |
1057 (min (+ 3 (string-to-int (substring sizearg 1))) 7)) | |
1058 ((= ?- (string-to-char sizearg)) | |
1059 (max (- 3 (string-to-int (substring sizearg 1))) 0)) | |
1060 ((string= sizearg (int-to-string (string-to-int sizearg))) | |
1061 (string-to-int sizearg)) | |
1062 (t nil))) | |
1063 (family (cdr-safe (assq 'face args))) | |
1064 (color (cdr-safe (assq 'color args))) | |
1065 (normcolor (if color (w3-normalize-color color))) | |
1066 (w3-current-stylesheet (list | |
1067 (list 'font | |
1068 (list 'internal | |
1069 (cons 'font-family family) | |
1070 (cons 'font-size-index sizenum) | |
1071 (cons 'foreground normcolor)))))) | |
1072 (w3-style-post-process-stylesheet w3-current-stylesheet) | |
1073 (w3-handle-emphasis args))) | |
1074 | |
1075 (defun w3-handle-/font (&optional args) | |
1076 (w3-handle-emphasis-end)) | |
1077 | |
1078 (defun w3-handle-center (&optional args) | |
1079 (w3-handle-paragraph) | |
1080 (w3-push-alignment 'center)) | |
1081 | |
1082 (defun w3-handle-/center (&optional args) | |
1083 (w3-handle-paragraph) | |
1084 (let ((tag 'center)) | |
1085 (w3-pop-alignment))) | |
1086 | |
1087 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
1088 ;;; Bonus HTML Tags just for fun :) | |
1089 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
1090 (defun w3-handle-embed (&optional args) | |
1091 ;; This needs to be reimplemented!!! | |
1092 ) | |
1093 | |
1094 (defun w3-handle-blink (&optional args) | |
1095 ;; Keep track of all the buffers with blinking in them, and do GC | |
1096 ;; of this list whenever a new <blink> tag is encountered. The | |
1097 ;; timer checks this list to see if any of the buffers are visible, | |
1098 ;; and only blinks the face if there are any visible. This cuts | |
1099 ;; down tremendously on the amount of X traffic, and frame !@#!age | |
1100 ;; due to lots of face munging. | |
1101 (w3-handle-emphasis args) | |
1102 (let ((buffs w3-blinking-buffs) | |
1103 (name1 (buffer-name)) | |
1104 (name2 nil) | |
1105 (add t)) | |
1106 (setq w3-blinking-buffs nil) | |
1107 ;; Get rid of old buffers | |
1108 (while buffs | |
1109 (setq name2 (buffer-name (car buffs))) | |
1110 (if (null name2) | |
1111 nil | |
1112 (setq w3-blinking-buffs (cons (car buffs) w3-blinking-buffs)) | |
1113 (if (string= name1 name2) | |
1114 (setq add nil))) | |
1115 (setq buffs (cdr buffs))) | |
1116 (if add | |
1117 (setq w3-blinking-buffs (cons (current-buffer) w3-blinking-buffs))))) | |
1118 | |
1119 (defun w3-handle-/blink (&optional args) | |
1120 (w3-handle-emphasis-end args)) | |
1121 | |
1122 (defun w3-handle-peek (&optional args) | |
1123 ;; Handle the peek tag. Valid attributes are: | |
1124 ;; VARIABLE:: any valid lisp variable | |
1125 ;; If VARIABLE is bound and non-nil, then the value of the variable is | |
1126 ;; inserted at point. This can handle variables whos values are any | |
1127 ;; arbitrary lisp type. | |
1128 (let* ((var-name (cdr-safe (assq 'variable args))) | |
1129 (var-sym (and var-name (intern var-name))) | |
1130 (val (and var-sym (boundp var-sym) (symbol-value var-sym)))) | |
1131 (cond | |
1132 ((null val) nil) | |
1133 ((stringp val) (w3-handle-text val)) | |
1134 (t (w3-handle-text (format "%S" val)))))) | |
1135 | |
1136 (defun w3-rotate-region (st nd &optional rotation) | |
1137 "Ceasar rotate a region between ST and ND using ROTATION as the | |
1138 amount to rotate the text. Defaults to caesar (13)." | |
1139 (setq rotation (or rotation 13)) | |
1140 (save-excursion | |
1141 (let (x) | |
1142 (while (< st nd) | |
1143 (setq x (char-after st)) | |
1144 (cond | |
1145 ((and (>= x ?a) (<= x ?z)) | |
1146 (setq x (- x ?a) | |
1147 x (char-to-string (+ (% (+ x rotation) 26) ?a)))) | |
1148 ((and (>= x ?A) (<= x ?Z)) | |
1149 (setq x (- x ?A) | |
1150 x (char-to-string (+ (% (+ x rotation) 26) ?A)))) | |
1151 (t (setq x nil))) | |
1152 (if x (progn (goto-char st) (delete-char 1) (insert x))) | |
1153 (setq st (1+ st)))))) | |
1154 | |
1155 (defun w3-handle-kill-sgml (&optional args) | |
1156 (w3-handle-text "SGML is the spawn of evil! It must be stopped!")) | |
1157 | |
1158 (defun w3-handle-secret (&optional args) | |
1159 (if (fboundp 'valid-specifier-locale-p) | |
1160 (let ((tag 'rot13)) | |
1161 (w3-handle-emphasis)) | |
1162 (w3-put-state :secret (set-marker (make-marker) (point))))) | |
1163 | |
1164 (defun w3-handle-/secret (&optional args) | |
1165 "Close a secret region of text." | |
1166 (if (fboundp 'valid-specifier-locale-p) | |
1167 (let ((tag '/rot13)) | |
1168 (w3-handle-emphasis-end)) | |
1169 (if (integer-or-marker-p (w3-get-state :secret)) | |
1170 (progn | |
1171 (w3-rotate-region (w3-get-state :secret) (point)) | |
1172 (w3-put-state :secret nil))))) | |
1173 | |
1174 (defun w3-handle-hype (&optional args) | |
1175 (if (and (or (featurep 'nas-sound) (featurep 'native-sound)) | |
1176 (assoc 'hype sound-alist)) | |
1177 (play-sound 'hype 100) | |
1178 (w3-handle-text "Hey, has Marca A. told you how cool he is?"))) | |
1179 | |
1180 (defun w3-handle-yogsothoth (&optional args) | |
1181 (w3-handle-image (list (cons 'src "href-to-yogsothoth-pic") | |
1182 (cons 'alt "YOGSOTHOTH LIVES!!!")))) | |
1183 | |
1184 (defun w3-handle-roach (&optional args) | |
1185 (w3-handle-text "Man, I am so wasted...")) | |
1186 | |
1187 (defun w3-handle-/roach (&optional args) | |
1188 (w3-handle-text (concat "So, you wanna get some " | |
1189 (or (cdr-safe (assq 'munchy args)) | |
1190 "nachos") "? "))) | |
1191 | |
1192 (defun w3-invert-face (face) | |
1193 (let ((buffs w3-blinking-buffs) | |
1194 (blink nil) | |
1195 (buff nil)) | |
1196 (if buffs | |
1197 (while buffs | |
1198 (setq buff (car buffs)) | |
1199 (cond | |
1200 ((bufferp buff) | |
1201 (if (buffer-name buff) | |
1202 (setq buff (car buffs)) | |
1203 (setq buff nil))) | |
1204 ((stringp buff) | |
1205 (setq buff (get-buffer buff))) | |
1206 (t | |
1207 (setq buff nil))) | |
1208 (setq buffs (cdr buffs) | |
1209 buff (and buff (get-buffer-window buff 'visible)) | |
1210 buff (and buff (window-live-p buff))) | |
1211 (if buff (setq buffs nil | |
1212 blink t)))) | |
1213 (if blink (invert-face face)))) | |
1214 | |
1215 (autoload 'sentence-ify "flame") | |
1216 (autoload 'string-ify "flame") | |
1217 (autoload '*flame "flame") | |
1218 (if (not (fboundp 'flatten)) (autoload 'flatten "flame")) | |
1219 | |
1220 (defvar w3-cookie-cache nil) | |
1221 | |
1222 (defun w3-handle-cookie (&optional args) | |
1223 (if (not (fboundp 'cookie)) | |
1224 (w3-handle-text "Sorry, no cookies today.") | |
1225 (let* ((url-working-buffer (url-generate-new-buffer-name " *cookie*")) | |
1226 (href (url-expand-file-name | |
1227 (or (cdr-safe (assq 'src args)) | |
1228 (cdr-safe (assq 'href args))) | |
1229 (cdr-safe (assoc (cdr-safe (assq 'base args)) | |
1230 w3-base-alist)))) | |
1231 (fname (or (cdr-safe (assoc href w3-cookie-cache)) | |
1232 (url-generate-unique-filename "%s.cki"))) | |
1233 (st (or (cdr-safe (assq 'start args)) "Loading cookies...")) | |
1234 (nd (or (cdr-safe (assq 'end args)) | |
1235 "Loading cookies... done."))) | |
1236 (if (not (assoc href w3-cookie-cache)) | |
1237 (save-excursion | |
1238 (url-clear-tmp-buffer) | |
1239 (setq url-be-asynchronous nil) | |
1240 (url-retrieve href) | |
1241 (url-uncompress) | |
1242 (write-region (point-min) (point-max) fname 5) | |
1243 (setq w3-cookie-cache (cons (cons href fname) w3-cookie-cache)))) | |
1244 (w3-handle-text (cookie fname st nd))))) | |
1245 | |
1246 (defun w3-handle-flame (&optional args) | |
1247 (condition-case () | |
1248 (w3-handle-text | |
1249 (concat | |
1250 (sentence-ify | |
1251 (string-ify | |
1252 (append-suffixes-hack (flatten (*flame))))))) | |
1253 (error nil))) | |
1254 | |
1255 (defun w3-handle-pinhead (&optional args) | |
1256 (if (fboundp 'yow) | |
1257 (w3-handle-text (yow)))) | |
1258 | |
1259 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
1260 ;;; Client-side Imagemaps | |
1261 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
1262 (defun w3-handle-map (&optional args) | |
1263 (w3-put-state :map (cons (or (cdr-safe (assq 'name args)) | |
1264 (cdr-safe (assq 'id args)) | |
1265 "unnamed") nil))) | |
1266 | |
1267 (defun w3-handle-/map (&optional args) | |
1268 (and (w3-get-state :map) | |
1269 (setq w3-imagemaps (cons (w3-get-state :map) w3-imagemaps))) | |
1270 (w3-put-state :map nil)) | |
1271 | |
1272 (defun w3-decode-area-coords (str) | |
1273 (let (retval) | |
1274 (while (string-match "\\([ \t0-9]+\\),\\([ \t0-9]+\\)" str) | |
1275 (setq retval (cons (vector (string-to-int (match-string 1 str)) | |
1276 (string-to-int (match-string 2 str))) retval) | |
1277 str (substring str (match-end 0) nil))) | |
1278 (if (string-match "\\([0-9]+\\)" str) | |
1279 (setq retval (cons (vector (+ (aref (car retval) 0) | |
1280 (string-to-int (match-string 1 str))) | |
1281 (aref (car retval) 1)) retval))) | |
1282 (nreverse retval))) | |
1283 | |
1284 (defun w3-handle-area (&optional args) | |
1285 (let ((type (downcase (or (cdr-safe (assq 'shape args)) "rect"))) | |
1286 (coords (w3-decode-area-coords (or (cdr-safe (assq 'coords args)) ""))) | |
1287 (alt (cdr-safe (assq 'alt args))) | |
1288 (href (if (assq 'nohref args) | |
1289 t | |
1290 (url-expand-file-name | |
1291 (or (cdr-safe (assq 'src args)) | |
1292 (cdr-safe (assq 'href args))) | |
1293 (cdr-safe (assoc (cdr-safe (assq 'base args)) | |
1294 w3-base-alist))))) | |
1295 (map (w3-get-state :map))) | |
1296 ;; data structure in storage is a vector | |
1297 ;; if (href == t) then no action should be taken | |
1298 ;; [ type coordinates href (hopefully)descriptive-text] | |
1299 (setcdr map (cons (vector type coords href alt) (cdr map))))) | |
1300 | |
1301 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
1302 ;;; Tags that don't really get drawn, etc. | |
1303 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
1304 (defun w3-handle-/html (&optional args) | |
1305 ;; Technically, we are not supposed to have any text outside the | |
1306 ;; html element, so start ignoring everything. | |
1307 (put 'text 'w3-formatter 'ack)) | |
1308 | |
1309 (defun w3-handle-body (&optional args) | |
1310 (if (not w3-user-colors-take-precedence) | |
1311 (let* ((vlink (cdr-safe (assq 'vlink args))) | |
1312 (alink (cdr-safe (assq 'alink args))) | |
1313 (link (cdr-safe (assq 'link args))) | |
1314 (text (cdr-safe (assq 'text args))) | |
1315 (backg (cdr-safe (assq 'background args))) | |
1316 (rgb (or (cdr-safe (assq 'bgcolor args)) | |
1317 (cdr-safe (assq 'rgb args)))) | |
1318 (temp-face nil) | |
1319 (sheet "")) | |
1320 (setq backg (url-expand-file-name | |
1321 backg | |
1322 (cdr-safe (assoc (cdr-safe (assq 'base args)) | |
1323 w3-base-alist)))) | |
1324 (if (or text rgb backg) | |
1325 (progn | |
1326 (setq sheet "html {") | |
1327 (if text (setq sheet (format "%scolor: %s; " sheet | |
1328 (w3-normalize-color text)))) | |
1329 (if rgb (setq sheet (format "%sbackground: %s; " | |
1330 sheet (w3-normalize-color rgb)))) | |
1331 (if backg (setq sheet (format "%sbackdrop: %s; " | |
1332 sheet backg))) | |
1333 (setq sheet (concat sheet " }\n")))) | |
1334 (if link | |
1335 (setq sheet (format "%sa.link { color: %s }\n" sheet | |
1336 (w3-normalize-color link)))) | |
1337 (if vlink | |
1338 (setq sheet (format "%sa.visited { color: %s }\n" sheet | |
1339 (w3-normalize-color vlink)))) | |
1340 (if alink | |
1341 (setq sheet (format "%sa.active { color: %s }\n" sheet | |
1342 (w3-normalize-color alink)))) | |
1343 (if (/= (length sheet) 0) | |
1344 (w3-handle-style (list (cons 'data sheet) | |
1345 (cons 'notation "css"))))))) | |
1346 | |
1347 (defun w3-handle-cryptopts (&optional args) | |
1348 (put 'text 'w3-formatter 'ack)) | |
1349 | |
1350 (defun w3-handle-/cryptopts (&optional args) | |
1351 (put 'text 'w3-formatter nil)) | |
1352 | |
1353 (defun w3-handle-certs (&optional args) | |
1354 (put 'text 'w3-formatter 'ack)) | |
1355 | |
1356 (defun w3-handle-/certs (&optional args) | |
1357 (put 'text 'w3-formatter nil)) | |
1358 | |
1359 (defun w3-handle-base (&optional args) | |
1360 (setq w3-base-alist (cons | |
1361 (cons (or (cdr-safe (assq 'name args)) | |
1362 (cdr-safe (assq 'id args))) | |
1363 (or (cdr-safe (assq 'href args)) | |
1364 (cdr-safe (assq 'src args)) | |
1365 (url-view-url t))) | |
1366 w3-base-alist))) | |
1367 | |
1368 (defun w3-handle-isindex (&optional args) | |
1369 (let ((prompt (or (cdr-safe (assq 'prompt args)) | |
1370 "Search on (+ separates keywords): ")) | |
1371 action) | |
1372 (setq action (url-expand-file-name | |
1373 (or (cdr-safe (assq 'src args)) | |
1374 (cdr-safe (assq 'href args)) | |
1375 (url-view-url t)) | |
1376 (cdr-safe (assoc (cdr-safe (assq 'base args)) | |
1377 w3-base-alist)))) | |
1378 (if (and prompt (string-match "[^: \t-]+$" prompt)) | |
1379 (setq prompt (concat prompt ": "))) | |
1380 (if w3-use-forms-index | |
1381 (progn | |
1382 (w3-handle-hr) | |
1383 (w3-handle-form (list (cons 'action action) | |
1384 (cons 'enctype "application/x-w3-isindex") | |
1385 (cons 'method "get"))) | |
1386 (w3-handle-text (concat prompt " ")) | |
1387 (w3-handle-input (list (cons 'type "text") | |
1388 (cons 'name "isindex"))))) | |
1389 (setq w3-current-isindex (cons action prompt)))) | |
1390 | |
1391 (defun w3-handle-meta (&optional args) | |
1392 (let* ((equiv (cdr-safe (assq 'http-equiv args))) | |
1393 (value (cdr-safe (assq 'content args))) | |
1394 (node (and equiv (assoc (setq equiv (downcase equiv)) | |
1395 url-current-mime-headers)))) | |
1396 (if equiv | |
1397 (setq url-current-mime-headers (cons (cons equiv value) | |
1398 url-current-mime-headers))) | |
1399 ;; Special-case the Set-Cookie header | |
1400 (if (and equiv (string= (downcase equiv) "set-cookie")) | |
1401 (url-cookie-handle-set-cookie value)) | |
1402 ;; Special-case the refresh header | |
1403 (if (and equiv (string= (downcase equiv) "refresh")) | |
1404 (url-handle-refresh-header value)))) | |
1405 | |
1406 (defun w3-handle-link (&optional args) | |
1407 (let* ((dest (cdr-safe (assq 'href args))) | |
1408 (type (if (assq 'rel args) "Parent of" "Child of")) | |
1409 (desc (or (cdr-safe (assq 'rel args)) | |
1410 (cdr-safe (assq 'rev args)))) | |
1411 (node-1 (assoc type w3-current-links)) | |
1412 (node-2 (and node-1 desc (assoc desc (cdr node-1)))) | |
1413 (base (cdr-safe (assq 'base args)))) | |
1414 (if dest | |
1415 (progn | |
1416 (setq dest (url-expand-file-name | |
1417 dest | |
1418 (cdr-safe (assoc base w3-base-alist)))) | |
1419 (cond | |
1420 (node-2 ; Add to old value | |
1421 (setcdr node-2 (cons dest (cdr node-2)))) | |
1422 (node-1 ; first rel/rev | |
1423 (setcdr node-1 (cons (cons desc (list dest)) (cdr node-1)))) | |
1424 (t (setq w3-current-links | |
1425 (cons (cons type (list (cons desc (list dest)))) | |
1426 w3-current-links)))) | |
1427 (if (and dest desc (member (downcase desc) | |
1428 '("style" "stylesheet"))) | |
1429 (w3-handle-style (list (cons 'src dest)))))))) | |
1430 | |
1431 (defun w3-maybe-start-image-download (widget) | |
1432 (let* ((src (widget-get widget 'src)) | |
1433 (cached-glyph (w3-image-cached-p src))) | |
1434 (if (and cached-glyph (w3-glyphp cached-glyph)) | |
1435 (setq w3-image-widgets-waiting (cons widget w3-image-widgets-waiting)) | |
1436 (cond | |
1437 ((or w3-delay-image-loads (not (fboundp 'valid-specifier-domain-p))) | |
1438 (w3-add-delayed-graphic widget)) | |
1439 ((not (w3-image-loadable-p src nil)) ; Hey, we can't load it! | |
1440 (w3-warn 'images (format "Skipping image %s" (url-basepath src t))) | |
1441 (w3-add-delayed-graphic widget)) | |
1442 (t ; Grab the images | |
1443 (let ( | |
1444 (url-request-method "GET") | |
1445 (old-asynch url-be-asynchronous) | |
1446 (url-request-data nil) | |
1447 (url-request-extra-headers nil) | |
1448 (url-source t) | |
1449 (url-mime-accept-string (substring | |
1450 (mapconcat | |
1451 (function | |
1452 (lambda (x) | |
1453 (if x | |
1454 (concat (car x) ",") | |
1455 ""))) | |
1456 w3-allowed-image-types "") | |
1457 0 -1)) | |
1458 (url-working-buffer (generate-new-buffer-name " *W3GRAPH*"))) | |
1459 (setq-default url-be-asynchronous t) | |
1460 (setq w3-graphics-list (cons (cons src (make-glyph)) | |
1461 w3-graphics-list)) | |
1462 (save-excursion | |
1463 (set-buffer (get-buffer-create url-working-buffer)) | |
1464 (setq url-current-callback-data (list widget) | |
1465 url-be-asynchronous t | |
1466 url-current-callback-func 'w3-finalize-image-download) | |
1467 (url-retrieve src)) | |
1468 (setq-default url-be-asynchronous old-asynch))))))) | |
1469 | |
1470 (defun w3-finalize-image-download (widget) | |
1471 (let ((glyph nil) | |
1472 (url (widget-get widget 'src)) | |
1473 (node nil) | |
1474 (buffer (widget-get widget 'buffer))) | |
1475 (message "Enhancing image...") | |
1476 (setq glyph (image-normalize (cdr-safe (assoc url-current-mime-type | |
1477 w3-image-mappings)) | |
1478 (buffer-string))) | |
1479 (message "Enhancing image... done") | |
1480 (kill-buffer (current-buffer)) | |
1481 (cond | |
1482 ((w3-image-invalid-glyph-p glyph) | |
1483 (w3-warn 'image (format "Reading of %s failed." url))) | |
1484 ((eq (aref glyph 0) 'xbm) | |
1485 (let ((temp-fname (url-generate-unique-filename "%s.xbm"))) | |
1486 (save-excursion | |
1487 (set-buffer (generate-new-buffer " *xbm-garbage*")) | |
1488 (erase-buffer) | |
1489 (insert (aref glyph 2)) | |
1490 (setq glyph temp-fname) | |
1491 (write-region (point-min) (point-max) temp-fname) | |
1492 (kill-buffer (current-buffer))) | |
1493 (setq glyph (make-glyph (list (cons 'x glyph)))) | |
1494 (condition-case () | |
1495 (delete-file temp-fname) | |
1496 (error nil)))) | |
1497 (t | |
1498 (setq glyph (make-glyph glyph)))) | |
1499 (setq node (assoc url w3-graphics-list)) | |
1500 (if node | |
1501 (set-glyph-image (cdr node) (glyph-image glyph)) | |
1502 (setq w3-graphics-list (cons (cons url glyph) w3-graphics-list))) | |
1503 | |
1504 (if (and (buffer-name buffer) ; Dest. buffer exists | |
1505 (w3-glyphp glyph)) ; got a valid glyph | |
1506 (save-excursion | |
1507 (set-buffer buffer) | |
1508 (if (eq major-mode 'w3-mode) | |
1509 (widget-value-set widget glyph) | |
1510 (setq w3-image-widgets-waiting | |
1511 (cons widget w3-image-widgets-waiting))))))) | |
1512 | |
1513 (defun w3-handle-image (&optional args) | |
1514 (let* ((parms args) | |
1515 (height (cdr-safe (assq 'height parms))) | |
1516 (width (cdr-safe (assq 'width parms))) | |
1517 (src (or (cdr-safe (assq 'src parms)) | |
1518 "Error Image")) | |
1519 (our-alt (cond | |
1520 ((null w3-auto-image-alt) "") | |
1521 ((eq t w3-auto-image-alt) | |
1522 (concat "[IMAGE(" (url-basepath src t) ")] ")) | |
1523 ((stringp w3-auto-image-alt) | |
1524 (format w3-auto-image-alt (url-basepath src t))))) | |
1525 (alt (or (cdr-safe (assq 'alt parms)) | |
1526 our-alt)) | |
1527 (ismap (and (assq 'ismap args) 'ismap)) | |
1528 (usemap (cdr-safe (assq 'usemap args))) | |
1529 (dest (w3-get-state :href)) | |
1530 (base (cdr-safe (assq 'base args))) | |
1531 (widget nil) | |
1532 (zone (w3-get-state :zone)) | |
1533 (align (intern (or (cdr-safe (assq 'align parms)) "middle")))) | |
1534 (setq src (url-expand-file-name src | |
1535 (cdr-safe (assoc base w3-base-alist)))) | |
1536 (if dest | |
1537 (w3-handle-hyperlink-end)) | |
1538 (setq widget | |
1539 (widget-create 'image | |
1540 'src src ; Where to load the image from | |
1541 'alt alt ; Textual replacement | |
1542 'ismap ismap ; Is it a server-side map? | |
1543 'usemap usemap ; Is it a client-side map? | |
1544 'href dest ; Hyperlink destination | |
1545 )) | |
1546 (widget-put widget 'buffer (current-buffer)) | |
1547 (w3-maybe-start-image-download widget) | |
1548 (goto-char (point-max)) | |
1549 (if dest | |
1550 (w3-handle-hyperlink (list (cons 'href dest)))))) | |
1551 | |
1552 (defun w3-handle-title (&optional args) | |
1553 (if (w3-get-state :title) | |
1554 (w3-put-state :title nil)) | |
1555 (put 'text 'w3-formatter 'w3-handle-title-text)) | |
1556 | |
1557 (defun w3-handle-title-text (&optional args) | |
1558 (w3-put-state :title | |
1559 (concat (w3-get-state :title) args))) | |
1560 | |
1561 (defun w3-handle-/title (&optional args) | |
1562 (put 'text 'w3-formatter nil) | |
1563 (let ((ttl (w3-get-state :title))) | |
1564 (if (not (stringp ttl)) | |
1565 nil | |
1566 (setq ttl (w3-fix-spaces ttl)) | |
1567 (if (and ttl (string= ttl "")) | |
1568 (setq ttl (w3-fix-spaces (url-view-url t)))) | |
1569 (rename-buffer (url-generate-new-buffer-name ttl)) | |
1570 ;; Make the URL show in list-buffers output | |
1571 (make-local-variable 'list-buffers-directory) | |
1572 (setq list-buffers-directory (url-view-url t)) | |
1573 (w3-put-state :title t)))) | |
1574 | |
1575 (fset 'w3-handle-/head 'w3-handle-/title) | |
1576 | |
1577 (defun w3-handle-hyperlink (&optional args) | |
1578 (let* ((href-node (assq 'href args)) | |
1579 (href (cdr href-node)) | |
1580 (title (cdr-safe (assq 'title args))) | |
1581 (base (cdr-safe (assq 'base args))) | |
1582 (name (or (cdr-safe (assq 'id args)) | |
1583 (cdr-safe (assq 'name args))))) | |
1584 (if href | |
1585 (progn | |
1586 (setq href (url-expand-file-name href (cdr-safe | |
1587 (assoc base w3-base-alist)))) | |
1588 (setcdr href-node href))) | |
1589 (w3-put-state :seen-this-url (url-have-visited-url href)) | |
1590 (w3-put-state :zone (point)) | |
1591 (w3-put-state :link-args args) | |
1592 (if title (w3-put-state :link-title title)) | |
1593 (if href (w3-put-state :href href)) | |
1594 (if name (w3-put-state :name name)))) | |
1595 | |
1596 (defun w3-follow-hyperlink (widget &rest ignore) | |
1597 (let* ((target (widget-get widget 'target)) | |
1598 (href (widget-get widget 'href)) | |
1599 (tag 'a) | |
1600 (args '((class . "visited"))) | |
1601 (face (cdr (w3-face-for-element))) | |
1602 (old-face (and (widget-get widget :from) | |
1603 (get-text-property (widget-get widget :from) 'face))) | |
1604 (faces (cond | |
1605 ((and old-face (consp old-face)) (cons face old-face)) | |
1606 (old-face (cons face (list old-face))) | |
1607 (t (list face))))) | |
1608 (if target (setq target (intern (downcase target)))) | |
1609 (put-text-property (widget-get widget :from) (widget-get widget :to) | |
1610 'face faces) | |
1611 (case target | |
1612 ((_blank external) | |
1613 (w3-fetch-other-frame href)) | |
1614 (_top | |
1615 (delete-other-windows) | |
1616 (w3-fetch href)) | |
1617 (otherwise | |
1618 (w3-fetch href))))) | |
1619 | |
1620 (defun w3-balloon-help-callback (object &optional event) | |
1621 (let* ((widget (widget-at (extent-start-position object))) | |
1622 (href (and widget (widget-get widget 'href)))) | |
1623 (if href | |
1624 (url-truncate-url-for-viewing href) | |
1625 nil))) | |
1626 | |
1627 (defun w3-handle-hyperlink-end (&optional args) | |
1628 (let* ((href (w3-get-state :href)) | |
1629 (old-args (w3-get-state :link-args)) | |
1630 (name (w3-get-state :name)) | |
1631 (zone (w3-get-state :zone)) | |
1632 (btdt (and href (w3-get-state :seen-this-url))) | |
1633 (tag 'a) | |
1634 (args (list (cons 'class (if btdt "visited" "link")))) | |
1635 (face (cdr (w3-face-for-element))) | |
1636 (old-face (and zone (get-text-property zone 'face))) | |
1637 (faces (cond | |
1638 ((and old-face (consp old-face)) (cons face old-face)) | |
1639 (old-face (cons face (list old-face))) | |
1640 (t (list face))))) | |
1641 (if (not href) | |
1642 nil | |
1643 (add-text-properties zone (point) | |
1644 (list 'mouse-face 'highlight | |
1645 'button | |
1646 (append | |
1647 (list 'push :args nil :value "" :tag "" | |
1648 :notify 'w3-follow-hyperlink | |
1649 :from (set-marker (make-marker) zone) | |
1650 :to (set-marker (make-marker) (point)) | |
1651 ) | |
1652 (alist-to-plist old-args)) | |
1653 'face faces | |
1654 'balloon-help 'w3-balloon-help-callback | |
1655 'title (cons | |
1656 (set-marker (make-marker) zone) | |
1657 (set-marker (make-marker) (point))) | |
1658 'help-echo href)) | |
1659 (w3-put-state :zone nil) | |
1660 (w3-put-state :href nil) | |
1661 (w3-put-state :name nil) | |
1662 (if (and w3-link-info-display-function | |
1663 (fboundp w3-link-info-display-function)) | |
1664 (let ((info (condition-case () | |
1665 (funcall w3-link-info-display-function href) | |
1666 (error nil)))) | |
1667 (if (and info (stringp info)) | |
1668 (w3-handle-text info))))))) | |
1669 | |
1670 (defvar w3-tab-alist nil | |
1671 "An assoc list of tab stops and their respective IDs") | |
1672 (make-variable-buffer-local 'w3-tab-alist) | |
1673 | |
1674 (defun w3-handle-tab (&optional args) | |
1675 (let* ((id (cdr-safe (assq 'id args))) | |
1676 (to (cdr-safe (assq 'to args))) | |
1677 (pos (cdr-safe (assoc to w3-tab-alist)))) | |
1678 (cond | |
1679 (id ; Define a new tab stop | |
1680 (setq w3-tab-alist (cons (cons id (current-column)) w3-tab-alist))) | |
1681 ((and to pos) ; Go to a currently defined tabstop | |
1682 (while (<= (current-column) pos) | |
1683 (insert " "))) | |
1684 (to ; Tabstop 'to' is no defined yet | |
1685 (w3-warn 'html (format "Unkown tab stop -- `%s'" to))) | |
1686 (t ; Just do a tab | |
1687 (insert (make-string w3-indent-level ? )))))) | |
1688 | |
1689 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
1690 ;;; Some bogus shit for pythia | |
1691 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
1692 (defun w3-handle-margin (&optional args) | |
1693 (if (assq 'reset args) | |
1694 (w3-handle-/blockquote nil) | |
1695 (w3-handle-blockquote nil))) | |
1696 | |
1697 (fset 'w3-handle-l 'w3-handle-br) | |
1698 | |
1699 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
1700 ;;; Guts of the forms interface for the new display engine | |
1701 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
1702 (defun w3-handle-form (&optional args) | |
1703 (let ((actn (cdr-safe (assq 'action args))) | |
1704 (enct (cdr-safe (assq 'enctype args))) | |
1705 (meth (cdr-safe (assq 'method args)))) | |
1706 (if (not meth) (setq args (cons (cons 'method "GET") args))) | |
1707 (if (not actn) | |
1708 (setq args (cons (cons 'action | |
1709 (or | |
1710 (cdr-safe (assoc (cdr-safe (assq 'base args)) | |
1711 w3-base-alist)) | |
1712 (url-view-url t))) args)) | |
1713 (setcdr (assq 'action args) | |
1714 (url-expand-file-name | |
1715 actn | |
1716 (cdr-safe (assoc (cdr-safe (assq 'base args)) | |
1717 w3-base-alist))))) | |
1718 (if (not enct) | |
1719 (setq args | |
1720 (cons (cons 'enctype "application/x-www-form-urlencoded") | |
1721 args))) | |
1722 (w3-put-state :form args))) | |
1723 | |
1724 (defun w3-handle-/form (&optional args) | |
1725 (w3-handle-paragraph) | |
1726 (w3-put-state :form nil) | |
1727 (w3-put-state :formnum (1+ (w3-get-state :formnum))) | |
1728 ) | |
1729 | |
1730 (defun w3-handle-keygen (&optional args) | |
1731 (w3-form-add-element 'keygen | |
1732 (or (cdr-safe (assq 'name args)) "") | |
1733 nil | |
1734 nil | |
1735 1000 | |
1736 nil | |
1737 (w3-get-state :form) | |
1738 nil | |
1739 (w3-get-state :formnum) | |
1740 nil | |
1741 (w3-face-for-element))) | |
1742 | |
1743 (defun w3-handle-input (&optional args) | |
1744 (if (or (not (w3-get-state :form)) | |
1745 (w3-get-state :select)) | |
1746 (w3-warn | |
1747 'html | |
1748 "<input> outside of a <form> or inside <select> construct - ERROR!!") | |
1749 (let* ((type (intern (downcase (or (cdr-safe (assq 'type args)) "text")))) | |
1750 (name (cdr-safe (assq 'name args))) | |
1751 (value (or (cdr-safe (assq 'value args)) "")) | |
1752 (size (string-to-int (or (cdr-safe (assq 'size args)) "20"))) | |
1753 (maxlength (cdr (assoc 'maxlength args))) | |
1754 (default value) | |
1755 (action (w3-get-state :form)) | |
1756 (options) | |
1757 (num (w3-get-state :formnum)) | |
1758 (id (cdr-safe (assq 'id args))) | |
1759 (checked (assq 'checked args)) | |
1760 (face (w3-face-for-element))) | |
1761 (if (and (string-match "^[ \t\n\r]+$" value) | |
1762 (not (eq type 'hidden))) | |
1763 (setq value "")) | |
1764 (if maxlength (setq maxlength (string-to-int maxlength))) | |
1765 (if (and name (string-match "[\r\n]" name)) | |
1766 (setq name (mapconcat (function | |
1767 (lambda (x) | |
1768 (if (memq x '(?\r ?\n)) | |
1769 "" | |
1770 (char-to-string x)))) | |
1771 name ""))) | |
1772 (if (memq type '(checkbox radio)) (setq default checked)) | |
1773 (if (and (eq type 'checkbox) (string= value "")) | |
1774 (setq value "on")) | |
1775 (w3-form-add-element type name value size maxlength default action | |
1776 options num id checked face)))) | |
1777 | |
1778 (defun w3-handle-/select (&optional args) | |
1779 (if (not (and (w3-get-state :form) | |
1780 (w3-get-state :select))) | |
1781 (w3-warn 'html | |
1782 "</select> outside of a <form> or <select> construct - ERROR!!") | |
1783 (put 'text 'w3-formatter 'w3-handle-text) | |
1784 (let* ((args (w3-get-state :select)) | |
1785 (tag 'input) | |
1786 (face (w3-face-for-element)) | |
1787 (opts (w3-get-state :options)) | |
1788 (form (w3-get-state :form)) | |
1789 (max-size nil) | |
1790 (type "OPTION") | |
1791 (default nil) | |
1792 (tmp nil) | |
1793 (id (cdr-safe (assq 'id args))) | |
1794 (checked nil) | |
1795 ) | |
1796 (setq tmp (reverse opts)) | |
1797 (if (assq 'multiple args) | |
1798 (let ((tag 'ul) ; Convert to a list of checkboxes | |
1799 (nam (or (cdr-safe (assq 'name args)) "option")) | |
1800 (old (w3-get-state :align)) | |
1801 (first nil)) | |
1802 (w3-put-state :options nil) | |
1803 (w3-put-state :select nil) | |
1804 (w3-handle-list-opening) | |
1805 (w3-put-state :align nil) | |
1806 (while tmp | |
1807 (w3-handle-list-item) | |
1808 (w3-handle-input (list (cons 'type "checkbox") | |
1809 (cons 'name nam) | |
1810 (cons 'value | |
1811 (or (cdr-safe | |
1812 (assq 'value (car tmp))) | |
1813 (cdr-safe | |
1814 (assoc 'ack (car tmp))) | |
1815 "unknown")) | |
1816 (if (or (assq 'checked (car tmp)) | |
1817 (assq 'selected (car tmp))) | |
1818 (cons 'checked "checked")))) | |
1819 (w3-handle-text (concat " " (or | |
1820 (cdr-safe (assq 'ack (car tmp))) | |
1821 "unknown"))) | |
1822 (setq tmp (cdr tmp))) | |
1823 (w3-handle-list-ending) | |
1824 (w3-put-state :align old)) | |
1825 (while (and (not default) tmp) | |
1826 (if (or (assq 'checked (car tmp)) | |
1827 (assq 'selected (car tmp))) | |
1828 (setq default (car tmp))) | |
1829 (setq tmp (cdr tmp))) | |
1830 (setq default (cdr (assq 'ack (or default | |
1831 (nth (1- (length opts)) opts)))) | |
1832 checked (mapcar | |
1833 (function | |
1834 (lambda (x) | |
1835 (cons (cdr-safe (assq 'ack x)) | |
1836 (or (cdr-safe (assq 'value x)) | |
1837 (cdr-safe (assq 'ack x)))))) | |
1838 opts) | |
1839 max-size (car (sort (mapcar | |
1840 (function | |
1841 (lambda (x) | |
1842 (length (cdr-safe (assq 'ack x))))) | |
1843 opts) | |
1844 '>))) | |
1845 (if (and form args opts) | |
1846 (let ((pos (point)) | |
1847 (siz (max max-size | |
1848 (string-to-int | |
1849 (or (cdr-safe (assq 'size args)) "0"))))) | |
1850 (w3-form-add-element 'option | |
1851 (or (cdr-safe (assq 'name args)) "option") | |
1852 default | |
1853 siz | |
1854 (string-to-int | |
1855 (or (cdr-safe (assq 'maxlength args)) | |
1856 "1000")) | |
1857 default | |
1858 (w3-get-state :form) | |
1859 checked | |
1860 (w3-get-state :formnum) | |
1861 nil checked face))))) | |
1862 (w3-put-state :options nil) | |
1863 (w3-put-state :select nil))) | |
1864 | |
1865 (defun w3-handle-option-data (&optional args) | |
1866 (let ((text (cond | |
1867 ((null args) nil) | |
1868 ((stringp args) args) | |
1869 ((listp args) (mapconcat 'identity args " "))))) | |
1870 (if text | |
1871 (progn | |
1872 (setq text (url-strip-leading-spaces | |
1873 (url-eat-trailing-space text))) | |
1874 (w3-put-state :options (cons (cons (cons 'ack text) | |
1875 (w3-get-state :optargs)) | |
1876 (w3-get-state :options)))))) | |
1877 (put 'text 'w3-formatter 'w3-handle-text)) | |
1878 | |
1879 (defun w3-handle-option (&optional args) | |
1880 (if (not (and (w3-get-state :form) | |
1881 (w3-get-state :select))) | |
1882 (w3-warn 'html | |
1883 "<option> outside of a <form> or <select> construct - ERROR!!") | |
1884 (w3-put-state :optargs args) | |
1885 (put 'text 'w3-formatter 'w3-handle-option-data))) | |
1886 | |
1887 (defun w3-handle-select (&optional args) | |
1888 (if (not (w3-get-state :form)) | |
1889 (w3-warn 'html "<select> outside of a <FORM> construct - ERROR!!") | |
1890 (w3-put-state :select args)) | |
1891 ) | |
1892 | |
1893 (defun w3-handle-textarea (&optional args) | |
1894 (if (not (w3-get-state :form)) | |
1895 (w3-warn 'html "<textarea> outside of a <FORM> construct - ERROR!!") | |
1896 (let ((node (assq 'maxlength args))) | |
1897 (cond | |
1898 ((null node) | |
1899 (setq args (cons (cons 'maxlength nil) args))) | |
1900 ((null (cdr-safe node)) | |
1901 nil) | |
1902 ((string= (downcase (cdr-safe node)) "unlimited") | |
1903 (setcdr node nil)))) | |
1904 (let* ( | |
1905 (face (let ((tag 'input) | |
1906 (args nil)) | |
1907 (w3-face-for-element))) | |
1908 (value (cdr-safe (assq 'data args))) | |
1909 (type "TEXTAREA") | |
1910 (name (cdr-safe (assq 'name args))) | |
1911 (size (string-to-int (or (cdr-safe (assq 'size args)) "20"))) | |
1912 (maxlength (string-to-int | |
1913 (or (cdr (assq 'maxlength args)) "10000"))) | |
1914 (default nil) | |
1915 (action (w3-get-state :form)) | |
1916 (options) | |
1917 (pos) | |
1918 (num (w3-get-state :formnum)) | |
1919 (id (cdr-safe (assq 'id args))) | |
1920 (checked (assq 'checked args))) | |
1921 (setq default value | |
1922 pos (point)) | |
1923 (put 'text 'w3-formatter 'w3-handle-text) | |
1924 (w3-form-add-element 'multiline name value size maxlength default | |
1925 action options num id checked face)))) | |
1926 | |
1927 (defun w3-handle-label-text (&optional args) | |
1928 (setcdr (w3-get-state :label-text) | |
1929 (concat (cdr (w3-get-state :label-text)) args)) | |
1930 (w3-handle-text args)) | |
1931 | |
1932 (defun w3-handle-/label (&optional args) | |
1933 (let ((num (w3-get-state :formnum)) | |
1934 (dat (w3-get-state :label-text))) | |
1935 (setq w3-form-labels (cons (cons (format "%d:%s" num (car dat)) | |
1936 (cdr dat)) | |
1937 w3-form-labels)) | |
1938 (put 'text 'w3-formatter 'w3-handle-text))) | |
1939 | |
1940 (defun w3-handle-label (&optional args) | |
1941 (if (not (w3-get-state :form)) | |
1942 (w3-warn 'html "<label> outside of a <FORM> construct - ERROR!!") | |
1943 (put 'text 'w3-formatter 'w3-handle-label-text) | |
1944 (w3-put-state :label-text (cons (or (cdr-safe (assq 'for args)) | |
1945 "Unknown label") "")))) | |
1946 | |
1947 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
1948 ;;; For displaying the buffer | |
1949 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
1950 (defun w3-show-buffer () | |
1951 (let ((potential-title | |
1952 (and (not (w3-get-state :title)) | |
1953 (url-generate-new-buffer-name | |
1954 (url-basepath url-current-file t))))) | |
1955 (if (and potential-title (string= potential-title "")) | |
1956 (setq potential-title | |
1957 (url-generate-new-buffer-name url-current-file))) | |
1958 (if (and potential-title (not (string= potential-title ""))) | |
1959 (rename-buffer potential-title))) | |
1960 (setq inhibit-read-only nil) | |
1961 (if url-find-this-link | |
1962 (w3-find-specific-link url-find-this-link)) | |
1963 (let* ((tag 'html) | |
1964 (args nil) | |
1965 (face (cdr (w3-face-for-element)))) | |
1966 (if (not face) | |
1967 (setq tag 'body | |
1968 face (cdr (w3-face-for-element)))) | |
1969 (and face | |
1970 (if (not (fboundp 'valid-specifier-locale-p)) | |
1971 nil | |
1972 (w3-my-safe-copy-face face 'default (current-buffer)))))) | |
1973 | |
1974 (defun w3-parse-header-link-items () | |
1975 ;; Parse `url-current-mime-headers' and look for any <link> items | |
1976 (let ((items url-current-mime-headers) | |
1977 (node nil) | |
1978 (url nil) | |
1979 (type nil) | |
1980 (args nil) | |
1981 (title nil) | |
1982 (label nil)) | |
1983 (while items | |
1984 (setq node (car items) | |
1985 items (cdr items)) | |
1986 (if (string= (car node) "link") | |
1987 (progn | |
1988 (setq args (mm-parse-args (cdr node)) | |
1989 type (if (assoc "rel" args) "rel" "rev") | |
1990 label (cdr-safe (assoc type args)) | |
1991 title (cdr-safe (assoc "title" args)) | |
1992 url (car-safe (rassoc nil args))) | |
1993 (if (string-match "^<.*>$" url) | |
1994 (setq url (substring url 1 -1))) | |
1995 (and url label type | |
1996 (w3-handle-link (list (cons "href" url) | |
1997 (cons type label) | |
1998 (cons "title" title))))))))) | |
1999 | |
2000 (defun w3-refresh-buffer (&rest args) | |
2001 "Redraw the current buffer - this does not refetch or reparse the current | |
2002 document, but uses the stored parse data." | |
2003 (interactive) | |
2004 (let ((buffer-read-only nil)) | |
2005 (if (get-buffer url-working-buffer) | |
2006 (kill-buffer url-working-buffer)) | |
2007 (error "Not yet reimplemented... sorry."))) | |
2008 | |
2009 (defun w3-prepare-buffer (&rest args) | |
2010 ;; The text/html viewer - does all the drawing and displaying of the buffer | |
2011 ;; that is necessary to go from raw HTML to a good presentation. | |
2012 (let ((active-minibuffer-window | |
2013 (if (minibuffer-window-active-p (minibuffer-window)) | |
2014 (minibuffer-window)))) | |
2015 (let ((pop-up-windows nil)) | |
2016 (if active-minibuffer-window | |
2017 (let* ((current-buffer (current-buffer)) | |
2018 (window (get-buffer-window current-buffer t))) | |
2019 (cond (window | |
2020 (and (fboundp 'select-frame) | |
2021 (fboundp 'window-frame) | |
2022 (select-frame (window-frame window))) | |
2023 (select-window window)) | |
2024 ((and (fboundp 'selected-frame) | |
2025 (fboundp 'window-frame) | |
2026 (eq (selected-frame) | |
2027 (window-frame (minibuffer-window)))) | |
2028 ;; on minibuffer-only-frame | |
2029 (select-frame (previous-frame)) | |
2030 (select-window (frame-first-window (selected-frame)))) | |
2031 ((fboundp 'frame-first-window) | |
2032 (select-window (frame-first-window)))) | |
2033 (set-buffer current-buffer)))) | |
2034 (let* ((source (buffer-string)) | |
2035 (parse (w3-preparse-buffer (current-buffer))) | |
2036 (buff (car parse))) | |
2037 (set-buffer-modified-p nil) | |
2038 (kill-buffer (current-buffer)) | |
2039 (set-buffer buff) | |
2040 (setq w3-current-source source | |
2041 w3-current-parse w3-last-parse-tree) | |
2042 (w3-parse-header-link-items) | |
2043 (save-excursion | |
2044 (goto-char (point-max)) | |
2045 (w3-handle-paragraph) | |
2046 (if (and (boundp 'w3-image-widgets-waiting) w3-image-widgets-waiting) | |
2047 (let (url glyph widget) | |
2048 (while w3-image-widgets-waiting | |
2049 (setq widget (car w3-image-widgets-waiting) | |
2050 w3-image-widgets-waiting (cdr w3-image-widgets-waiting) | |
2051 url (widget-get widget 'src) | |
2052 glyph (cdr-safe (assoc url w3-graphics-list))) | |
2053 (widget-value-set widget glyph)))) | |
2054 (w3-mode) | |
2055 (w3-handle-annotations) | |
2056 (w3-handle-headers) | |
2057 (set-buffer-modified-p nil) | |
2058 ) | |
2059 (switch-to-buffer (current-buffer)) | |
2060 (or active-minibuffer-window | |
2061 (let ((window nil) | |
2062 (pop-up-windows nil)) | |
2063 (display-buffer (current-buffer)) | |
2064 (if (or w3-running-FSF19 w3-running-xemacs) | |
2065 (setq window (get-buffer-window (current-buffer) t)) | |
2066 (setq window (get-buffer-window (current-buffer)))) | |
2067 (select-window window) | |
2068 (if (and (fboundp 'select-frame) | |
2069 (fboundp 'window-frame)) | |
2070 (select-frame (window-frame window))))) | |
2071 (goto-char (point-min)) | |
2072 (w3-show-buffer) | |
2073 (if url-keep-history | |
2074 (let ((url (url-view-url t))) | |
2075 (if (not (url-hashtablep url-history-list)) | |
2076 (setq url-history-list (url-make-hashtable 131))) | |
2077 (url-puthash url (buffer-name) url-history-list) | |
2078 (if (fboundp 'w3-shuffle-history-menu) | |
2079 (w3-shuffle-history-menu))))) | |
2080 (cond (active-minibuffer-window | |
2081 (select-window active-minibuffer-window) | |
2082 (sit-for 0))))) | |
2083 | |
2084 (defun w3-handle-headers () | |
2085 ;; Insert any headers the user wants to see into the current buffer. | |
2086 (let ((show w3-show-headers) | |
2087 (cur nil) | |
2088 (hdrs nil) | |
2089 (tag 'ol) | |
2090 (header nil) | |
2091 (w3-last-fill-pos (point-max)) | |
2092 (val nil) | |
2093 (first t)) | |
2094 (goto-char (point-max)) | |
2095 (if (eq show t) (setq show '(".*"))) | |
2096 (while show | |
2097 (setq cur (car show) | |
2098 show (cdr show) | |
2099 hdrs url-current-mime-headers) | |
2100 (while hdrs | |
2101 (setq header (car (car hdrs)) | |
2102 val (cdr (car hdrs)) | |
2103 hdrs (cdr hdrs)) | |
2104 (if (numberp val) (setq val (int-to-string val))) | |
2105 (if (and (/= 0 (length header)) | |
2106 (string-match cur header)) | |
2107 (progn | |
2108 (if first | |
2109 (progn | |
2110 (w3-handle-hr) | |
2111 (w3-handle-list-opening '(("value" . 1))) | |
2112 (setq tag 'li | |
2113 first nil))) | |
2114 (w3-handle-list-item) | |
2115 (w3-handle-text (concat (capitalize header) | |
2116 ": " val)))))) | |
2117 (if (not first) ; We showed some headers | |
2118 (setq tag '/ol | |
2119 tag (w3-handle-list-ending))))) | |
2120 | |
2121 (defun w3-handle-annotations () | |
2122 ;; Insert personal annotations into the current buffer | |
2123 (let ((annos (w3-fetch-personal-annotations)) | |
2124 (tag nil)) | |
2125 (if (not annos) | |
2126 nil ; No annotations | |
2127 (goto-char (cond | |
2128 ((eq w3-annotation-position 'bottom) (point-max)) | |
2129 ((eq w3-annotation-position 'top) (point-min)) | |
2130 (t (message "Bad value for w3-annotation-position") | |
2131 (point-max)))) | |
2132 (w3-handle-div '((class . "annotations"))) | |
2133 (w3-handle-hr '((width . "75%") | |
2134 (label . " Personal Annotations ") | |
2135 (align . "center"))) | |
2136 (setq tag 'ol) | |
2137 (w3-handle-list-opening) | |
2138 (while annos | |
2139 (w3-handle-list-item) | |
2140 (w3-handle-hyperlink (list (cons 'href (car (car annos))))) | |
2141 (w3-handle-text (cdr (car annos))) | |
2142 (w3-handle-hyperlink-end) | |
2143 (setq annos (cdr annos))) | |
2144 (w3-handle-list-ending) | |
2145 (w3-handle-hr '((width . "75%") | |
2146 (align . "center"))) | |
2147 (w3-handle-/div) | |
2148 ))) | |
2149 | |
2150 (defun w3-fetch-personal-annotations () | |
2151 ;; Grab any personal annotations for the current url | |
2152 (let ((url (url-view-url t)) | |
2153 (anno w3-personal-annotations) | |
2154 (annolist nil)) | |
2155 (if (assoc url anno) | |
2156 (while anno | |
2157 (if (equal (car (car anno)) url) | |
2158 (setq annolist | |
2159 (cons | |
2160 (cons | |
2161 (format "file:%s%s/PAN-%s.html" | |
2162 (if (= ?/ (string-to-char | |
2163 w3-personal-annotation-directory)) "" | |
2164 "/") | |
2165 w3-personal-annotation-directory | |
2166 (car (car (cdr (car anno))))) | |
2167 (car (cdr (car (cdr (car anno)))))) | |
2168 annolist))) | |
2169 (setq anno (cdr anno)))) | |
2170 annolist)) | |
2171 | |
2172 (defun w3-normalize-spaces (string) | |
2173 ;; nuke spaces at the beginning | |
2174 (if (string-match "^[ \t\r\n]+" string) | |
2175 (setq string (substring string (match-end 0)))) | |
2176 | |
2177 ;; nuke spaces in the middle | |
2178 (while (string-match "[ \t\r\n][ \r\t\n]+" string) | |
2179 (setq string (concat (substring string 0 (1+ (match-beginning 0))) | |
2180 (substring string (match-end 0))))) | |
2181 | |
2182 ;; nuke spaces at the end | |
2183 (if (string-match "[ \t\n\r]+$" string) | |
2184 (setq string (substring string 0 (match-beginning 0)))) | |
2185 string) | |
2186 | |
2187 (defun w3-upcase-region (st nd &optional end) | |
2188 (and st nd (upcase-region st nd))) | |
2189 | |
2190 (provide 'w3-draw) | |
2191 |