annotate lisp/format.el @ 4981:4aebb0131297

Cleanups/renaming of EXTERNAL_TO_C_STRING and friends -------------------- ChangeLog entries follow: -------------------- modules/ChangeLog addition: 2010-02-05 Ben Wing <ben@xemacs.org> * postgresql/postgresql.c: * postgresql/postgresql.c (CHECK_LIVE_CONNECTION): * postgresql/postgresql.c (Fpq_connectdb): * postgresql/postgresql.c (Fpq_connect_start): * postgresql/postgresql.c (Fpq_lo_import): * postgresql/postgresql.c (Fpq_lo_export): * ldap/eldap.c (Fldap_open): * ldap/eldap.c (Fldap_search_basic): * ldap/eldap.c (Fldap_add): * ldap/eldap.c (Fldap_modify): * ldap/eldap.c (Fldap_delete): * canna/canna_api.c (Fcanna_initialize): * canna/canna_api.c (Fcanna_store_yomi): * canna/canna_api.c (Fcanna_parse): * canna/canna_api.c (Fcanna_henkan_begin): EXTERNAL_TO_C_STRING returns its argument instead of storing it in a parameter, and is renamed to EXTERNAL_TO_ITEXT. Similar things happen to related macros. See entry in src/ChangeLog. More Mule-izing of postgresql.c. Extract out common code between `pq-connectdb' and `pq-connect-start'. Fix places that signal an error string using a formatted string to instead follow the standard and have a fixed reason followed by the particular error message stored as one of the frobs. src/ChangeLog addition: 2010-02-05 Ben Wing <ben@xemacs.org> * console-msw.c (write_string_to_mswindows_debugging_output): * console-msw.c (Fmswindows_message_box): * console-x.c (x_perhaps_init_unseen_key_defaults): * console.c: * database.c (dbm_get): * database.c (dbm_put): * database.c (dbm_remove): * database.c (berkdb_get): * database.c (berkdb_put): * database.c (berkdb_remove): * database.c (Fopen_database): * device-gtk.c (gtk_init_device): * device-msw.c (msprinter_init_device_internal): * device-msw.c (msprinter_default_printer): * device-msw.c (msprinter_init_device): * device-msw.c (sync_printer_with_devmode): * device-msw.c (Fmsprinter_select_settings): * device-x.c (sanity_check_geometry_resource): * device-x.c (Dynarr_add_validified_lisp_string): * device-x.c (x_init_device): * device-x.c (Fx_put_resource): * device-x.c (Fx_valid_keysym_name_p): * device-x.c (Fx_set_font_path): * dialog-msw.c (push_lisp_string_as_unicode): * dialog-msw.c (handle_directory_dialog_box): * dialog-msw.c (handle_file_dialog_box): * dialog-x.c (dbox_descriptor_to_widget_value): * editfns.c (Fformat_time_string): * editfns.c (Fencode_time): * editfns.c (Fset_time_zone_rule): * emacs.c (make_argc_argv): * emacs.c (Fdump_emacs): * emodules.c (emodules_load): * eval.c: * eval.c (maybe_signal_error_1): * event-msw.c (Fdde_alloc_advise_item): * event-msw.c (mswindows_dde_callback): * event-msw.c (mswindows_wnd_proc): * fileio.c (report_error_with_errno): * fileio.c (Fsysnetunam): * fileio.c (Fdo_auto_save): * font-mgr.c (extract_fcapi_string): * font-mgr.c (Ffc_config_app_font_add_file): * font-mgr.c (Ffc_config_app_font_add_dir): * font-mgr.c (Ffc_config_filename): * frame-gtk.c (gtk_set_frame_text_value): * frame-gtk.c (gtk_create_widgets): * frame-msw.c (mswindows_init_frame_1): * frame-msw.c (mswindows_set_title_from_ibyte): * frame-msw.c (msprinter_init_frame_3): * frame-x.c (x_set_frame_text_value): * frame-x.c (x_set_frame_properties): * frame-x.c (start_drag_internal_1): * frame-x.c (x_cde_transfer_callback): * frame-x.c (x_create_widgets): * glyphs-eimage.c (my_jpeg_output_message): * glyphs-eimage.c (jpeg_instantiate): * glyphs-eimage.c (gif_instantiate): * glyphs-eimage.c (png_instantiate): * glyphs-eimage.c (tiff_instantiate): * glyphs-gtk.c (xbm_instantiate_1): * glyphs-gtk.c (gtk_xbm_instantiate): * glyphs-gtk.c (gtk_xpm_instantiate): * glyphs-gtk.c (gtk_xface_instantiate): * glyphs-gtk.c (cursor_font_instantiate): * glyphs-gtk.c (gtk_redisplay_widget): * glyphs-gtk.c (gtk_widget_instantiate_1): * glyphs-gtk.c (gtk_add_tab_item): * glyphs-msw.c (mswindows_xpm_instantiate): * glyphs-msw.c (bmp_instantiate): * glyphs-msw.c (mswindows_resource_instantiate): * glyphs-msw.c (xbm_instantiate_1): * glyphs-msw.c (mswindows_xbm_instantiate): * glyphs-msw.c (mswindows_xface_instantiate): * glyphs-msw.c (mswindows_redisplay_widget): * glyphs-msw.c (mswindows_widget_instantiate): * glyphs-msw.c (add_tree_item): * glyphs-msw.c (add_tab_item): * glyphs-msw.c (mswindows_combo_box_instantiate): * glyphs-msw.c (mswindows_widget_query_string_geometry): * glyphs-x.c (x_locate_pixmap_file): * glyphs-x.c (xbm_instantiate_1): * glyphs-x.c (x_xbm_instantiate): * glyphs-x.c (extract_xpm_color_names): * glyphs-x.c (x_xpm_instantiate): * glyphs-x.c (x_xface_instantiate): * glyphs-x.c (autodetect_instantiate): * glyphs-x.c (safe_XLoadFont): * glyphs-x.c (cursor_font_instantiate): * glyphs-x.c (x_redisplay_widget): * glyphs-x.c (Fchange_subwindow_property): * glyphs-x.c (x_widget_instantiate): * glyphs-x.c (x_tab_control_redisplay): * glyphs.c (pixmap_to_lisp_data): * gui-x.c (menu_separator_style_and_to_external): * gui-x.c (add_accel_and_to_external): * gui-x.c (button_item_to_widget_value): * hpplay.c (player_error_internal): * hpplay.c (play_sound_file): * hpplay.c (play_sound_data): * intl.c (Fset_current_locale): * lisp.h: * menubar-gtk.c (gtk_xemacs_set_accel_keys): * menubar-msw.c (populate_menu_add_item): * menubar-msw.c (populate_or_checksum_helper): * menubar-x.c (menu_item_descriptor_to_widget_value_1): * nt.c (init_user_info): * nt.c (get_long_basename): * nt.c (nt_get_resource): * nt.c (init_mswindows_environment): * nt.c (get_cached_volume_information): * nt.c (mswindows_readdir): * nt.c (read_unc_volume): * nt.c (mswindows_stat): * nt.c (mswindows_getdcwd): * nt.c (mswindows_executable_type): * nt.c (Fmswindows_short_file_name): * ntplay.c (nt_play_sound_file): * objects-gtk.c: * objects-gtk.c (gtk_valid_color_name_p): * objects-gtk.c (gtk_initialize_font_instance): * objects-gtk.c (gtk_font_list): * objects-msw.c (font_enum_callback_2): * objects-msw.c (parse_font_spec): * objects-x.c (x_parse_nearest_color): * objects-x.c (x_valid_color_name_p): * objects-x.c (x_initialize_font_instance): * objects-x.c (x_font_instance_truename): * objects-x.c (x_font_list): * objects-xlike-inc.c (XFUN): * objects-xlike-inc.c (xft_find_charset_font): * process-nt.c (mswindows_report_winsock_error): * process-nt.c (nt_create_process): * process-nt.c (get_internet_address): * process-nt.c (nt_open_network_stream): * process-unix.c: * process-unix.c (allocate_pty): * process-unix.c (get_internet_address): * process-unix.c (unix_canonicalize_host_name): * process-unix.c (unix_open_network_stream): * realpath.c: * select-common.h (lisp_data_to_selection_data): * select-gtk.c (symbol_to_gtk_atom): * select-gtk.c (atom_to_symbol): * select-msw.c (symbol_to_ms_cf): * select-msw.c (mswindows_register_selection_data_type): * select-x.c (symbol_to_x_atom): * select-x.c (x_atom_to_symbol): * select-x.c (hack_motif_clipboard_selection): * select-x.c (Fx_store_cutbuffer_internal): * sound.c (Fplay_sound_file): * sound.c (Fplay_sound): * sound.h (sound_perror): * sysdep.c: * sysdep.c (qxe_allocating_getcwd): * sysdep.c (qxe_execve): * sysdep.c (copy_in_passwd): * sysdep.c (qxe_getpwnam): * sysdep.c (qxe_ctime): * sysdll.c (dll_open): * sysdll.c (dll_function): * sysdll.c (dll_variable): * sysdll.c (search_linked_libs): * sysdll.c (dll_error): * sysfile.h: * sysfile.h (PATHNAME_CONVERT_OUT_TSTR): * sysfile.h (PATHNAME_CONVERT_OUT_UTF_8): * sysfile.h (PATHNAME_CONVERT_OUT): * sysfile.h (LISP_PATHNAME_CONVERT_OUT): * syswindows.h (ITEXT_TO_TSTR): * syswindows.h (LOCAL_FILE_FORMAT_TO_TSTR): * syswindows.h (TSTR_TO_LOCAL_FILE_FORMAT): * syswindows.h (LOCAL_FILE_FORMAT_TO_INTERNAL_MSWIN): * syswindows.h (LISP_LOCAL_FILE_FORMAT_MAYBE_URL_TO_TSTR): * text.h: * text.h (eicpy_ext_len): * text.h (enum new_dfc_src_type): * text.h (EXTERNAL_TO_ITEXT): * text.h (GET_STRERROR): * tooltalk.c (check_status): * tooltalk.c (Fadd_tooltalk_message_arg): * tooltalk.c (Fadd_tooltalk_pattern_attribute): * tooltalk.c (Fadd_tooltalk_pattern_arg): * win32.c (tstr_to_local_file_format): * win32.c (mswindows_lisp_error_1): * win32.c (mswindows_report_process_error): * win32.c (Fmswindows_shell_execute): * win32.c (mswindows_read_link_1): Changes involving external/internal format conversion, mostly code cleanup and renaming. 1. Eliminate the previous macros like LISP_STRING_TO_EXTERNAL that stored its result in a parameter. The new version of LISP_STRING_TO_EXTERNAL returns its result through the return value, same as the previous NEW_LISP_STRING_TO_EXTERNAL. Use the new-style macros throughout the code. 2. Rename C_STRING_TO_EXTERNAL and friends to ITEXT_TO_EXTERNAL, in keeping with overall naming rationalization involving Itext and related types. Macros involved in previous two: EXTERNAL_TO_C_STRING -> EXTERNAL_TO_ITEXT EXTERNAL_TO_C_STRING_MALLOC -> EXTERNAL_TO_ITEXT_MALLOC SIZED_EXTERNAL_TO_C_STRING -> SIZED_EXTERNAL_TO_ITEXT SIZED_EXTERNAL_TO_C_STRING_MALLOC -> SIZED_EXTERNAL_TO_ITEXT_MALLOC C_STRING_TO_EXTERNAL -> ITEXT_TO_EXTERNAL C_STRING_TO_EXTERNAL_MALLOC -> ITEXT_TO_EXTERNAL_MALLOC LISP_STRING_TO_EXTERNAL LISP_STRING_TO_EXTERNAL_MALLOC LISP_STRING_TO_TSTR C_STRING_TO_TSTR -> ITEXT_TO_TSTR TSTR_TO_C_STRING -> TSTR_TO_ITEXT The following four still return their values through parameters, since they have more than one value to return: C_STRING_TO_SIZED_EXTERNAL -> ITEXT_TO_SIZED_EXTERNAL LISP_STRING_TO_SIZED_EXTERNAL C_STRING_TO_SIZED_EXTERNAL_MALLOC -> ITEXT_TO_SIZED_EXTERNAL_MALLOC LISP_STRING_TO_SIZED_EXTERNAL_MALLOC Sometimes additional casts had to be inserted, since the old macros played strange games and completely defeated the type system of the store params. 3. Rewrite many places where direct calls to TO_EXTERNAL_FORMAT occurred with calls to one of the convenience macros listed above, or to make_extstring(). 4. Eliminate SIZED_C_STRING macros (they were hardly used, anyway) and use a direct call to TO_EXTERNAL_FORMAT or TO_INTERNAL_FORMAT. 4. Use LISP_PATHNAME_CONVERT_OUT in many places instead of something like LISP_STRING_TO_EXTERNAL(..., Qfile_name). 5. Eliminate some temporary variables that are no longer necessary now that we return a value rather than storing it into a variable. 6. Some Mule-izing in database.c. 7. Error functions: -- A bit of code cleanup in maybe_signal_error_1. -- Eliminate report_file_type_error; it's just an alias for signal_error_2 with params in a different order. -- Fix some places in the hostname-handling code that directly inserted externally-retrieved error strings into the supposed ASCII "reason" param instead of doing the right thing and sticking text descriptive of what was going on in "reason" and putting the external message in a frob. 8. Use Ascbyte instead of CIbyte in process-unix.c and maybe one or two other places. 9. Some code cleanup in copy_in_passwd() in sysdep.c. 10. Fix a real bug due to accidental variable shadowing in tstr_to_local_file_format() in win32.c.
author Ben Wing <ben@xemacs.org>
date Fri, 05 Feb 2010 11:02:24 -0600
parents 517f6887fbc0
children 3acaa0fc09be
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
10 ;; XEmacs is free software; you can redistribute it and/or modify it
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
11 ;; under the terms of the GNU General Public License as published by
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
12 ;; the Free Software Foundation; either version 2, or (at your option)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
13 ;; any later version.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
14
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
15 ;; XEmacs is distributed in the hope that it will be useful, but
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
16 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
18 ;; General Public License for more details.
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
21 ;; along with XEmacs; see the file COPYING. If not, write to the Free
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
22 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
23 ;; 02111-1307, USA.
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 ;;; Synched up with: Emacs 20.2.
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 ;;; Commentary:
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 is dumped with XEmacs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
30
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
31 ;; This file defines a unified mechanism for saving & loading files stored
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
32 ;; in different formats. `format-alist' contains information that directs
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
33 ;; Emacs to call an encoding or decoding function when reading or writing
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
34 ;; files that match certain conditions.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
35 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
36 ;; When a file is visited, its format is determined by matching the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
37 ;; beginning of the file against regular expressions stored in
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
38 ;; `format-alist'. If this fails, you can manually translate the buffer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
39 ;; using `format-decode-buffer'. In either case, the formats used are
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
40 ;; listed in the variable `buffer-file-format', and become the default
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
41 ;; 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
42 ;; change this variable, or use `format-write-file'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
43 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
44 ;; 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
45 ;; 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
46 ;; particularly fast or otherwise preferred format to be used for
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
47 ;; 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
48 ;; risk losing any text-properties in the buffer).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
49 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
50 ;; 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
51 ;; with the functions `format-encode-buffer' and `format-decode-buffer'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
52 ;; To translate just the region use the functions `format-encode-region'
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
53 ;; and `format-decode-region'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
54 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
55 ;; You can define a new format by writing the encoding and decoding
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
56 ;; functions, and adding an entry to `format-alist'. See enriched.el for
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
57 ;; an example of how to implement a file format. There are various
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
58 ;; functions defined in this file that may be useful for writing the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
59 ;; encoding and decoding functions:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
60 ;; * `format-annotate-region' and `format-deannotate-region' allow a
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
61 ;; single alist of information to be used for encoding and decoding.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
62 ;; The alist defines a correspondence between strings in the file
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
63 ;; ("annotations") and text-properties in the buffer.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
64 ;; * `format-replace-strings' is similarly useful for doing simple
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
65 ;; string->string translations in a reversible manner.
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 ;;; Code:
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 (put 'buffer-file-format 'permanent-local t)
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 (defvar format-alist
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
72 '(
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
73 ; (image/jpeg "JPEG image" "\377\330\377\340\000\020JFIF"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
74 ; image-decode-jpeg nil t image-mode)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
75 ; (image/gif "GIF image" "GIF8[79]"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
76 ; image-decode-gif nil t image-mode)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
77 ; (image/png "Portable Network Graphics" "\211PNG"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
78 ; image-decode-png nil t image-mode)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
79 ; (image/x-xpm "XPM image" "/\\* XPM \\*/"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
80 ; image-decode-xpm nil t image-mode)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
81
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
82 ; ;; TIFF files have lousy magic
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
83 ; (image/tiff "TIFF image" "II\\*\000"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
84 ; image-decode-tiff nil t image-mode) ;; TIFF 6.0 big-endian
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
85 ; (image/tiff "TIFF image" "MM\000\\*"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
86 ; image-decode-tiff nil t image-mode) ;; TIFF 6.0 little-endian
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
87
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
88 (text/enriched "Extended MIME text/enriched format."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
89 "Content-[Tt]ype:[ \t]*text/enriched"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
90 enriched-decode enriched-encode t enriched-mode)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
91 (text/richtext "Extended MIME obsolete text/richtext format."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
92 "Content-[Tt]ype:[ \t]*text/richtext"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
93 richtext-decode richtext-encode t enriched-mode)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
94 (plain "ISO 8859-1 standard format, no text properties."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
95 ;; Plain only exists so that there is an obvious neutral choice in
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
96 ;; the completion list.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
97 nil nil nil nil nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
98 ;; (ibm "IBM Code Page 850 (DOS)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
99 ;; "1\\(^\\)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
100 ;; "recode ibm-pc:latin1" "recode latin1:ibm-pc" t nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
101 ;; (mac "Apple Macintosh"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
102 ;; "1\\(^\\)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
103 ;; "recode mac:latin1" "recode latin1:mac" t nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
104 ;; (hp "HP Roman8"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
105 ;; "1\\(^\\)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
106 ;; "recode roman8:latin1" "recode latin1:roman8" t nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
107 ;; (TeX "TeX (encoding)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
108 ;; "1\\(^\\)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
109 ;; iso-tex2iso iso-iso2tex t nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
110 ;; (gtex "German TeX (encoding)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
111 ;; "1\\(^\\)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
112 ;; iso-gtex2iso iso-iso2gtex t nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
113 ;; (html "HTML (encoding)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
114 ;; "1\\(^\\)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
115 ;; "recode html:latin1" "recode latin1:html" t nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
116 ;; (rot13 "rot13"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
117 ;; "1\\(^\\)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
118 ;; "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
119 ;; (duden "Duden Ersatzdarstellung"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
120 ;; "1\\(^\\)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
121 ;; "diac" iso-iso2duden t nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
122 ;; (de646 "German ASCII (ISO 646)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
123 ;; "1\\(^\\)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
124 ;; "recode iso646-ge:latin1" "recode latin1:iso646-ge" t nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
125 ;; (denet "net German"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
126 ;; "1\\(^\\)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
127 ;; iso-german iso-cvt-read-only t nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
128 ;; (esnet "net Spanish"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
129 ;; "1\\(^\\)"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
130 ;; iso-spanish iso-cvt-read-only t nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
131 )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
132 "List of information about understood file formats.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
133 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
134
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
135 NAME is a symbol, which is stored in `buffer-file-format'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
136
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
137 DOC-STR should be a single line providing more information about the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
138 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
139 the user if they ask for more information.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
140
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
141 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
142 it should match only files in that format.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
143
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
144 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
145 and END, and can make any modifications it likes, returning the new
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
146 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
147 matches REGEXP, or else it will get called again.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
148 Alternatively, FROM-FN can be a string, which specifies a shell command
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
149 (including options) to be used as a filter to perform the conversion.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
150
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
151 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
152 arguments: BEGIN, END, and BUFFER. BUFFER is the original buffer that
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
153 the data being written came from, which the function could use, for
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
154 example, to find the values of local variables. TO-FN should either
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
155 return a list of annotations like `write-region-annotate-functions',
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
156 or modify the region and return the new end.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
157 Alternatively, TO-FN can be a string, which specifies a shell command
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
158 (including options) to be used as a filter to perform the conversion.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
159
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
160 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
161 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
162 annotations.
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 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
165
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
166 ;;; Basic Functions (called from Lisp)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
167
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
168 (defun format-encode-run-method (method from to &optional buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
169 "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
170 If METHOD is a string, it is a shell command;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
171 otherwise, it should be a Lisp function.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
172 BUFFER should be the buffer that the output originally came from."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
173 (if (stringp method)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
174 (save-current-buffer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
175 (set-buffer buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
176 (with-output-to-temp-buffer "*Format Errors*"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
177 (shell-command-on-region from to method t nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
178 (point))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
179 (funcall method from to buffer)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
180
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
181 (defun format-decode-run-method (method from to &optional buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
182 "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
183 If METHOD is a string, it is a shell command;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
184 otherwise, it should be a Lisp function."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
185 (if (stringp method)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
186 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
187 (with-output-to-temp-buffer "*Format Errors*"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
188 (shell-command-on-region from to method t nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
189 (point))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
190 (funcall method from to)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
191
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
192 (defun format-annotate-function (format from to orig-buf)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
193 "Return annotations for writing region as FORMAT.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
194 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
195 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
196 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
197 ORIG-BUF is the original buffer that the data came from.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
198 This function works like a function on `write-region-annotate-functions':
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
199 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
200 current, which contains the modified text to write.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
201
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
202 For most purposes, consider using `format-encode-region' instead."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
203 ;; This function is called by write-region (actually build-annotations)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
204 ;; for each element of buffer-file-format.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
205 (let* ((info (assq format format-alist))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
206 (to-fn (nth 4 info))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
207 (modify (nth 5 info)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
208 (if to-fn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
209 (if modify
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
210 ;; To-function wants to modify region. Copy to safe place.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
211 (let ((copy-buf (get-buffer-create " *Format Temp*")))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
212 (copy-to-buffer copy-buf from to)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
213 (set-buffer copy-buf)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
214 (format-insert-annotations write-region-annotations-so-far from)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
215 (format-encode-run-method to-fn (point-min) (point-max) orig-buf)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
216 nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
217 ;; Otherwise just call function, it will return annotations.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
218 (funcall to-fn from to orig-buf)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
219
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
220 (defun format-decode (format length &optional visit-flag)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
221 "Decode text from any known FORMAT.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
222 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
223 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
224 matching against the regular expressions in `format-alist'. After a match is
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
225 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
226 for another match.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
227
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
228 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
229 If optional third arg VISIT-FLAG is true, set `buffer-file-format'
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
230 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
231 formats.
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 Returns the new length of the decoded region.
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 For most purposes, consider using `format-decode-region' instead.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
236
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
237 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
238 (let ((mod (buffer-modified-p))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
239 (begin (point))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
240 (end (+ (point) length)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
241 (if (null format)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
242 ;; Figure out which format it is in, remember list in `format'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
243 (let ((try format-alist))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
244 (while try
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
245 (let* ((f (car try))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
246 (regexp (nth 2 f))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
247 (p (point)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
248 (if (and regexp (looking-at regexp)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
249 (< (match-end 0) (+ begin length)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
250 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
251 (setq format (cons (car f) format))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
252 ;; Decode it
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
253 (if (nth 3 f)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
254 (setq end (format-decode-run-method (nth 3 f) begin end)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
255 ;; Call visit function if required
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
256 (if (and visit-flag (nth 6 f)) (funcall (nth 6 f) 1))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
257 ;; Safeguard against either of the functions changing pt.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
258 (goto-char p)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
259 ;; Rewind list to look for another format
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
260 (setq try format-alist))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
261 (setq try (cdr try))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
262 ;; Deal with given format(s)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
263 (or (listp format) (setq format (list format)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
264 (let ((do format) f)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
265 (while do
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
266 (or (setq f (assq (car do) format-alist))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
267 (error "Unknown format" (car do)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
268 ;; Decode:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
269 (if (nth 3 f)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
270 (setq end (format-decode-run-method (nth 3 f) begin end)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
271 ;; Call visit function if required
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
272 (if (and visit-flag (nth 6 f)) (funcall (nth 6 f) 1))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
273 (setq do (cdr do)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
274 (if visit-flag
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
275 (setq buffer-file-format format))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
276 (set-buffer-modified-p mod)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
277 ;; Return new length of region
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
278 (- end begin)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
279
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 ;;; Interactive functions & entry points
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
282 ;;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
283
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
284 (defun format-decode-buffer (&optional format)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
285 "Translate the buffer from some FORMAT.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
286 If the format is not specified, this function attempts to guess.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
287 `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
288 for the format are called."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
289 (interactive
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
290 (list (format-read "Translate buffer from format (default: guess): ")))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
291 (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
292 (goto-char (point-min))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
293 (format-decode format (buffer-size) t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
294
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
295 (defun format-decode-region (from to &optional format)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
296 "Decode the region from some format.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
297 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
298 for identifying regular expressions at the beginning of the region."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
299 (interactive
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
300 (list (region-beginning) (region-end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
301 (format-read "Translate region from format (default: guess): ")))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
302 (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
303 (goto-char from)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
304 (format-decode format (- to from) nil)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
305
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
306 (defun format-encode-buffer (&optional format)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
307 "Translate the buffer into FORMAT.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
308 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
309 formats defined in `format-alist', or a list of such symbols."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
310 (interactive
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
311 (list (format-read (format "Translate buffer to format (default %s): "
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
312 buffer-file-format))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
313 (format-encode-region (point-min) (point-max) format))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
314
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 428
diff changeset
315 (defun format-encode-region (start end &optional format)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
316 "Translate the region into some FORMAT.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
317 FORMAT defaults to `buffer-file-format', it is a symbol naming
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
318 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
319 (interactive
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
320 (list (region-beginning) (region-end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
321 (format-read (format "Translate region to format (default %s): "
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
322 buffer-file-format))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
323 (if (null format) (setq format buffer-file-format))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
324 (if (symbolp format) (setq format (list format)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
325 (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
326 (goto-char end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
327 (let ( ; (cur-buf (current-buffer))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
328 (end (point-marker)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
329 (while format
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
330 (let* ((info (assq (car format) format-alist))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
331 (to-fn (nth 4 info))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
332 (modify (nth 5 info))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
333 ;; result
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
334 )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
335 (if to-fn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
336 (if modify
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 428
diff changeset
337 (setq end (format-encode-run-method to-fn start end
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
338 (current-buffer)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
339 (format-insert-annotations
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 428
diff changeset
340 (funcall to-fn start end (current-buffer)))))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
341 (setq format (cdr format)))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
342
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
343 (defun format-write-file (filename format)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
344 "Write current buffer into a FILE using some FORMAT.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
345 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
346 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
347 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
348 (interactive
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
349 ;; Same interactive spec as write-file, plus format question.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
350 (let* ((file (if buffer-file-name
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 nil nil nil nil)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
353 (read-file-name "Write file: "
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
354 (cdr (assq 'default-directory
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
355 (buffer-local-variables)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
356 nil nil (buffer-name))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
357 (fmt (format-read (format "Write file `%s' in format: "
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
358 (file-name-nondirectory file)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
359 (list file fmt)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
360 (setq buffer-file-format format)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
361 (write-file filename))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
362
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
363 (defun format-find-file (filename format)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
364 "Find the file FILE using data format FORMAT.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
365 If FORMAT is nil then do not do any format conversion."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
366 (interactive
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
367 ;; Same interactive spec as write-file, plus format question.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
368 (let* ((file (read-file-name "Find file: "))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
369 (fmt (format-read (format "Read file `%s' in format: "
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
370 (file-name-nondirectory file)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
371 (list file fmt)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
372 (let ((format-alist nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
373 (find-file filename))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
374 (if format
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
375 (format-decode-buffer format)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
376
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 428
diff changeset
377 (defun format-insert-file (filename format &optional start end)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
378 "Insert the contents of file FILE using data format FORMAT.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
379 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
380 The optional third and fourth arguments START and END specify
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
381 the part of the file to read.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
382
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
383 The return value is like the value of `insert-file-contents':
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
384 a list (ABSOLUTE-FILE-NAME . SIZE)."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
385 (interactive
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
386 ;; Same interactive spec as write-file, plus format question.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
387 (let* ((file (read-file-name "Find file: "))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
388 (fmt (format-read (format "Read file `%s' in format: "
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
389 (file-name-nondirectory file)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
390 (list file fmt)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
391 (let (value size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
392 (let ((format-alist nil))
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 428
diff changeset
393 (setq value (insert-file-contents filename nil start end))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
394 (setq size (nth 1 value)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
395 (if format
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
396 (setq size (format-decode format size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
397 value (cons (car value) size)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
398 value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
399
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
400 (defun format-read (&optional prompt)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
401 "Read and return the name of a format.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
402 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
403 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
404 (let* ((table (mapcar (lambda (x) (list (symbol-name (car x))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
405 format-alist))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
406 (ans (completing-read (or prompt "Format: ") table nil t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
407 (if (not (equal "" ans)) (list (intern ans)))))
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
410 ;;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
411 ;;; Below are some functions that may be useful in writing encoding and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
412 ;;; decoding functions for use in format-alist.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
413 ;;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
414
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 428
diff changeset
415 (defun format-replace-strings (alist &optional reverse start end)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
416 "Do multiple replacements on the buffer.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
417 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
418 `search-forward' and `replace-match' respectively.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
419 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
420 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
421 strings.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
422 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
423 (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
424 (save-restriction
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 428
diff changeset
425 (or start (setq start (point-min)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
426 (if end (narrow-to-region (point-min) end))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
427 (while alist
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
428 (let ((from (if reverse (cdr (car alist)) (car (car alist))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
429 (to (if reverse (car (cdr alist)) (cdr (car alist)))))
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 428
diff changeset
430 (goto-char start)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
431 (while (search-forward from nil t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
432 (goto-char (match-beginning 0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
433 (insert to)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
434 (set-text-properties (- (point) (length to)) (point)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
435 (text-properties-at (point)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
436 (delete-region (point) (+ (point) (- (match-end 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
437 (match-beginning 0)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
438 (setq alist (cdr alist)))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
439
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
440 ;;; Some list-manipulation functions that we need.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
441
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
442 (defun format-delq-cons (cons list)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
443 "Remove the given CONS from LIST by side effect,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
444 and return the new LIST. Since CONS could be the first element
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
445 of LIST, write `\(setq foo \(format-delq-cons element foo))' to be sure of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
446 changing the value of `foo'."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
447 (if (eq cons list)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
448 (cdr list)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
449 (let ((p list))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
450 (while (not (eq (cdr p) cons))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
451 (if (null p) (error "format-delq-cons: not an element."))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
452 (setq p (cdr p)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
453 ;; Now (cdr p) is the cons to delete
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
454 (setcdr p (cdr cons))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
455 list)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
456
4607
517f6887fbc0 Remove duplicate functions, chiefly #'delete-duplicates reimplementations.
Aidan Kehoe <kehoea@parhasard.net>
parents: 444
diff changeset
457 ;; XEmacs: this is #'nset-exclusive-or with a :test of #'equal, though we
517f6887fbc0 Remove duplicate functions, chiefly #'delete-duplicates reimplementations.
Aidan Kehoe <kehoea@parhasard.net>
parents: 444
diff changeset
458 ;; probably don't want to replace it right now.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
459 (defun format-make-relatively-unique (a b)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
460 "Delete common elements of lists A and B, return as pair.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
461 Compares using `equal'."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
462 (let* ((acopy (copy-sequence a))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
463 (bcopy (copy-sequence b))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
464 (tail acopy))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
465 (while tail
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
466 (let ((dup (member (car tail) bcopy))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
467 (next (cdr tail)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
468 (if dup (setq acopy (format-delq-cons tail acopy)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
469 bcopy (format-delq-cons dup bcopy)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
470 (setq tail next)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
471 (cons acopy bcopy)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
472
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
473 (defun format-common-tail (a b)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
474 "Given two lists that have a common tail, return it.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
475 Compares with `equal', and returns the part of A that is equal to the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
476 equivalent part of B. If even the last items of the two are not equal,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
477 returns nil."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
478 (let ((la (length a))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
479 (lb (length b)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
480 ;; Make sure they are the same length
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
481 (if (> la lb)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
482 (setq a (nthcdr (- la lb) a))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
483 (setq b (nthcdr (- lb la) b))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
484 (while (not (equal a b))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
485 (setq a (cdr a)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
486 b (cdr b)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
487 a)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
488
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
489 (defun format-reorder (items order)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
490 "Arrange ITEMS to following partial ORDER.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
491 Elements of ITEMS equal to elements of ORDER will be rearranged to follow the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
492 ORDER. Unmatched items will go last."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
493 (if order
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
494 (let ((item (member (car order) items)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
495 (if item
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
496 (cons (car item)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
497 (format-reorder (format-delq-cons item items)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
498 (cdr order)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
499 (format-reorder items (cdr order))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
500 items))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
501
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
502 (put 'face 'format-list-valued t) ; These text-properties take values
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
503 (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
504 ; should be considered separately.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
505 ; See format-deannotate-region and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
506 ; format-annotate-region.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
507
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
508 ;;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
509 ;;; Decoding
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
510 ;;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
511
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
512 (defun format-deannotate-region (from to translations next-fn)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
513 "Translate annotations in the region into text properties.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
514 This sets text properties between FROM to TO as directed by the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
515 TRANSLATIONS and NEXT-FN arguments.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
516
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
517 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
518 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
519 END are buffer positions bounding the annotation, NAME is the name searched
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
520 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
521 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
522 NEXT-FN should return nil if there are no annotations after point.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
523
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
524 The basic format of the TRANSLATIONS argument is described in the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
525 documentation for the `format-annotate-region' function. There are some
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
526 additional things to keep in mind for decoding, though:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
527
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
528 When an annotation is found, the TRANSLATIONS list is searched for a
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
529 text-property name and value that corresponds to that annotation. If the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
530 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
531 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
532 found whose annotations are all present is used.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
533
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
534 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
535 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
536 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
537 surrounding value of the property, rather than replacing that value.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
538
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
539 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
540 the TRANSLATIONS list: PARAMETER and FUNCTION \(spelled in uppercase).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
541 Annotations listed under the pseudo-property PARAMETER are considered to be
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
542 arguments of the immediately surrounding annotation; the text between the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
543 opening and closing parameter annotations is deleted from the buffer but saved
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
544 as a string. The surrounding annotation should be listed under the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
545 pseudo-property FUNCTION. Instead of inserting a text-property for this
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
546 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
547 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
548 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
549 region.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
550
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
551 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
552 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
553 The TRANSLATIONS list should usually contain an entry of the form
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
554 \(unknown \(nil format-annotate-value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
555 to write these unknown annotations back into the file."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
556 (save-excursion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
557 (save-restriction
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
558 (narrow-to-region (point-min) to)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
559 (goto-char from)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
560 (let (next open-ans todo
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
561 ;; loc
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
562 unknown-ans)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
563 (while (setq next (funcall next-fn))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
564 (let* ((loc (nth 0 next))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
565 (end (nth 1 next))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
566 (name (nth 2 next))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
567 (positive (nth 3 next))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
568 (found nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
569
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
570 ;; Delete the annotation
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
571 (delete-region loc end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
572 (cond
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
573 ;; Positive annotations are stacked, remembering location
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
574 (positive (setq open-ans (cons `(,name ((,loc . nil))) open-ans)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
575 ;; It is a negative annotation:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
576 ;; Close the top annotation & add its text property.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
577 ;; 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
578 ;; the top thing on the open-annotations stack.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
579 ;; If no matching annotation is open, just ignore the close.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
580 ((not (assoc name open-ans))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
581 (message "Extra closing annotation (%s) in file" name))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
582 ;; 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
583 ;; the things in between as well. Set `found' when the real
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
584 ;; one is closed.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
585 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
586 (while (not found)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
587 (let* ((top (car open-ans)) ; first on stack: should match.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
588 (top-name (car top)) ; text property name
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
589 (top-extents (nth 1 top)) ; property regions
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
590 (params (cdr (cdr top))) ; parameters
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
591 (aalist translations)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
592 (matched nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
593 (if (equal name top-name)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
594 (setq found t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
595 (message "Improper nesting in file."))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
596 ;; Look through property names in TRANSLATIONS
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
597 (while aalist
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
598 (let ((prop (car (car aalist)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
599 (alist (cdr (car aalist))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
600 ;; And look through values for each property
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
601 (while alist
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
602 (let ((value (car (car alist)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
603 (ans (cdr (car alist))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
604 (if (member top-name ans)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
605 ;; This annotation is listed, but still have to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
606 ;; check if multiple annotations are satisfied
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
607 (if (member nil (mapcar (lambda (r)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
608 (assoc r open-ans))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
609 ans))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
610 nil ; multiple ans not satisfied
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
611 ;; If there are multiple annotations going
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
612 ;; into one text property, split up the other
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
613 ;; annotations so they apply individually to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
614 ;; the other regions.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
615 (setcdr (car top-extents) loc)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
616 (let ((to-split ans) this-one extents)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
617 (while to-split
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
618 (setq this-one
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
619 (assoc (car to-split) open-ans)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
620 extents (nth 1 this-one))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
621 (if (not (eq this-one top))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
622 (setcar (cdr this-one)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
623 (format-subtract-regions
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
624 extents top-extents)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
625 (setq to-split (cdr to-split))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
626 ;; Set loop variables to nil so loop
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
627 ;; will exit.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
628 (setq alist nil aalist nil matched t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
629 ;; pop annotation off stack.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
630 open-ans (cdr open-ans))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
631 (let ((extents top-extents)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
632 (start (car (car top-extents)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
633 (loc (cdr (car top-extents))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
634 (while extents
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
635 (cond
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
636 ;; Check for pseudo-properties
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
637 ((eq prop 'PARAMETER)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
638 ;; A parameter of the top open ann:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
639 ;; delete text and use as arg.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
640 (if open-ans
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
641 ;; (If nothing open, discard).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
642 (setq open-ans
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
643 (cons
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
644 (append (car open-ans)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
645 (list
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
646 (buffer-substring
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
647 start loc)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
648 (cdr open-ans))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
649 (delete-region start loc))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
650 ((eq prop 'FUNCTION)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
651 ;; Not a property, but a function.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
652 (let ((rtn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
653 (apply value start loc params)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
654 (if rtn (setq todo (cons rtn todo)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
655 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
656 ;; Normal property/value pair
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
657 (setq todo
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
658 (cons (list start loc prop value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
659 todo))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
660 (setq extents (cdr extents)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
661 start (car (car extents))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
662 loc (cdr (car extents))))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
663 (setq alist (cdr alist))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
664 (setq aalist (cdr aalist)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
665 (unless matched
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
666 ;; Didn't find any match for the annotation:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
667 ;; Store as value of text-property `unknown'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
668 (setcdr (car top-extents) loc)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
669 (let ((extents top-extents)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
670 (start (car (car top-extents)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
671 (loc (cdr (car top-extents))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
672 (while extents
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
673 (setq open-ans (cdr open-ans)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
674 todo (cons (list start loc 'unknown top-name)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
675 todo)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
676 unknown-ans (cons name unknown-ans)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
677 extents (cdr extents)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
678 start (car (car extents))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
679 loc (cdr (car extents))))))))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
680
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
681 ;; Once entire file has been scanned, add the properties.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
682 (while todo
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
683 (let* ((item (car todo))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
684 (from (nth 0 item))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
685 (to (nth 1 item))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
686 (prop (nth 2 item))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
687 (val (nth 3 item)))
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 (if (numberp val) ; add to ambient value if numeric
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
690 (format-property-increment-region from to prop val 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
691 (put-text-property
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
692 from to prop
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
693 (cond ((get prop 'format-list-valued) ; value gets consed onto
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
694 ; list-valued properties
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
695 (let ((prev (get-text-property from prop)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
696 (cons val (if (listp prev) prev (list prev)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
697 (t val))))) ; normally, just set to val.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
698 (setq todo (cdr todo)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
699
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
700 (if unknown-ans
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
701 (message "Unknown annotations: %s" unknown-ans))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
702
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
703 (defun format-subtract-regions (minu subtra)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
704 "Remove the regions in SUBTRAHEND from the regions in MINUEND. A region
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
705 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
706 list must contain nonoverlapping, noncontiguous regions, in descending
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
707 order. The result is also nonoverlapping, noncontiguous, and in descending
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
708 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
709 the end of that region is not yet known."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
710 (let* ((minuend (copy-alist minu))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
711 (subtrahend (copy-alist subtra))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
712 (m (car minuend))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
713 (s (car subtrahend))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
714 results)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
715 (while (and minuend subtrahend)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
716 (cond
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
717 ;; The minuend starts after the subtrahend ends; keep it.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
718 ((> (car m) (cdr s))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
719 (setq results (cons m results)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
720 minuend (cdr minuend)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
721 m (car minuend)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
722 ;; The minuend extends beyond the end of the subtrahend. Chop it off.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
723 ((or (null (cdr m)) (> (cdr m) (cdr s)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
724 (setq results (cons (cons (1+ (cdr s)) (cdr m)) results))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
725 (setcdr m (cdr s)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
726 ;; The subtrahend starts after the minuend ends; throw it away.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
727 ((< (cdr m) (car s))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
728 (setq subtrahend (cdr subtrahend) s (car subtrahend)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
729 ;; The subtrahend extends beyond the end of the minuend. Chop it off.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
730 (t ;(<= (cdr m) (cdr s)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
731 (if (>= (car m) (car s))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
732 (setq minuend (cdr minuend) m (car minuend))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
733 (setcdr m (1- (car s)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
734 (setq subtrahend (cdr subtrahend) s (car subtrahend))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
735 (nconc (nreverse results) minuend)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
736
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
737 ;; This should probably go somewhere other than format.el. Then again,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
738 ;; indent.el has alter-text-property. NOTE: We can also use
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
739 ;; next-single-property-change instead of text-property-not-all, but then
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
740 ;; we have to see if we passed TO.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
741 (defun format-property-increment-region (from to prop delta default)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
742 "Increment property PROP over the region between FROM and TO by the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
743 amount DELTA (which may be negative). If property PROP is nil anywhere
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
744 in the region, it is treated as though it were DEFAULT."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
745 (let ((cur from) val newval next)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
746 (while cur
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
747 (setq val (get-text-property cur prop)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
748 newval (+ (or val default) delta)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
749 next (text-property-not-all cur to prop val))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
750 (put-text-property cur (or next to) prop newval)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
751 (setq cur next))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
752
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
753 ;;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
754 ;;; Encoding
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
755 ;;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
756
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
757 (defun format-insert-annotations (list &optional offset)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
758 "Apply list of annotations to buffer as `write-region' would.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
759 Inserts each element of the given LIST of buffer annotations at its
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
760 appropriate place. Use second arg OFFSET if the annotations' locations are
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
761 not relative to the beginning of the buffer: annotations will be inserted
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
762 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
763 of the first character in the buffer)."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
764 (if (not offset)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
765 (setq offset 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
766 (setq offset (1- offset)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
767 (let ((l (reverse list)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
768 (while l
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
769 (goto-char (- (car (car l)) offset))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
770 (insert (cdr (car l)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
771 (setq l (cdr l)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
772
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
773 (defun format-annotate-value (old new)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
774 "Return OLD and NEW as a \(close . open) annotation pair.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
775 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
776 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
777 `unknown' text property."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
778 (cons (if old (list old))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
779 (if new (list new))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
780
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
781 (defun format-annotate-region (from to trans format-fn ignore)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
782 "Generate annotations for text properties in the region.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
783 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
784 annotations as defined by alist TRANSLATIONS and FORMAT-FN. IGNORE lists text
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
785 properties not to consider; any text properties that are neither ignored nor
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
786 listed in TRANSLATIONS are warned about.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
787 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
788 function to `format-insert-annotations'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
789
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
790 Format of the TRANSLATIONS argument:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
791
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
792 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
793 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
794 ANNOTATIONS. Whenever the property takes on that value, the annotations
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
795 \(as formatted by FORMAT-FN) are inserted into the file.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
796 When the property stops having that value, the matching negated annotation
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
797 will be inserted \(it may actually be closed earlier and reopened, if
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
798 necessary, to keep proper nesting).
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 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
801 separately.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
802
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
803 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
804 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
805 Thus, given the entry \(left-margin \(4 \"indent\")), if the left margin
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
806 changes from 4 to 12, two <indent> annotations will be generated.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
807
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
808 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
809 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
810 transitions not explicitly listed in the table. The function is called with
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
811 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
812 lists of annotations like `format-annotate-location' does.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
813
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
814 The same structure can be used in reverse for reading files."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
815 (let ((all-ans nil) ; All annotations - becomes return value
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
816 (open-ans nil) ; Annotations not yet closed
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
817 (loc nil) ; Current location
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
818 (not-found nil)) ; Properties that couldn't be saved
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
819 (while (or (null loc)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
820 (and (setq loc (next-property-change loc nil to))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
821 (< loc to)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
822 (or loc (setq loc from))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
823 (let* ((ans (format-annotate-location loc (= loc from) ignore trans))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
824 (neg-ans (format-reorder (aref ans 0) open-ans))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
825 (pos-ans (aref ans 1))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
826 (ignored (aref ans 2)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
827 (setq not-found (append ignored not-found)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
828 ignore (append ignored ignore))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
829 ;; First do the negative (closing) annotations
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
830 (while neg-ans
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
831 ;; Check if it's missing. This can happen (eg, a numeric property
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
832 ;; going negative can generate closing annotations before there are
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
833 ;; any open). Warn user & ignore.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
834 (if (not (member (car neg-ans) open-ans))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
835 (message "Can't close %s: not open." (car neg-ans))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
836 (while (not (equal (car neg-ans) (car open-ans)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
837 ;; 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
838 ;; remembering to re-open them later.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
839 (setq pos-ans (cons (car open-ans) pos-ans))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
840 (setq all-ans
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
841 (cons (cons loc (funcall format-fn (car open-ans) nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
842 all-ans))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
843 (setq open-ans (cdr open-ans)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
844 ;; Now remove the one we're really interested in from open list.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
845 (setq open-ans (cdr open-ans))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
846 ;; And put the closing annotation here.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
847 (setq all-ans
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
848 (cons (cons loc (funcall format-fn (car neg-ans) nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
849 all-ans)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
850 (setq neg-ans (cdr neg-ans)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
851 ;; Now deal with positive (opening) annotations
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
852 (let ( ; (p pos-ans)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
853 )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
854 (while pos-ans
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
855 (setq open-ans (cons (car pos-ans) open-ans))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
856 (setq all-ans
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
857 (cons (cons loc (funcall format-fn (car pos-ans) t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
858 all-ans))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
859 (setq pos-ans (cdr pos-ans))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
860
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
861 ;; Close any annotations still open
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
862 (while open-ans
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
863 (setq all-ans
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
864 (cons (cons to (funcall format-fn (car open-ans) nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
865 all-ans))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
866 (setq open-ans (cdr open-ans)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
867 (if not-found
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
868 (message "These text properties could not be saved:\n %s"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
869 not-found))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
870 (nreverse all-ans)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
871
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
872 ;;; Internal functions for format-annotate-region.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
873
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
874 (defun format-annotate-location (loc all ignore trans)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
875 "Return annotation(s) needed at LOCATION.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
876 This includes any properties that change between LOC-1 and LOC.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
877 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
878 all non-nil properties.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
879 Third argument IGNORE is a list of text-properties not to consider.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
880
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
881 Return value is a vector of 3 elements:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
882 1. List of names of the annotations to close
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
883 2. List of the names of annotations to open.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
884 3. List of properties that were ignored or couldn't be annotated."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
885 (let* ((prev-loc (1- loc))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
886 (before-plist (if all nil (text-properties-at prev-loc)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
887 (after-plist (text-properties-at loc))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
888 p negatives positives prop props not-found)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
889 ;; make list of all property names involved
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
890 (setq p before-plist)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
891 (while p
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
892 (if (not (memq (car p) props))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
893 (setq props (cons (car p) props)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
894 (setq p (cdr (cdr p))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
895 (setq p after-plist)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
896 (while p
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
897 (if (not (memq (car p) props))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
898 (setq props (cons (car p) props)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
899 (setq p (cdr (cdr p))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
900
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
901 (while props
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
902 (setq prop (car props)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
903 props (cdr props))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
904 (if (memq prop ignore)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
905 nil ; If it's been ignored before, ignore it now.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
906 (let ((before (if all nil (car (cdr (memq prop before-plist)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
907 (after (car (cdr (memq prop after-plist)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
908 (if (equal before after)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
909 nil ; no change; ignore
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
910 (let ((result (format-annotate-single-property-change
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
911 prop before after trans)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
912 (if (not result)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
913 (setq not-found (cons prop not-found))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
914 (setq negatives (nconc negatives (car result))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
915 positives (nconc positives (cdr result)))))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
916 (vector negatives positives not-found)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
917
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
918 (defun format-annotate-single-property-change (prop old new trans)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
919 "Return annotations for PROPERTY changing from OLD to NEW.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
920 These are searched for in the TRANSLATIONS alist.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
921 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
922 function is called.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
923 Annotations to open and to close are returned as a dotted pair."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
924 (let ((prop-alist (cdr (assoc prop trans)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
925 ;; default
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
926 )
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
927 (if (not prop-alist)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
928 nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
929 ;; 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
930 (if (or (consp old) (consp new))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
931 (let* ((old (if (listp old) old (list old)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
932 (new (if (listp new) new (list new)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
933 ;; (tail (format-common-tail old new))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
934 close open)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
935 (while old
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
936 (setq close
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
937 (append (car (format-annotate-atomic-property-change
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
938 prop-alist (car old) nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
939 close)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
940 old (cdr old)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
941 (while new
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
942 (setq open
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
943 (append (cdr (format-annotate-atomic-property-change
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
944 prop-alist nil (car new)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
945 open)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
946 new (cdr new)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
947 (format-make-relatively-unique close open))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
948 (format-annotate-atomic-property-change prop-alist old new)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
949
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
950 (defun format-annotate-atomic-property-change (prop-alist old new)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
951 "Internal function annotate a single property change.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
952 PROP-ALIST is the relevant segment of a TRANSLATIONS list.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
953 OLD and NEW are the values."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
954 (let (num-ann)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
955 ;; If old and new values are numbers,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
956 ;; look for a number in PROP-ALIST.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
957 (if (and (or (null old) (numberp old))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
958 (or (null new) (numberp new)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
959 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
960 (setq num-ann prop-alist)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
961 (while (and num-ann (not (numberp (car (car num-ann)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
962 (setq num-ann (cdr num-ann)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
963 (if num-ann
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
964 ;; Numerical annotation - use difference
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
965 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
966 ;; If property is numeric, nil means 0
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
967 (cond ((and (numberp old) (null new))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
968 (setq new 0))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
969 ((and (numberp new) (null old))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
970 (setq old 0)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
971
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
972 (let* ((entry (car num-ann))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
973 (increment (car entry))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
974 (n (ceiling (/ (float (- new old)) (float increment))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
975 (anno (car (cdr entry))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
976 (if (> n 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
977 (cons nil (make-list n anno))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
978 (cons (make-list (- n) anno) nil))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
979
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
980 ;; Standard annotation
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
981 (let ((close (and old (cdr (assoc old prop-alist))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
982 (open (and new (cdr (assoc new prop-alist)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
983 (if (or close open)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
984 (format-make-relatively-unique close open)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
985 ;; Call "Default" function, if any
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
986 (let ((default (assq nil prop-alist)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
987 (if default
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
988 (funcall (car (cdr default)) old new))))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
989
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
990 ;;; format.el ends here