comparison lisp/prim/format.el @ 4:b82b59fe008d r19-15b3

Import from CVS: tag r19-15b3
author cvs
date Mon, 13 Aug 2007 08:46:56 +0200
parents 376386a54a3c
children 441bb1e64a06
comparison
equal deleted inserted replaced
3:30df88044ec6 4:b82b59fe008d
1 ;;; format.el --- read and save files in multiple formats 1 ;;; format.el --- read and save files in multiple formats
2
2 ;; Copyright (c) 1994, 1995 Free Software Foundation 3 ;; Copyright (c) 1994, 1995 Free Software Foundation
3 4
4 ;; Author: Boris Goldowsky <boris@gnu.ai.mit.edu> 5 ;; Author: Boris Goldowsky <boris@gnu.ai.mit.edu>
6 ;; Keywords: extensions
5 7
6 ;; This file is part of GNU Emacs. 8 ;; This file is part of GNU Emacs.
7 9
8 ;; GNU Emacs is free software; you can redistribute it and/or modify 10 ;; GNU Emacs is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by 11 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option) 12 ;; the Free Software Foundation; either version 2, or (at your option)
11 ;; any later version. 13 ;; any later version.
12 ;; 14
13 ;; GNU Emacs is distributed in the hope that it will be useful, 15 ;; GNU Emacs is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details. 18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING. If not, write to the
22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
24
25 ;;; Synched up with: FSF 19.34.
26
27 ;;; Commentary:
28
29 ;; This file defines a unified mechanism for saving & loading files stored
30 ;; in different formats. `format-alist' contains information that directs
31 ;; Emacs to call an encoding or decoding function when reading or writing
32 ;; files that match certain conditions.
17 ;; 33 ;;
18 ;; You should have received a copy of the GNU General Public License 34 ;; When a file is visited, its format is determined by matching the
19 ;; along with GNU Emacs; see the file COPYING. If not, write to 35 ;; beginning of the file against regular expressions stored in
20 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 36 ;; `format-alist'. If this fails, you can manually translate the buffer
21 37 ;; using `format-decode-buffer'. In either case, the formats used are
22 ;;; Synched up with: FSF 19.30. 38 ;; listed in the variable `buffer-file-format', and become the default
23 39 ;; format for saving the buffer. To save a buffer in a different format,
24 ;;; Commentary: 40 ;; change this variable, or use `format-write-file'.
25 ;; This file defines a unified mechanism for saving & loading files stored in
26 ;; different formats. `format-alist' contains information that directs
27 ;; Emacs to call an encoding or decoding function when reading or writing
28 ;; files that match certain conditions.
29 ;;
30 ;; When a file is visited, its format is determined by matching the beginning
31 ;; of the file against regular expressions stored in `format-alist'. If this
32 ;; fails, you can manually translate the buffer using `format-decode-buffer'.
33 ;; In either case, the formats used are listed in the variable
34 ;; `buffer-file-format', and become the default format for saving the buffer.
35 ;; To save a buffer in a different format, change this variable, or use
36 ;; `format-write-file'.
37 ;; 41 ;;
38 ;; Auto-save files are normally created in the same format as the visited 42 ;; Auto-save files are normally created in the same format as the visited
39 ;; file, but the variable `auto-save-file-format' can be set to a particularly 43 ;; file, but the variable `auto-save-file-format' can be set to a
40 ;; fast or otherwise preferred format to be used for auto-saving (or nil to do 44 ;; particularly fast or otherwise preferred format to be used for
41 ;; no encoding on auto-save files, but then you risk losing any 45 ;; auto-saving (or nil to do no encoding on auto-save files, but then you
42 ;; text-properties in the buffer). 46 ;; risk losing any text-properties in the buffer).
43 ;; 47 ;;
44 ;; You can manually translate a buffer into or out of a particular format with 48 ;; You can manually translate a buffer into or out of a particular format
45 ;; the functions `format-encode-buffer' and `format-decode-buffer'. 49 ;; with the functions `format-encode-buffer' and `format-decode-buffer'.
46 ;; To translate just the region use the functions `format-encode-region' and 50 ;; To translate just the region use the functions `format-encode-region'
47 ;; `format-decode-region'. 51 ;; and `format-decode-region'.
48 ;; 52 ;;
49 ;; You can define a new format by writing the encoding and decoding functions, 53 ;; You can define a new format by writing the encoding and decoding
50 ;; and adding an entry to `format-alist'. See enriched.el for an example of 54 ;; functions, and adding an entry to `format-alist'. See enriched.el for
51 ;; how to implement a file format. There are various functions defined 55 ;; an example of how to implement a file format. There are various
52 ;; in this file that may be useful for writing the encoding and decoding 56 ;; functions defined in this file that may be useful for writing the
53 ;; functions: 57 ;; encoding and decoding functions:
54 ;; * `format-annotate-region' and `format-deannotate-region' allow a single 58 ;; * `format-annotate-region' and `format-deannotate-region' allow a
55 ;; alist of information to be used for encoding and decoding. The alist 59 ;; single alist of information to be used for encoding and decoding.
56 ;; defines a correspondence between strings in the file ("annotations") 60 ;; The alist defines a correspondence between strings in the file
57 ;; and text-properties in the buffer. 61 ;; ("annotations") and text-properties in the buffer.
58 ;; * `format-replace-strings' is similarly useful for doing simple 62 ;; * `format-replace-strings' is similarly useful for doing simple
59 ;; string->string translations in a reversible manner. 63 ;; string->string translations in a reversible manner.
64
65 ;;; Code:
60 66
61 (put 'buffer-file-format 'permanent-local t) 67 (put 'buffer-file-format 'permanent-local t)
62 68
63 (defconst format-alist 69 (defconst format-alist
64 '((text/enriched "Extended MIME text/enriched format." 70 '((text/enriched "Extended MIME text/enriched format."
468 ;; If no matching annotation is open, just ignore the close. 474 ;; If no matching annotation is open, just ignore the close.
469 (if (not (assoc name open-ans)) 475 (if (not (assoc name open-ans))
470 (message "Extra closing annotation (%s) in file" name) 476 (message "Extra closing annotation (%s) in file" name)
471 ;; If one is open, but not on the top of the stack, close 477 ;; If one is open, but not on the top of the stack, close
472 ;; the things in between as well. Set `found' when the real 478 ;; the things in between as well. Set `found' when the real
473 ;; oneis closed. 479 ;; one is closed.
474 (while (not found) 480 (while (not found)
475 (let* ((top (car open-ans)) ; first on stack: should match. 481 (let* ((top (car open-ans)) ; first on stack: should match.
476 (top-name (car top)) 482 (top-name (car top))
477 (start (car (cdr top))) ; location of start 483 (start (car (cdr top))) ; location of start
478 (params (cdr (cdr top))) ; parameters 484 (params (cdr (cdr top))) ; parameters
495 (if (member 'nil (mapcar 501 (if (member 'nil (mapcar
496 (lambda (r) 502 (lambda (r)
497 (assoc r open-ans)) 503 (assoc r open-ans))
498 ans)) 504 ans))
499 nil ; multiple ans not satisfied 505 nil ; multiple ans not satisfied
500 ;; Yes, use the current property name & 506 ;; Yes, all set.
501 ;; value. Set loop variables to nil so loop 507 ;; If there are multiple annotations going
508 ;; into one text property, adjust the
509 ;; begin points of the other annotations
510 ;; so that we don't get double marking.
511 (let ((to-reset ans)
512 this-one)
513 (while to-reset
514 (setq this-one
515 (assoc (car to-reset)
516 (cdr open-ans)))
517 (if this-one
518 (setcdr this-one (list loc)))
519 (setq to-reset (cdr to-reset))))
520 ;; Set loop variables to nil so loop
502 ;; will exit. 521 ;; will exit.
503 (setq alist nil aalist nil matched t 522 (setq alist nil aalist nil matched t
504 ;; pop annotation off stack. 523 ;; pop annotation off stack.
505 open-ans (cdr open-ans)) 524 open-ans (cdr open-ans))
506 (cond 525 (cond
732 (let ((prop-alist (cdr (assoc prop trans))) 751 (let ((prop-alist (cdr (assoc prop trans)))
733 default) 752 default)
734 (if (not prop-alist) 753 (if (not prop-alist)
735 nil 754 nil
736 ;; If property is numeric, nil means 0 755 ;; If property is numeric, nil means 0
737 (cond ((and (numberp old) (null new) 756 (cond ((and (numberp old) (null new))
738 (numberp (car (car prop-alist))))
739 (setq new 0)) 757 (setq new 0))
740 ((and (numberp new) (null old) 758 ((and (numberp new) (null old))
741 (numberp (car (car prop-alist))))
742 (setq old 0))) 759 (setq old 0)))
743 ;; If either old or new is a list, have to treat both that way. 760 ;; If either old or new is a list, have to treat both that way.
744 (if (or (consp old) (consp new)) 761 (if (or (consp old) (consp new))
745 (let* ((old (if (listp old) old (list old))) 762 (let* ((old (if (listp old) old (list old)))
746 (new (if (listp new) new (list new))) 763 (new (if (listp new) new (list new)))
761 (format-make-relatively-unique close open)) 778 (format-make-relatively-unique close open))
762 (format-annotate-atomic-property-change prop-alist old new))))) 779 (format-annotate-atomic-property-change prop-alist old new)))))
763 780
764 (defun format-annotate-atomic-property-change (prop-alist old new) 781 (defun format-annotate-atomic-property-change (prop-alist old new)
765 "Internal function annotate a single property change. 782 "Internal function annotate a single property change.
766 PROP-ALIST is the relevant segement of a TRANSLATIONS list. 783 PROP-ALIST is the relevant segment of a TRANSLATIONS list.
767 OLD and NEW are the values." 784 OLD and NEW are the values."
768 (cond 785 (cond
769 ;; Numerical annotation - use difference 786 ;; Numerical annotation - use difference
770 ((and (numberp old) (numberp new) 787 ((and (numberp old) (numberp new))
771 (numberp (car (car prop-alist))))
772 (let* ((entry (progn 788 (let* ((entry (progn
773 (while (and (car (car prop-alist)) 789 (while (and (car (car prop-alist))
774 (not (numberp (car (car prop-alist))))) 790 (not (numberp (car (car prop-alist)))))
775 (setq prop-alist (cdr prop-alist))) 791 (setq prop-alist (cdr prop-alist)))
776 (car prop-alist))) 792 (car prop-alist)))