annotate lisp/format.el @ 5574:d4f334808463

Support inlining labels, bytecomp.el. lisp/ChangeLog addition: 2011-10-02 Aidan Kehoe <kehoea@parhasard.net> * bytecomp.el (byte-compile-initial-macro-environment): Add #'declare to this, so it doesn't need to rely on #'cl-compiling file to determine when we're byte-compiling. Update #'labels to support declaring labels inline, as Common Lisp requires. * bytecomp.el (byte-compile-function-form): Don't error if FUNCTION is quoting a non-lambda, non-symbol, just return it. * cl-extra.el (cl-macroexpand-all): If a label name has been quoted, expand to the label placeholder quoted with 'function. This allows the byte compiler to distinguish between uses of the placeholder as data and uses in contexts where it should be inlined. * cl-macs.el: * cl-macs.el (cl-do-proclaim): When proclaming something as inline, if it is bound as a label, don't modify the symbol's plist; instead, treat the first element of its placeholder constant vector as a place to store compile information. * cl-macs.el (declare): Leave processing declarations while compiling to the implementation of #'declare in byte-compile-initial-macro-environment. tests/ChangeLog addition: 2011-10-02 Aidan Kehoe <kehoea@parhasard.net> * automated/lisp-tests.el: * automated/lisp-tests.el (+): Test #'labels and inlining.
author Aidan Kehoe <kehoea@parhasard.net>
date Sun, 02 Oct 2011 15:32:16 +0100
parents ac37a5f7e5be
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1 ;;; format.el --- read and save files in multiple formats
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3 ;; Copyright (c) 1994, 1995, 1997 Free Software Foundation
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
4
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
5 ;; Author: Boris Goldowsky <boris@gnu.ai.mit.edu>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
6 ;; Keywords: extensions, dumped
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
7
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
8 ;; This file is part of XEmacs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
9
5402
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 5270
diff changeset
10 ;; XEmacs is free software: you can redistribute it and/or modify it
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 5270
diff changeset
11 ;; under the terms of the GNU General Public License as published by the
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 5270
diff changeset
12 ;; Free Software Foundation, either version 3 of the License, or (at your
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 5270
diff changeset
13 ;; option) any later version.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
14
5402
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 5270
diff changeset
15 ;; XEmacs is distributed in the hope that it will be useful, but WITHOUT
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 5270
diff changeset
16 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 5270
diff changeset
17 ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 5270
diff changeset
18 ;; for more details.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
19
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
20 ;; You should have received a copy of the GNU General Public License
5402
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 5270
diff changeset
21 ;; along with XEmacs. If not, see <http://www.gnu.org/licenses/>.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
22
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
23 ;;; Synched up with: Emacs 20.2.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
24
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
25 ;;; Commentary:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
26
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
27 ;; This file is dumped with XEmacs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
28
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
29 ;; This file defines a unified mechanism for saving & loading files stored
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
30 ;; in different formats. `format-alist' contains information that directs
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
31 ;; Emacs to call an encoding or decoding function when reading or writing
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
32 ;; files that match certain conditions.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
33 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
34 ;; When a file is visited, its format is determined by matching the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
35 ;; beginning of the file against regular expressions stored in
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
36 ;; `format-alist'. If this fails, you can manually translate the buffer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
37 ;; using `format-decode-buffer'. In either case, the formats used are
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
38 ;; listed in the variable `buffer-file-format', and become the default
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
39 ;; format for saving the buffer. To save a buffer in a different format,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
40 ;; change this variable, or use `format-write-file'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
41 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
42 ;; Auto-save files are normally created in the same format as the visited
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
43 ;; file, but the variable `auto-save-file-format' can be set to a
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
44 ;; particularly fast or otherwise preferred format to be used for
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
45 ;; auto-saving (or nil to do no encoding on auto-save files, but then you
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
46 ;; risk losing any text-properties in the buffer).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
47 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
48 ;; You can manually translate a buffer into or out of a particular format
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
49 ;; with the functions `format-encode-buffer' and `format-decode-buffer'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
50 ;; To translate just the region use the functions `format-encode-region'
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
51 ;; and `format-decode-region'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
52 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
53 ;; You can define a new format by writing the encoding and decoding
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
54 ;; functions, and adding an entry to `format-alist'. See enriched.el for
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
55 ;; an example of how to implement a file format. There are various
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
56 ;; functions defined in this file that may be useful for writing the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
57 ;; encoding and decoding functions:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
58 ;; * `format-annotate-region' and `format-deannotate-region' allow a
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
59 ;; single alist of information to be used for encoding and decoding.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
60 ;; The alist defines a correspondence between strings in the file
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
61 ;; ("annotations") and text-properties in the buffer.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
62 ;; * `format-replace-strings' is similarly useful for doing simple
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
63 ;; string->string translations in a reversible manner.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
64
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
65 ;;; Code:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
66
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
67 (put 'buffer-file-format 'permanent-local t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
68
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
69 (defvar format-alist
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
70 '(
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
71 ; (image/jpeg "JPEG image" "\377\330\377\340\000\020JFIF"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
72 ; image-decode-jpeg nil t image-mode)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
73 ; (image/gif "GIF image" "GIF8[79]"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
74 ; image-decode-gif nil t image-mode)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
75 ; (image/png "Portable Network Graphics" "\211PNG"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
76 ; image-decode-png nil t image-mode)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
77 ; (image/x-xpm "XPM image" "/\\* XPM \\*/"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
78 ; image-decode-xpm nil t image-mode)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
79
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
80 ; ;; TIFF files have lousy magic
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
81 ; (image/tiff "TIFF image" "II\\*\000"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
82 ; image-decode-tiff nil t image-mode) ;; TIFF 6.0 big-endian
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
83 ; (image/tiff "TIFF image" "MM\000\\*"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
84 ; image-decode-tiff nil t image-mode) ;; TIFF 6.0 little-endian
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
85
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
86 (text/enriched "Extended MIME text/enriched format."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
87 "Content-[Tt]ype:[ \t]*text/enriched"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
88 enriched-decode enriched-encode t enriched-mode)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
89 (text/richtext "Extended MIME obsolete text/richtext format."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
90 "Content-[Tt]ype:[ \t]*text/richtext"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
91 richtext-decode richtext-encode t enriched-mode)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
92 (plain "ISO 8859-1 standard format, no text properties."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
93 ;; Plain only exists so that there is an obvious neutral choice in
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
94 ;; the completion list.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
95 nil nil nil nil nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
96 ;; (ibm "IBM Code Page 850 (DOS)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
97 ;; "1\\(^\\)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
98 ;; "recode ibm-pc:latin1" "recode latin1:ibm-pc" t nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
99 ;; (mac "Apple Macintosh"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
100 ;; "1\\(^\\)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
101 ;; "recode mac:latin1" "recode latin1:mac" t nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
102 ;; (hp "HP Roman8"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
103 ;; "1\\(^\\)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
104 ;; "recode roman8:latin1" "recode latin1:roman8" t nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
105 ;; (TeX "TeX (encoding)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
106 ;; "1\\(^\\)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
107 ;; iso-tex2iso iso-iso2tex t nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
108 ;; (gtex "German TeX (encoding)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
109 ;; "1\\(^\\)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
110 ;; iso-gtex2iso iso-iso2gtex t nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
111 ;; (html "HTML (encoding)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
112 ;; "1\\(^\\)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
113 ;; "recode html:latin1" "recode latin1:html" t nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
114 ;; (rot13 "rot13"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
115 ;; "1\\(^\\)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
116 ;; "tr a-mn-z n-za-m" "tr a-mn-z n-za-m" t nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
117 ;; (duden "Duden Ersatzdarstellung"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
118 ;; "1\\(^\\)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
119 ;; "diac" iso-iso2duden t nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
120 ;; (de646 "German ASCII (ISO 646)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
121 ;; "1\\(^\\)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
122 ;; "recode iso646-ge:latin1" "recode latin1:iso646-ge" t nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
123 ;; (denet "net German"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
124 ;; "1\\(^\\)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
125 ;; iso-german iso-cvt-read-only t nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
126 ;; (esnet "net Spanish"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
127 ;; "1\\(^\\)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
128 ;; iso-spanish iso-cvt-read-only t nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
129 )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
130 "List of information about understood file formats.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
131 Elements are of the form \(NAME DOC-STR REGEXP FROM-FN TO-FN MODIFY MODE-FN).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
132
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
133 NAME is a symbol, which is stored in `buffer-file-format'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
134
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
135 DOC-STR should be a single line providing more information about the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
136 format. It is currently unused, but in the future will be shown to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
137 the user if they ask for more information.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
138
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
139 REGEXP is a regular expression to match against the beginning of the file;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
140 it should match only files in that format.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
141
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
142 FROM-FN is called to decode files in that format; it gets two args, BEGIN
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
143 and END, and can make any modifications it likes, returning the new
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
144 end. It must make sure that the beginning of the file no longer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
145 matches REGEXP, or else it will get called again.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
146 Alternatively, FROM-FN can be a string, which specifies a shell command
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
147 (including options) to be used as a filter to perform the conversion.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
148
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
149 TO-FN is called to encode a region into that format; it is passed three
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
150 arguments: BEGIN, END, and BUFFER. BUFFER is the original buffer that
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
151 the data being written came from, which the function could use, for
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
152 example, to find the values of local variables. TO-FN should either
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
153 return a list of annotations like `write-region-annotate-functions',
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
154 or modify the region and return the new end.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
155 Alternatively, TO-FN can be a string, which specifies a shell command
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
156 (including options) to be used as a filter to perform the conversion.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
157
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
158 MODIFY, if non-nil, means the TO-FN wants to modify the region. If nil,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
159 TO-FN will not make any changes but will instead return a list of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
160 annotations.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
161
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
162 MODE-FN, if specified, is called when visiting a file with that format.")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
163
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
164 ;;; Basic Functions (called from Lisp)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
165
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
166 (defun format-encode-run-method (method from to &optional buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
167 "Translate using function or shell script METHOD the text from FROM to TO.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
168 If METHOD is a string, it is a shell command;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
169 otherwise, it should be a Lisp function.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
170 BUFFER should be the buffer that the output originally came from."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
171 (if (stringp method)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
172 (save-current-buffer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
173 (set-buffer buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
174 (with-output-to-temp-buffer "*Format Errors*"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
175 (shell-command-on-region from to method t nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
176 (point))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
177 (funcall method from to buffer)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
178
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
179 (defun format-decode-run-method (method from to &optional buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
180 "Decode using function or shell script METHOD the text from FROM to TO.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
181 If METHOD is a string, it is a shell command;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
182 otherwise, it should be a Lisp function."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
183 (if (stringp method)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
184 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
185 (with-output-to-temp-buffer "*Format Errors*"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
186 (shell-command-on-region from to method t nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
187 (point))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
188 (funcall method from to)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
189
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
190 (defun format-annotate-function (format from to orig-buf)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
191 "Return annotations for writing region as FORMAT.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
192 FORMAT is a symbol naming one of the formats defined in `format-alist',
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
193 it must be a single symbol, not a list like `buffer-file-format'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
194 FROM and TO delimit the region to be operated on in the current buffer.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
195 ORIG-BUF is the original buffer that the data came from.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
196 This function works like a function on `write-region-annotate-functions':
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
197 it either returns a list of annotations, or returns with a different buffer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
198 current, which contains the modified text to write.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
199
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
200 For most purposes, consider using `format-encode-region' instead."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
201 ;; This function is called by write-region (actually build-annotations)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
202 ;; for each element of buffer-file-format.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
203 (let* ((info (assq format format-alist))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
204 (to-fn (nth 4 info))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
205 (modify (nth 5 info)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
206 (if to-fn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
207 (if modify
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
208 ;; To-function wants to modify region. Copy to safe place.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
209 (let ((copy-buf (get-buffer-create " *Format Temp*")))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
210 (copy-to-buffer copy-buf from to)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
211 (set-buffer copy-buf)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
212 (format-insert-annotations write-region-annotations-so-far from)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
213 (format-encode-run-method to-fn (point-min) (point-max) orig-buf)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
214 nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
215 ;; Otherwise just call function, it will return annotations.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
216 (funcall to-fn from to orig-buf)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
217
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
218 (defun format-decode (format length &optional visit-flag)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
219 "Decode text from any known FORMAT.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
220 FORMAT is a symbol appearing in `format-alist' or a list of such symbols,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
221 or nil, in which case this function tries to guess the format of the data by
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
222 matching against the regular expressions in `format-alist'. After a match is
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
223 found and the region decoded, the alist is searched again from the beginning
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
224 for another match.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
225
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
226 Second arg LENGTH is the number of characters following point to operate on.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
227 If optional third arg VISIT-FLAG is true, set `buffer-file-format'
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
228 to the list of formats used, and call any mode functions defined for those
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
229 formats.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
230
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
231 Returns the new length of the decoded region.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
232
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
233 For most purposes, consider using `format-decode-region' instead.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
234
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
235 This function is called by insert-file-contents whenever a file is read."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
236 (let ((mod (buffer-modified-p))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
237 (begin (point))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
238 (end (+ (point) length)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
239 (if (null format)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
240 ;; Figure out which format it is in, remember list in `format'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
241 (let ((try format-alist))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
242 (while try
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
243 (let* ((f (car try))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
244 (regexp (nth 2 f))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
245 (p (point)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
246 (if (and regexp (looking-at regexp)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
247 (< (match-end 0) (+ begin length)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
248 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
249 (setq format (cons (car f) format))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
250 ;; Decode it
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
251 (if (nth 3 f)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
252 (setq end (format-decode-run-method (nth 3 f) begin end)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
253 ;; Call visit function if required
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
254 (if (and visit-flag (nth 6 f)) (funcall (nth 6 f) 1))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
255 ;; Safeguard against either of the functions changing pt.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
256 (goto-char p)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
257 ;; Rewind list to look for another format
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
258 (setq try format-alist))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
259 (setq try (cdr try))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
260 ;; Deal with given format(s)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
261 (or (listp format) (setq format (list format)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
262 (let ((do format) f)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
263 (while do
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
264 (or (setq f (assq (car do) format-alist))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
265 (error "Unknown format" (car do)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
266 ;; Decode:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
267 (if (nth 3 f)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
268 (setq end (format-decode-run-method (nth 3 f) begin end)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
269 ;; Call visit function if required
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
270 (if (and visit-flag (nth 6 f)) (funcall (nth 6 f) 1))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
271 (setq do (cdr do)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
272 (if visit-flag
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
273 (setq buffer-file-format format))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
274 (set-buffer-modified-p mod)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
275 ;; Return new length of region
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
276 (- end begin)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
277
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
278 ;;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
279 ;;; Interactive functions & entry points
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
280 ;;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
281
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
282 (defun format-decode-buffer (&optional format)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
283 "Translate the buffer from some FORMAT.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
284 If the format is not specified, this function attempts to guess.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
285 `buffer-file-format' is set to the format used, and any mode-functions
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
286 for the format are called."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
287 (interactive
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
288 (list (format-read "Translate buffer from format (default: guess): ")))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
289 (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
290 (goto-char (point-min))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
291 (format-decode format (buffer-size) t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
292
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
293 (defun format-decode-region (from to &optional format)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
294 "Decode the region from some format.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
295 Arg FORMAT is optional; if omitted the format will be determined by looking
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
296 for identifying regular expressions at the beginning of the region."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
297 (interactive
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
298 (list (region-beginning) (region-end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
299 (format-read "Translate region from format (default: guess): ")))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
300 (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
301 (goto-char from)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
302 (format-decode format (- to from) nil)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
303
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
304 (defun format-encode-buffer (&optional format)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
305 "Translate the buffer into FORMAT.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
306 FORMAT defaults to `buffer-file-format'. It is a symbol naming one of the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
307 formats defined in `format-alist', or a list of such symbols."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
308 (interactive
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
309 (list (format-read (format "Translate buffer to format (default %s): "
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
310 buffer-file-format))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
311 (format-encode-region (point-min) (point-max) format))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
312
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 428
diff changeset
313 (defun format-encode-region (start end &optional format)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
314 "Translate the region into some FORMAT.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
315 FORMAT defaults to `buffer-file-format', it is a symbol naming
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
316 one of the formats defined in `format-alist', or a list of such symbols."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
317 (interactive
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
318 (list (region-beginning) (region-end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
319 (format-read (format "Translate region to format (default %s): "
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
320 buffer-file-format))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
321 (if (null format) (setq format buffer-file-format))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
322 (if (symbolp format) (setq format (list format)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
323 (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
324 (goto-char end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
325 (let ( ; (cur-buf (current-buffer))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
326 (end (point-marker)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
327 (while format
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
328 (let* ((info (assq (car format) format-alist))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
329 (to-fn (nth 4 info))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
330 (modify (nth 5 info))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
331 ;; result
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
332 )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
333 (if to-fn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
334 (if modify
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 428
diff changeset
335 (setq end (format-encode-run-method to-fn start end
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
336 (current-buffer)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
337 (format-insert-annotations
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 428
diff changeset
338 (funcall to-fn start end (current-buffer)))))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
339 (setq format (cdr format)))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
340
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
341 (defun format-write-file (filename format)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
342 "Write current buffer into a FILE using some FORMAT.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
343 Makes buffer visit that file and sets the format as the default for future
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
344 saves. If the buffer is already visiting a file, you can specify a directory
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
345 name as FILE, to write a file of the same old name in that directory."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
346 (interactive
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
347 ;; Same interactive spec as write-file, plus format question.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
348 (let* ((file (if buffer-file-name
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
349 (read-file-name "Write file: "
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
350 nil nil nil nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
351 (read-file-name "Write file: "
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
352 (cdr (assq 'default-directory
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
353 (buffer-local-variables)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
354 nil nil (buffer-name))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
355 (fmt (format-read (format "Write file `%s' in format: "
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
356 (file-name-nondirectory file)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
357 (list file fmt)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
358 (setq buffer-file-format format)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
359 (write-file filename))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
360
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
361 (defun format-find-file (filename format)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
362 "Find the file FILE using data format FORMAT.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
363 If FORMAT is nil then do not do any format conversion."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
364 (interactive
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
365 ;; Same interactive spec as write-file, plus format question.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
366 (let* ((file (read-file-name "Find file: "))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
367 (fmt (format-read (format "Read file `%s' in format: "
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
368 (file-name-nondirectory file)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
369 (list file fmt)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
370 (let ((format-alist nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
371 (find-file filename))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
372 (if format
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
373 (format-decode-buffer format)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
374
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 428
diff changeset
375 (defun format-insert-file (filename format &optional start end)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
376 "Insert the contents of file FILE using data format FORMAT.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
377 If FORMAT is nil then do not do any format conversion.
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 428
diff changeset
378 The optional third and fourth arguments START and END specify
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
379 the part of the file to read.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
380
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
381 The return value is like the value of `insert-file-contents':
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
382 a list (ABSOLUTE-FILE-NAME . SIZE)."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
383 (interactive
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
384 ;; Same interactive spec as write-file, plus format question.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
385 (let* ((file (read-file-name "Find file: "))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
386 (fmt (format-read (format "Read file `%s' in format: "
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
387 (file-name-nondirectory file)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
388 (list file fmt)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
389 (let (value size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
390 (let ((format-alist nil))
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 428
diff changeset
391 (setq value (insert-file-contents filename nil start end))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
392 (setq size (nth 1 value)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
393 (if format
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
394 (setq size (format-decode format size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
395 value (cons (car value) size)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
396 value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
397
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
398 (defun format-read (&optional prompt)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
399 "Read and return the name of a format.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
400 Return value is a list, like `buffer-file-format'; it may be nil.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
401 Formats are defined in `format-alist'. Optional arg is the PROMPT to use."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
402 (let* ((table (mapcar (lambda (x) (list (symbol-name (car x))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
403 format-alist))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
404 (ans (completing-read (or prompt "Format: ") table nil t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
405 (if (not (equal "" ans)) (list (intern ans)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
406
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
407
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
408 ;;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
409 ;;; Below are some functions that may be useful in writing encoding and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
410 ;;; decoding functions for use in format-alist.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
411 ;;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
412
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 428
diff changeset
413 (defun format-replace-strings (alist &optional reverse start end)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
414 "Do multiple replacements on the buffer.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
415 ALIST is a list of (from . to) pairs, which should be proper arguments to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
416 `search-forward' and `replace-match' respectively.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
417 Optional 2nd arg REVERSE, if non-nil, means the pairs are (to . from), so that
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
418 you can use the same list in both directions if it contains only literal
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
419 strings.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
420 Optional args BEGIN and END specify a region of the buffer to operate on."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
421 (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
422 (save-restriction
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 428
diff changeset
423 (or start (setq start (point-min)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
424 (if end (narrow-to-region (point-min) end))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
425 (while alist
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
426 (let ((from (if reverse (cdr (car alist)) (car (car alist))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
427 (to (if reverse (car (cdr alist)) (cdr (car alist)))))
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 428
diff changeset
428 (goto-char start)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
429 (while (search-forward from nil t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
430 (goto-char (match-beginning 0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
431 (insert to)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
432 (set-text-properties (- (point) (length to)) (point)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
433 (text-properties-at (point)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
434 (delete-region (point) (+ (point) (- (match-end 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
435 (match-beginning 0)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
436 (setq alist (cdr alist)))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
437
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
438 (put 'face 'format-list-valued t) ; These text-properties take values
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
439 (put 'unknown 'format-list-valued t) ; that are lists, the elements of which
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
440 ; should be considered separately.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
441 ; See format-deannotate-region and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
442 ; format-annotate-region.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
443
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
444 ;;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
445 ;;; Decoding
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
446 ;;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
447
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
448 (defun format-deannotate-region (from to translations next-fn)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
449 "Translate annotations in the region into text properties.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
450 This sets text properties between FROM to TO as directed by the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
451 TRANSLATIONS and NEXT-FN arguments.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
452
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
453 NEXT-FN is a function that searches forward from point for an annotation.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
454 It should return a list of 4 elements: \(BEGIN END NAME POSITIVE). BEGIN and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
455 END are buffer positions bounding the annotation, NAME is the name searched
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
456 for in TRANSLATIONS, and POSITIVE should be non-nil if this annotation marks
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
457 the beginning of a region with some property, or nil if it ends the region.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
458 NEXT-FN should return nil if there are no annotations after point.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
459
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
460 The basic format of the TRANSLATIONS argument is described in the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
461 documentation for the `format-annotate-region' function. There are some
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
462 additional things to keep in mind for decoding, though:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
463
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
464 When an annotation is found, the TRANSLATIONS list is searched for a
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
465 text-property name and value that corresponds to that annotation. If the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
466 text-property has several annotations associated with it, it will be used only
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
467 if the other annotations are also in effect at that point. The first match
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
468 found whose annotations are all present is used.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
469
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
470 The text property thus determined is set to the value over the region between
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
471 the opening and closing annotations. However, if the text-property name has a
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
472 non-nil `format-list-valued' property, then the value will be consed onto the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
473 surrounding value of the property, rather than replacing that value.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
474
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
475 There are some special symbols that can be used in the \"property\" slot of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
476 the TRANSLATIONS list: PARAMETER and FUNCTION \(spelled in uppercase).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
477 Annotations listed under the pseudo-property PARAMETER are considered to be
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
478 arguments of the immediately surrounding annotation; the text between the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
479 opening and closing parameter annotations is deleted from the buffer but saved
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
480 as a string. The surrounding annotation should be listed under the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
481 pseudo-property FUNCTION. Instead of inserting a text-property for this
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
482 annotation, the function listed in the VALUE slot is called to make whatever
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
483 changes are appropriate. The function's first two arguments are the START and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
484 END locations, and the rest of the arguments are any PARAMETERs found in that
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
485 region.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
486
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
487 Any annotations that are found by NEXT-FN but not defined by TRANSLATIONS
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
488 are saved as values of the `unknown' text-property \(which is list-valued).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
489 The TRANSLATIONS list should usually contain an entry of the form
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
490 \(unknown \(nil format-annotate-value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
491 to write these unknown annotations back into the file."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
492 (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
493 (save-restriction
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
494 (narrow-to-region (point-min) to)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
495 (goto-char from)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
496 (let (next open-ans todo
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
497 ;; loc
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
498 unknown-ans)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
499 (while (setq next (funcall next-fn))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
500 (let* ((loc (nth 0 next))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
501 (end (nth 1 next))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
502 (name (nth 2 next))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
503 (positive (nth 3 next))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
504 (found nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
505
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
506 ;; Delete the annotation
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
507 (delete-region loc end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
508 (cond
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
509 ;; Positive annotations are stacked, remembering location
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
510 (positive (setq open-ans (cons `(,name ((,loc . nil))) open-ans)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
511 ;; It is a negative annotation:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
512 ;; Close the top annotation & add its text property.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
513 ;; If the file's nesting is messed up, the close might not match
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
514 ;; the top thing on the open-annotations stack.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
515 ;; If no matching annotation is open, just ignore the close.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
516 ((not (assoc name open-ans))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
517 (message "Extra closing annotation (%s) in file" name))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
518 ;; If one is open, but not on the top of the stack, close
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
519 ;; the things in between as well. Set `found' when the real
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
520 ;; one is closed.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
521 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
522 (while (not found)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
523 (let* ((top (car open-ans)) ; first on stack: should match.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
524 (top-name (car top)) ; text property name
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
525 (top-extents (nth 1 top)) ; property regions
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
526 (params (cdr (cdr top))) ; parameters
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
527 (aalist translations)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
528 (matched nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
529 (if (equal name top-name)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
530 (setq found t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
531 (message "Improper nesting in file."))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
532 ;; Look through property names in TRANSLATIONS
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
533 (while aalist
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
534 (let ((prop (car (car aalist)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
535 (alist (cdr (car aalist))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
536 ;; And look through values for each property
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
537 (while alist
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
538 (let ((value (car (car alist)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
539 (ans (cdr (car alist))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
540 (if (member top-name ans)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
541 ;; This annotation is listed, but still have to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
542 ;; check if multiple annotations are satisfied
5270
3acaa0fc09be Use #'some, #'every, etc. for composing boolean operations on lists.
Aidan Kehoe <kehoea@parhasard.net>
parents: 4607
diff changeset
543 (if (notevery (lambda (r) (assoc r open-ans))
3acaa0fc09be Use #'some, #'every, etc. for composing boolean operations on lists.
Aidan Kehoe <kehoea@parhasard.net>
parents: 4607
diff changeset
544 ans)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
545 nil ; multiple ans not satisfied
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
546 ;; If there are multiple annotations going
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
547 ;; into one text property, split up the other
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
548 ;; annotations so they apply individually to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
549 ;; the other regions.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
550 (setcdr (car top-extents) loc)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
551 (let ((to-split ans) this-one extents)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
552 (while to-split
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
553 (setq this-one
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
554 (assoc (car to-split) open-ans)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
555 extents (nth 1 this-one))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
556 (if (not (eq this-one top))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
557 (setcar (cdr this-one)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
558 (format-subtract-regions
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
559 extents top-extents)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
560 (setq to-split (cdr to-split))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
561 ;; Set loop variables to nil so loop
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
562 ;; will exit.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
563 (setq alist nil aalist nil matched t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
564 ;; pop annotation off stack.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
565 open-ans (cdr open-ans))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
566 (let ((extents top-extents)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
567 (start (car (car top-extents)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
568 (loc (cdr (car top-extents))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
569 (while extents
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
570 (cond
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
571 ;; Check for pseudo-properties
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
572 ((eq prop 'PARAMETER)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
573 ;; A parameter of the top open ann:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
574 ;; delete text and use as arg.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
575 (if open-ans
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
576 ;; (If nothing open, discard).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
577 (setq open-ans
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
578 (cons
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
579 (append (car open-ans)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
580 (list
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
581 (buffer-substring
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
582 start loc)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
583 (cdr open-ans))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
584 (delete-region start loc))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
585 ((eq prop 'FUNCTION)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
586 ;; Not a property, but a function.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
587 (let ((rtn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
588 (apply value start loc params)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
589 (if rtn (setq todo (cons rtn todo)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
590 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
591 ;; Normal property/value pair
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
592 (setq todo
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
593 (cons (list start loc prop value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
594 todo))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
595 (setq extents (cdr extents)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
596 start (car (car extents))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
597 loc (cdr (car extents))))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
598 (setq alist (cdr alist))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
599 (setq aalist (cdr aalist)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
600 (unless matched
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
601 ;; Didn't find any match for the annotation:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
602 ;; Store as value of text-property `unknown'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
603 (setcdr (car top-extents) loc)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
604 (let ((extents top-extents)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
605 (start (car (car top-extents)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
606 (loc (cdr (car top-extents))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
607 (while extents
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
608 (setq open-ans (cdr open-ans)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
609 todo (cons (list start loc 'unknown top-name)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
610 todo)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
611 unknown-ans (cons name unknown-ans)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
612 extents (cdr extents)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
613 start (car (car extents))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
614 loc (cdr (car extents))))))))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
615
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
616 ;; Once entire file has been scanned, add the properties.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
617 (while todo
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
618 (let* ((item (car todo))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
619 (from (nth 0 item))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
620 (to (nth 1 item))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
621 (prop (nth 2 item))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
622 (val (nth 3 item)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
623
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
624 (if (numberp val) ; add to ambient value if numeric
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
625 (format-property-increment-region from to prop val 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
626 (put-text-property
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
627 from to prop
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
628 (cond ((get prop 'format-list-valued) ; value gets consed onto
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
629 ; list-valued properties
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
630 (let ((prev (get-text-property from prop)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
631 (cons val (if (listp prev) prev (list prev)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
632 (t val))))) ; normally, just set to val.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
633 (setq todo (cdr todo)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
634
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
635 (if unknown-ans
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
636 (message "Unknown annotations: %s" unknown-ans))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
637
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
638 (defun format-subtract-regions (minu subtra)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
639 "Remove the regions in SUBTRAHEND from the regions in MINUEND. A region
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
640 is a dotted pair (from . to). Both parameters are lists of regions. Each
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
641 list must contain nonoverlapping, noncontiguous regions, in descending
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
642 order. The result is also nonoverlapping, noncontiguous, and in descending
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
643 order. The first element of MINUEND can have a cdr of nil, indicating that
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
644 the end of that region is not yet known."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
645 (let* ((minuend (copy-alist minu))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
646 (subtrahend (copy-alist subtra))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
647 (m (car minuend))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
648 (s (car subtrahend))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
649 results)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
650 (while (and minuend subtrahend)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
651 (cond
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
652 ;; The minuend starts after the subtrahend ends; keep it.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
653 ((> (car m) (cdr s))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
654 (setq results (cons m results)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
655 minuend (cdr minuend)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
656 m (car minuend)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
657 ;; The minuend extends beyond the end of the subtrahend. Chop it off.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
658 ((or (null (cdr m)) (> (cdr m) (cdr s)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
659 (setq results (cons (cons (1+ (cdr s)) (cdr m)) results))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
660 (setcdr m (cdr s)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
661 ;; The subtrahend starts after the minuend ends; throw it away.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
662 ((< (cdr m) (car s))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
663 (setq subtrahend (cdr subtrahend) s (car subtrahend)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
664 ;; The subtrahend extends beyond the end of the minuend. Chop it off.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
665 (t ;(<= (cdr m) (cdr s)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
666 (if (>= (car m) (car s))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
667 (setq minuend (cdr minuend) m (car minuend))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
668 (setcdr m (1- (car s)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
669 (setq subtrahend (cdr subtrahend) s (car subtrahend))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
670 (nconc (nreverse results) minuend)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
671
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
672 ;; This should probably go somewhere other than format.el. Then again,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
673 ;; indent.el has alter-text-property. NOTE: We can also use
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
674 ;; next-single-property-change instead of text-property-not-all, but then
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
675 ;; we have to see if we passed TO.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
676 (defun format-property-increment-region (from to prop delta default)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
677 "Increment property PROP over the region between FROM and TO by the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
678 amount DELTA (which may be negative). If property PROP is nil anywhere
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
679 in the region, it is treated as though it were DEFAULT."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
680 (let ((cur from) val newval next)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
681 (while cur
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
682 (setq val (get-text-property cur prop)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
683 newval (+ (or val default) delta)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
684 next (text-property-not-all cur to prop val))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
685 (put-text-property cur (or next to) prop newval)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
686 (setq cur next))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
687
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
688 ;;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
689 ;;; Encoding
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
690 ;;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
691
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
692 (defun format-insert-annotations (list &optional offset)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
693 "Apply list of annotations to buffer as `write-region' would.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
694 Inserts each element of the given LIST of buffer annotations at its
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
695 appropriate place. Use second arg OFFSET if the annotations' locations are
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
696 not relative to the beginning of the buffer: annotations will be inserted
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
697 at their location-OFFSET+1 \(ie, the offset is treated as the character number
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
698 of the first character in the buffer)."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
699 (if (not offset)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
700 (setq offset 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
701 (setq offset (1- offset)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
702 (let ((l (reverse list)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
703 (while l
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
704 (goto-char (- (car (car l)) offset))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
705 (insert (cdr (car l)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
706 (setq l (cdr l)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
707
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
708 (defun format-annotate-value (old new)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
709 "Return OLD and NEW as a \(close . open) annotation pair.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
710 Useful as a default function for TRANSLATIONS alist when the value of the text
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
711 property is the name of the annotation that you want to use, as it is for the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
712 `unknown' text property."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
713 (cons (if old (list old))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
714 (if new (list new))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
715
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
716 (defun format-annotate-region (from to trans format-fn ignore)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
717 "Generate annotations for text properties in the region.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
718 Searches for changes between FROM and TO, and describes them with a list of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
719 annotations as defined by alist TRANSLATIONS and FORMAT-FN. IGNORE lists text
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
720 properties not to consider; any text properties that are neither ignored nor
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
721 listed in TRANSLATIONS are warned about.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
722 If you actually want to modify the region, give the return value of this
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
723 function to `format-insert-annotations'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
724
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
725 Format of the TRANSLATIONS argument:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
726
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
727 Each element is a list whose car is a PROPERTY, and the following
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
728 elements are VALUES of that property followed by the names of zero or more
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
729 ANNOTATIONS. Whenever the property takes on that value, the annotations
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
730 \(as formatted by FORMAT-FN) are inserted into the file.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
731 When the property stops having that value, the matching negated annotation
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
732 will be inserted \(it may actually be closed earlier and reopened, if
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
733 necessary, to keep proper nesting).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
734
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
735 If the property's value is a list, then each element of the list is dealt with
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
736 separately.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
737
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
738 If a VALUE is numeric, then it is assumed that there is a single annotation
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
739 and each occurrence of it increments the value of the property by that number.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
740 Thus, given the entry \(left-margin \(4 \"indent\")), if the left margin
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
741 changes from 4 to 12, two <indent> annotations will be generated.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
742
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
743 If the VALUE is nil, then instead of annotations, a function should be
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
744 specified. This function is used as a default: it is called for all
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
745 transitions not explicitly listed in the table. The function is called with
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
746 two arguments, the OLD and NEW values of the property. It should return
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
747 lists of annotations like `format-annotate-location' does.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
748
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
749 The same structure can be used in reverse for reading files."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
750 (let ((all-ans nil) ; All annotations - becomes return value
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
751 (open-ans nil) ; Annotations not yet closed
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
752 (loc nil) ; Current location
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
753 (not-found nil)) ; Properties that couldn't be saved
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
754 (while (or (null loc)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
755 (and (setq loc (next-property-change loc nil to))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
756 (< loc to)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
757 (or loc (setq loc from))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
758 (let* ((ans (format-annotate-location loc (= loc from) ignore trans))
5365
dbae25a8949d Remove redundant functions, format.el, use functions from cl*.el instead.
Aidan Kehoe <kehoea@parhasard.net>
parents: 5270
diff changeset
759 (neg-ans (sort* (aref ans 0) '<
dbae25a8949d Remove redundant functions, format.el, use functions from cl*.el instead.
Aidan Kehoe <kehoea@parhasard.net>
parents: 5270
diff changeset
760 :key #'(lambda (object)
dbae25a8949d Remove redundant functions, format.el, use functions from cl*.el instead.
Aidan Kehoe <kehoea@parhasard.net>
parents: 5270
diff changeset
761 (or
dbae25a8949d Remove redundant functions, format.el, use functions from cl*.el instead.
Aidan Kehoe <kehoea@parhasard.net>
parents: 5270
diff changeset
762 (position object open-ans :test 'equal)
dbae25a8949d Remove redundant functions, format.el, use functions from cl*.el instead.
Aidan Kehoe <kehoea@parhasard.net>
parents: 5270
diff changeset
763 most-positive-fixnum))))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
764 (pos-ans (aref ans 1))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
765 (ignored (aref ans 2)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
766 (setq not-found (append ignored not-found)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
767 ignore (append ignored ignore))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
768 ;; First do the negative (closing) annotations
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
769 (while neg-ans
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
770 ;; Check if it's missing. This can happen (eg, a numeric property
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
771 ;; going negative can generate closing annotations before there are
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
772 ;; any open). Warn user & ignore.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
773 (if (not (member (car neg-ans) open-ans))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
774 (message "Can't close %s: not open." (car neg-ans))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
775 (while (not (equal (car neg-ans) (car open-ans)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
776 ;; To close anno. N, need to first close ans 1 to N-1,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
777 ;; remembering to re-open them later.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
778 (setq pos-ans (cons (car open-ans) pos-ans))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
779 (setq all-ans
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
780 (cons (cons loc (funcall format-fn (car open-ans) nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
781 all-ans))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
782 (setq open-ans (cdr open-ans)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
783 ;; Now remove the one we're really interested in from open list.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
784 (setq open-ans (cdr open-ans))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
785 ;; And put the closing annotation here.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
786 (setq all-ans
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
787 (cons (cons loc (funcall format-fn (car neg-ans) nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
788 all-ans)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
789 (setq neg-ans (cdr neg-ans)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
790 ;; Now deal with positive (opening) annotations
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
791 (let ( ; (p pos-ans)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
792 )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
793 (while pos-ans
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
794 (setq open-ans (cons (car pos-ans) open-ans))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
795 (setq all-ans
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
796 (cons (cons loc (funcall format-fn (car pos-ans) t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
797 all-ans))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
798 (setq pos-ans (cdr pos-ans))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
799
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
800 ;; Close any annotations still open
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
801 (while open-ans
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
802 (setq all-ans
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
803 (cons (cons to (funcall format-fn (car open-ans) nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
804 all-ans))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
805 (setq open-ans (cdr open-ans)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
806 (if not-found
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
807 (message "These text properties could not be saved:\n %s"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
808 not-found))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
809 (nreverse all-ans)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
810
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
811 ;;; Internal functions for format-annotate-region.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
812
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
813 (defun format-annotate-location (loc all ignore trans)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
814 "Return annotation(s) needed at LOCATION.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
815 This includes any properties that change between LOC-1 and LOC.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
816 If ALL is true, don't look at previous location, but generate annotations for
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
817 all non-nil properties.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
818 Third argument IGNORE is a list of text-properties not to consider.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
819
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
820 Return value is a vector of 3 elements:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
821 1. List of names of the annotations to close
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
822 2. List of the names of annotations to open.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
823 3. List of properties that were ignored or couldn't be annotated."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
824 (let* ((prev-loc (1- loc))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
825 (before-plist (if all nil (text-properties-at prev-loc)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
826 (after-plist (text-properties-at loc))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
827 p negatives positives prop props not-found)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
828 ;; make list of all property names involved
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
829 (setq p before-plist)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
830 (while p
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
831 (if (not (memq (car p) props))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
832 (setq props (cons (car p) props)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
833 (setq p (cdr (cdr p))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
834 (setq p after-plist)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
835 (while p
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
836 (if (not (memq (car p) props))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
837 (setq props (cons (car p) props)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
838 (setq p (cdr (cdr p))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
839
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
840 (while props
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
841 (setq prop (car props)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
842 props (cdr props))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
843 (if (memq prop ignore)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
844 nil ; If it's been ignored before, ignore it now.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
845 (let ((before (if all nil (car (cdr (memq prop before-plist)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
846 (after (car (cdr (memq prop after-plist)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
847 (if (equal before after)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
848 nil ; no change; ignore
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
849 (let ((result (format-annotate-single-property-change
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
850 prop before after trans)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
851 (if (not result)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
852 (setq not-found (cons prop not-found))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
853 (setq negatives (nconc negatives (car result))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
854 positives (nconc positives (cdr result)))))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
855 (vector negatives positives not-found)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
856
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
857 (defun format-annotate-single-property-change (prop old new trans)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
858 "Return annotations for PROPERTY changing from OLD to NEW.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
859 These are searched for in the TRANSLATIONS alist.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
860 If NEW does not appear in the list, but there is a default function, then that
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
861 function is called.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
862 Annotations to open and to close are returned as a dotted pair."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
863 (let ((prop-alist (cdr (assoc prop trans)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
864 ;; default
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
865 )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
866 (if (not prop-alist)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
867 nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
868 ;; If either old or new is a list, have to treat both that way.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
869 (if (or (consp old) (consp new))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
870 (let* ((old (if (listp old) old (list old)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
871 (new (if (listp new) new (list new)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
872 close open)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
873 (while old
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
874 (setq close
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
875 (append (car (format-annotate-atomic-property-change
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
876 prop-alist (car old) nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
877 close)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
878 old (cdr old)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
879 (while new
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
880 (setq open
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
881 (append (cdr (format-annotate-atomic-property-change
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
882 prop-alist nil (car new)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
883 open)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
884 new (cdr new)))
5365
dbae25a8949d Remove redundant functions, format.el, use functions from cl*.el instead.
Aidan Kehoe <kehoea@parhasard.net>
parents: 5270
diff changeset
885 (cons
dbae25a8949d Remove redundant functions, format.el, use functions from cl*.el instead.
Aidan Kehoe <kehoea@parhasard.net>
parents: 5270
diff changeset
886 (set-difference close open :stable t)
dbae25a8949d Remove redundant functions, format.el, use functions from cl*.el instead.
Aidan Kehoe <kehoea@parhasard.net>
parents: 5270
diff changeset
887 (set-difference open close :stable t)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
888 (format-annotate-atomic-property-change prop-alist old new)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
889
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
890 (defun format-annotate-atomic-property-change (prop-alist old new)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
891 "Internal function annotate a single property change.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
892 PROP-ALIST is the relevant segment of a TRANSLATIONS list.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
893 OLD and NEW are the values."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
894 (let (num-ann)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
895 ;; If old and new values are numbers,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
896 ;; look for a number in PROP-ALIST.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
897 (if (and (or (null old) (numberp old))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
898 (or (null new) (numberp new)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
899 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
900 (setq num-ann prop-alist)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
901 (while (and num-ann (not (numberp (car (car num-ann)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
902 (setq num-ann (cdr num-ann)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
903 (if num-ann
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
904 ;; Numerical annotation - use difference
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
905 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
906 ;; If property is numeric, nil means 0
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
907 (cond ((and (numberp old) (null new))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
908 (setq new 0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
909 ((and (numberp new) (null old))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
910 (setq old 0)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
911
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
912 (let* ((entry (car num-ann))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
913 (increment (car entry))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
914 (n (ceiling (/ (float (- new old)) (float increment))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
915 (anno (car (cdr entry))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
916 (if (> n 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
917 (cons nil (make-list n anno))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
918 (cons (make-list (- n) anno) nil))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
919
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
920 ;; Standard annotation
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
921 (let ((close (and old (cdr (assoc old prop-alist))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
922 (open (and new (cdr (assoc new prop-alist)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
923 (if (or close open)
5365
dbae25a8949d Remove redundant functions, format.el, use functions from cl*.el instead.
Aidan Kehoe <kehoea@parhasard.net>
parents: 5270
diff changeset
924 (cons
dbae25a8949d Remove redundant functions, format.el, use functions from cl*.el instead.
Aidan Kehoe <kehoea@parhasard.net>
parents: 5270
diff changeset
925 (set-difference close open :stable t)
dbae25a8949d Remove redundant functions, format.el, use functions from cl*.el instead.
Aidan Kehoe <kehoea@parhasard.net>
parents: 5270
diff changeset
926 (set-difference open close :stable t))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
927 ;; Call "Default" function, if any
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
928 (let ((default (assq nil prop-alist)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
929 (if default
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
930 (funcall (car (cdr default)) old new))))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
931
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
932 ;;; format.el ends here