aboutsummaryrefslogtreecommitdiffhomepage
path: root/x-symbol/lisp
diff options
context:
space:
mode:
authorGravatar David Aspinall <da@inf.ed.ac.uk>2003-01-16 19:13:44 +0000
committerGravatar David Aspinall <da@inf.ed.ac.uk>2003-01-16 19:13:44 +0000
commit0705c7170b4e818a66ef2a1d7bd22c4969fb5855 (patch)
tree6a91ba4e085377b98d64e8e2364f7a0717e72b88 /x-symbol/lisp
parent4b7f885b622973d4d461e89b6f510435ad869d7b (diff)
X-Symbol version 4.45 beta
Diffstat (limited to 'x-symbol/lisp')
-rw-r--r--x-symbol/lisp/x-symbol.el4861
1 files changed, 4861 insertions, 0 deletions
diff --git a/x-symbol/lisp/x-symbol.el b/x-symbol/lisp/x-symbol.el
new file mode 100644
index 00000000..b5e6bf52
--- /dev/null
+++ b/x-symbol/lisp/x-symbol.el
@@ -0,0 +1,4861 @@
+;;; x-symbol.el --- semi WYSIWYG for LaTeX, HTML, etc using additional fonts
+
+;; Copyright (C) 1995-2003 Free Software Foundation, Inc.
+;;
+;; Author: Christoph Wedler <wedler@users.sourceforge.net>
+;; Maintainer: (Please use `M-x x-symbol-package-bug' to contact the maintainer)
+;; Version: 4.4.X
+;; Keywords: WYSIWYG, LaTeX, HTML, wp, math, internationalization
+;; X-URL: http://x-symbol.sourceforge.net/
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; if not, write to the Free Software
+;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+;;; Commentary:
+
+;; If you want to use package x-symbol, please visit the URL (use
+;; \\[x-symbol-package-web]) and read the info (use \\[x-symbol-package-info]).
+
+;; This is the main file of package X-Symbol. It also defines charsets for the
+;; basic fonts: latin1, latin2, latin3, latin5, xsymb0 and xsymb1.
+
+;; This file does some initialization. Thus, do not put any `defcustom'
+;; commands into this file. If you think some variables in this files should
+;; be customized, move them to file `x-symbol-vars.el'.
+
+;;; Code:
+
+(provide 'x-symbol)
+;;(require 'x-symbol-hooks)
+(require 'x-symbol-vars)
+(require (if (featurep 'mule) 'x-symbol-mule 'x-symbol-nomule))
+(eval-when-compile (require 'x-symbol-macs))
+(eval-when-compile (require 'cl))
+
+(eval-when-compile
+ (defvar font-lock-extra-managed-props) ; font-lock of Emacs-21.4
+ (defvar reporter-prompt-for-summary-p))
+
+;; CW: TODO
+(defvar x-symbol-trace-invisible nil)
+;; shows that invisible is reset but Emacs still shows it as invisible
+
+
+
+
+;;;;##########################################################################
+;;;; General code, default values for `x-symbol-*-function'
+;;;;##########################################################################
+
+
+;;;===========================================================================
+;;; Token languages
+;;;===========================================================================
+
+(defconst x-symbol-language-access-alist
+ `((x-symbol-auto-style "auto-style" t listp) ; redefinition, TODO: optional is just temporary
+ (x-symbol-modeline-name "modeline-name" nil stringp)
+ (x-symbol-required-fonts "required-fonts" t listp)
+ (x-symbol-token-grammar "token-grammar" nil
+ ,(lambda (x)
+ (or (vectorp x)
+ (eq (car-safe x) 'x-symbol-make-grammar))))
+ (x-symbol-input-token-grammar "input-token-grammar" nil consp)
+ (x-symbol-table "table" nil consp)
+ (x-symbol-generated-data "generated-data" nil null)
+ ;; input methods
+ (x-symbol-header-groups-alist "header-groups-alist" nil listp)
+ (x-symbol-class-alist "class-alist" nil listp)
+ (x-symbol-class-face-alist "class-face-alist" t listp)
+ (x-symbol-electric-ignore "electric-ignore")
+ (x-symbol-extra-menu-items "extra-menu-items" t listp)
+ ;; super-/subscripts, images
+ (x-symbol-subscript-matcher "subscript-matcher" t)
+ (x-symbol-image-keywords "image-keywords" t listp)
+ (x-symbol-master-directory "master-directory" x-symbol-image-keywords
+ functionp)
+ (x-symbol-image-searchpath "image-searchpath" x-symbol-image-keywords
+ listp)
+ (x-symbol-image-cached-dirs "image-cached-dirs" x-symbol-image-keywords
+ listp))
+ "Alist of token language dependent variable accesses.
+Each element looks like (ACCESS . SUFFIX) or (ACCESS MULE . NOMULE).
+With the first form, the symbol of the LANGUAGE dependent variable is
+`FEATURE-SUFFIX' where FEATURE is the value of LANGUAGE's symbol
+property `x-symbol-feature'. With the second form, the symbol is
+`FEATURE-MULE' when running under XEmacs/Mule or `FEATURE-NOMULE' when
+running under XEmacs/no-Mule. The symbol is stored as LANGUAGE's
+property ACCESS. To get a value of a language dependent variable, use
+`x-symbol-language-value'.
+
+The following language dependent access is defined after the language
+has been registered, see `x-symbol-register-language':
+
+ * `x-symbol-name': String naming the language when presented to the user.
+
+The following language dependent accesses are defined after the language
+has been initialized, see `x-symbol-init-language':
+
+ * `x-symbol-modeline-name': String naming the language in the modeline.
+ * `x-symbol-master-directory': Function returning the directory of the
+ master file, see `x-symbol-image-parse-buffer'.
+ * `x-symbol-image-searchpath': Search path used for implicitly relative
+ image file names, see `x-symbol-image-use-remote'.
+ * `x-symbol-image-cached-dirs': Directory parts of image file names
+ stored in the memory cache, see `x-symbol-image-use-remote'.
+ * `x-symbol-image-keywords': Keywords used to find image insertion
+ commands, see `x-symbol-image-parse-buffer'.
+ * `x-symbol-font-lock-keywords': font-lock keywords for super- and
+ subscripts.
+
+ * `x-symbol-header-groups-alist': If non-nil, used instead
+ `x-symbol-header-groups-alist' in the language specific grid/menu.
+ * `x-symbol-class-alist': Alist used for the info in the echo area, see
+ `x-symbol-character-info'. Each element looks like (CLASS . SPEC)
+ where CLASS is a valid token class, see `x-symbol-init-language' and
+ SPEC is used according to `x-symbol-fancy-string'. You should define
+ entries for the CLASSes `VALID' and `INVALID'.
+ * `x-symbol-class-face-alist': Alist used for the color scheme in the
+ language dependent grid and token info. Each element looks like
+ (CLASS FACE . FACE-SPECS) where CLASS is a valid token class, FACE is
+ used for the character in the grid, and FACE-SPECS is used according
+ to `x-symbol-fancy-string'.
+ * `x-symbol-electric-ignore': Language dependent version of
+ `x-symbol-electric-ignore', see variable `x-symbol-electric-input'.
+
+ * `x-symbol-required-fonts': Features providing fonts.
+ * `x-symbol-case-insensitive': If non-nil, tokens are case-insensitive.
+ The non-nil value should be a function: `upcase' or `downcase'.
+ * `x-symbol-token-shape': Used to (conditionally) prevent decoding
+ tokens of the given shape. Looks like
+ (TOKEN-ESC TOKEN-REGEXP . LETTER-REGEXP)
+ If TOKEN-ESC is non-nil, a token is not decoded if the character
+ before token is TOKEN-ESC, TOKEN-ESC is allowed to appear exactly
+ even times, though. If non-nil, TOKEN-REGEXP matches tokens not to
+ be decoded if LETTER-REGEXP matches the character after the token.
+ * `x-symbol-table': Table defining the language, includes user table.
+ * `x-symbol-token-list': The token specification in language tables are
+ passed to this function, see `x-symbol-init-language'.
+ * `x-symbol-input-token-ignore': Regexp or function used to \"hide\"
+ some tokens from input method TOKEN.
+ * `x-symbol-exec-specs': Specification used when building executables,
+ t if no executables should be built, see `x-symbol-exec-create'.
+
+The following internal language dependent accesses are defined after the
+language has been initialized, see `x-symbol-init-language':
+
+ * `x-symbol-menu-alist': Alist used for language dependent menu.
+ * `x-symbol-grid-alist': Alist used for language dependent grid.
+ * `x-symbol-decode-atree': Atree for used by `x-symbol-token-input'.
+ * `x-symbol-decode-alist': Alist used during decoding.
+ * `x-symbol-encode-alist': Alist used during encoding.
+ * `x-symbol-decode-exec': File name of decode executable. If this
+ access is not present, no warning is issued, as opposed to value nil.
+ * `x-symbol-encode-exec': File name of encode executable. If this
+ access is not present, no warning is issued, as opposed to value nil.")
+
+
+;;;===========================================================================
+;;; Structure data types
+;;;===========================================================================
+
+(defstruct (x-symbol-generated (:type vector)
+ (:constructor x-symbol-make-generated-data)
+ (:copier nil))
+ encode-table
+ decode-obarray
+ menu-alist
+ grid-alist
+ token-classes
+ max-token-len)
+
+(defstruct (x-symbol-grammar (:type vector)
+ (:constructor x-symbol-make-grammar)
+ (:copier nil))
+ case-function
+ encode-spec
+ decode-regexp
+ decode-spec
+ token-list
+ after-init)
+
+
+;;;===========================================================================
+;;; Internal variables used throughout the package
+;;;===========================================================================
+
+(defvar x-symbol-map nil
+ "Keymap for x-symbol key sequences starting with \\[x-symbol-map].
+Set by `x-symbol-init-input'.")
+
+(defvar x-symbol-unalias-alist nil
+ "Internal. Alist used to resolve character aliases.
+See `x-symbol-unalias'.")
+
+(defvar x-symbol-latin-decode-alists nil
+ "Internal. Alist used during decoding to handle different file codings.
+Used if `x-symbol-coding' differs from `x-symbol-default-coding'.")
+
+(defvar x-symbol-context-atree nil
+ "Internal. Atree used by input method context.
+See `x-symbol-modify-key'.")
+
+(defvar x-symbol-electric-atree nil
+ "Internal. Atree used by `x-symbol-electric-input'.")
+
+(defvar x-symbol-grid-alist nil
+ "Internal. Alist containing the global grid.")
+
+(defvar x-symbol-menu-alist nil
+ "Internal. Alist containing the global submenus for insert commands.")
+
+(defvar x-symbol-all-charsyms nil
+ "Internal. List of all defined charsyms in order of definition.
+Symbol property `x-symbol-decode-alist' is a cache {symbol-name->symbol}
+used by `x-symbol-read-token'.")
+
+(defvar x-symbol-fancy-value-cache nil
+ "Internal. Cache for `x-symbol-fancy-value'.")
+
+;; encoding -> charsym-for-char-in-encoding-cset -> char-in-default-cset
+(defvar x-symbol-fchar-tables nil)
+
+;; encoding -> charsym-for-char-in-encoding-cset -> char-in-encoding-cset (string in nomule)
+(defvar x-symbol-bchar-tables nil)
+
+(defvar x-symbol-cstring-table nil)
+
+(defvar x-symbol-fontified-cstring-table nil)
+
+(defvar x-symbol-charsym-decode-obarray nil)
+
+
+;;;===========================================================================
+;;; General functions
+;;;===========================================================================
+
+(defun x-symbol-set-variable (var value)
+ "Set VAR's value to VALUE, using special set functions.
+If VAR has a symbol property `x-symbol-set-function', use that function
+instead `set' to set the value. At the end, run each hook in the symbol
+property `x-symbol-after-set-hook' of VAR."
+ (if (get var 'x-symbol-set-function)
+ (funcall (get var 'x-symbol-set-function) var value)
+ (if (and (get var 'custom-type)
+ (null (local-variable-if-set-p var (current-buffer))))
+ (customize-set-variable var value)
+ (set var value)))
+ (let ((hook (get var 'x-symbol-after-set-hook)))
+ (while hook (funcall (pop hook)))))
+
+(defun x-symbol-ensure-hashtable (symbol)
+ "Make sure that SYMBOL's value is a hashtable.
+The initial size of the key-weak hashtable is `x-symbol-cache-size'."
+ (or (hash-table-p (symbol-value symbol))
+ (set symbol (make-hash-table :size x-symbol-cache-size
+ :test 'eq :weakness 'key))))
+
+(defun x-symbol-puthash (key val hashtable)
+ "Hash KEY to VAL in HASHTABLE. Return VAL.
+Flush HASHTABLE, i.e., delete all entries before, if number of entries
+would become larger than `x-symbol-cache-size'."
+ (if (>= (hash-table-count hashtable) x-symbol-cache-size)
+ (clrhash hashtable))
+ (puthash key val hashtable))
+
+(defun x-symbol-call-function-or-regexp (callee string &rest args)
+ "Check STRING by calling function or matching a regexp.
+If CALLEE is a function, call function with first argument STRING and
+rest ARGS. If it is a string, return index of start of first match for
+CALLEE in STRING."
+ (if (stringp callee)
+ (string-match callee string)
+ (if (fboundp callee) (apply callee string args))))
+
+(defun x-symbol-match-in-alist (elem alist &optional result replacep)
+ "Check ALIST for element whose car is a regexp matching elem.
+Return cdr of matching element or RESULT if the cdr is nil. If REPLACEP
+is non-nil and the cdr is a string, replace text matched by the car with
+the cdr and return result, see `replace-match' for details. If REPLACEP
+is non-nil and the cdr is a non-empty list, call the car of the cdr with
+ELEM and the remaining arguments in the cdr of the cdr to get the
+result."
+ (let (match)
+ (while alist
+ (if (string-match (caar alist) elem)
+ (setq result (cdar alist)
+ match t
+ alist nil)
+ (setq alist (cdr alist))))
+ (if (and replacep match)
+ (cond ((stringp result) (replace-match result t nil elem))
+ ((consp result) (apply (car result) elem (cdr result)))
+ (t result))
+ result)))
+
+
+;;;===========================================================================
+;;; Strings with properties (inclusive. caching)
+;;;===========================================================================
+;; both Emacs and XEmacs fail with properties & `format': XEmacs drops the
+;; properties, Emacs does it wrong, i.e., keeps the original positions in the
+;; format string
+
+(defun x-symbol-fancy-string (spec)
+ "Return a \"fancy\" string according to SPEC.
+SPEC has the form (STRING FACE-SPEC...). Return a copy of STRING
+annotated with faces as duplicatable text properties. FACE-SPEC has the
+form ([START [END]] FACE...). All characters between START and END are
+attached with FACEs. START and END can be positive numbers, denoting
+string positions, negative numbers, denoting positions from the end, and
+default to 0 or the end of the string, respectively."
+ (if (cdr spec)
+ (let* ((string (copy-sequence (pop spec)))
+ (len (length string))
+ faces start end)
+ (while spec
+ (setq faces (pop spec))
+ (setq start (if (numberp (car faces)) (pop faces) 0)
+ end (if (numberp (car faces)) (pop faces) len))
+ (put-text-property (if (natnump start) start (+ len start))
+ (if (natnump end) end (+ len end))
+ 'face faces string))
+ string)
+ (car spec)))
+
+(defun x-symbol-fancy-value (symbol &optional string-fn)
+ "Return the \"fancy\" value of variable SYMBOL.
+If the value is not cached in SYMBOL's property `x-symbol-fancy-value',
+pass SYMBOL's value SPEC to `x-symbol-fancy-string', caching the result.
+If STRING-FN is non-nil, the STRING part of SPEC is passed to function
+STRING-FN before."
+ (or (hash-table-p x-symbol-fancy-value-cache)
+ (setq x-symbol-fancy-value-cache
+ (make-hash-table :size x-symbol-fancy-cache-size :test 'eq)))
+ (or (gethash symbol x-symbol-fancy-value-cache)
+ (puthash symbol
+ (let ((spec (symbol-value symbol)))
+ (x-symbol-fancy-string
+ (if string-fn
+ (cons (funcall string-fn (car spec)) (cdr spec))
+ spec)))
+ x-symbol-fancy-value-cache)))
+
+
+(defun x-symbol-fancy-associations (symbols spec-alist pre sep post
+ &optional default)
+ "Return all \"fancy\" associations for SYMBOLS in SPEC-ALIST.
+SPEC-ALIST should have elements which look like (SYMBOL . SPEC).
+Collect all SPECs whose SYMBOL is a element in SYMBOLS or is equal to
+DEFAULT when no SPEC can be collected.
+
+If SPECs is nil, concat the fancy value of PRE with all fancy strings of
+SPECs separated by the fancy value of SEP, and the fancy value of POST,
+see `x-symbol-fancy-string' and `x-symbol-fancy-value'."
+ (let (spec result)
+ (while symbols
+ (and (setq spec (cdr (assq (pop symbols) spec-alist)))
+ (push spec result)))
+ (and (null result)
+ (setq spec (cdr (assq default spec-alist)))
+ (setq result (list spec)))
+ (when result
+ (concat (x-symbol-fancy-value pre)
+ (mapconcat 'x-symbol-fancy-string
+ (nreverse result)
+ (x-symbol-fancy-value sep))
+ (x-symbol-fancy-value post)))))
+
+
+;;;===========================================================================
+;;; Tiny x-symbol specific functions
+;;;===========================================================================
+
+(defun x-symbol-language-value (access &optional language)
+ "Return value of language dependent variable accessed by ACCESS.
+LANGUAGE defaults to `x-symbol-language'. If necessary, load file
+providing the token language and initialize language. For supported
+accesses, see `x-symbol-language-access-alist'."
+ (or language (setq language x-symbol-language))
+ (let ((symbol (get language access)))
+ (if symbol (symbol-value symbol)
+ (and language
+ (null (get language 'x-symbol-initialized))
+ (or (x-symbol-init-language language)
+ (warn "Illegal X-Symbol token language `%s'" language))
+ (symbol-value (get language access))))))
+
+(defun x-symbol-charsym-face (charsym language)
+ "Return face and face specs for CHARSYM in LANGUAGE.
+The returned value is (FACE . FACE-SPECS) where FACE is used for the
+grid and FACE-SPECS for the token in the info. For the format of
+FACE-SPECS, see `x-symbol-fancy-string'. The value depends on the first
+token class and the language access `x-symbol-class-face-alist'."
+ (cdr (assq (car (gethash charsym
+ (x-symbol-generated-token-classes
+ (x-symbol-language-value
+ 'x-symbol-generated-data language))))
+ (x-symbol-language-value 'x-symbol-class-face-alist language))))
+
+(defun x-symbol-image-available-p ()
+ "Non-nil, if `x-symbol-image' can be set in current file."
+ (and (x-symbol-language-value 'x-symbol-image-keywords)
+ (null (file-remote-p default-directory))))
+
+(defun x-symbol-default-context-info-ignore (context charsym)
+ "Non-nil, if no info in the echo area should be shown for CONTEXT.
+The CONTEXT would be modified to the character represented by CHARSYM.
+Return non-nil, if the group of CHARSYM is a member of
+`x-symbol-context-info-ignore-groups' or the context is shorter than
+`x-symbol-context-info-threshold' or the context is matched by
+`x-symbol-context-info-ignore-regexp'. This function is the default
+value for `x-symbol-context-info-ignore'."
+ (or (memq (car (get charsym 'x-symbol-grouping))
+ x-symbol-context-info-ignore-groups)
+ (< (length context) x-symbol-context-info-threshold)
+ (and x-symbol-context-info-ignore-regexp
+ (string-match x-symbol-context-info-ignore-regexp context))))
+
+(defun x-symbol-default-info-keys-keymaps (&optional dummy)
+ ;; checkdoc-params: (dummy)
+ "Used in keys info for not showing the prefix \\[x-symbol-map].
+Used as the default value for `x-symbol-info-keys-keymaps'."
+ ;; probably just `x-symbol-map' with Emacs-20.4
+ (list x-symbol-map))
+
+
+;;;===========================================================================
+;;; Get Valid charsyms
+;;;===========================================================================
+
+(defun x-symbol-alias-charsym (pos+charsym)
+ "Charsym of character alist, nil for other characters.
+If the character after the `car' of POS+CHARSYM is a character alias,
+return the `cdr' of POS+CHARSYM."
+ (and (car pos+charsym)
+ (not (eq (char-after (car pos+charsym))
+ (aref (gethash (cdr pos+charsym) x-symbol-cstring-table) 0)))
+ (cdr pos+charsym)))
+
+(defun x-symbol-default-valid-charsym (charsym &optional language)
+ "Non-nil, if CHARSYM is valid in LANGUAGE.
+If LANGUAGE is non-nil or `x-symbol-mode' is on, CHARSYM must represent
+a token in LANGUAGE which defaults to `x-symbol-language'. Otherwise,
+it should be a 8bit character according to `x-symbol-coding'.
+If LANGUAGE is non-nil, the result looks like (TOKEN . MISC)."
+ (if (or language (and x-symbol-mode x-symbol-language))
+ (and (or language
+ (null x-symbol-coding) ; default coding
+ (assq x-symbol-coding x-symbol-fchar-tables) ; valid coding
+ (not (gethash charsym ; not a 8bit char in default coding
+ (cdr (assq (x-symbol-buffer-coding)
+ x-symbol-fchar-tables)))))
+ (gethash charsym (x-symbol-generated-encode-table
+ (x-symbol-language-value
+ 'x-symbol-generated-data
+ (or language x-symbol-language)))))
+ (gethash charsym (cdr (assq (or (x-symbol-buffer-coding)
+ x-symbol-default-coding
+ 'iso-8859-1)
+ x-symbol-fchar-tables)))))
+
+(defun x-symbol-next-valid-charsym (charsym direction &optional prop tried)
+ "Return a valid charsym starting with CHARSYM.
+Try CHARSYM first, if it is not valid, use CHARSYM's property PROP. If
+DIRECTION is not t, charsym must have a rotate aspect direction with
+value DIRECTION. Do not try to use charsyms in TRIED. See
+`x-symbol-valid-charsym-function'."
+ (let ((line (and (consp charsym) (prog1 (cdr charsym)
+ (setq charsym (car charsym))))))
+ (while (and charsym
+ (if (memq charsym tried)
+ (setq charsym nil)
+ (push charsym tried))
+ (not (and (gethash charsym x-symbol-cstring-table) ; CW: nec?
+ (funcall x-symbol-valid-charsym-function charsym)
+ (or (eq direction t)
+ (eq (plist-get
+ (cdr (get charsym 'x-symbol-rotate-aspects))
+ 'direction)
+ direction)))))
+ (if line
+ (setq charsym (car line)
+ line (cdr line))
+ (if (consp (setq charsym (get charsym prop)))
+ (setq line (cdr charsym)
+ charsym (car charsym)))))
+ charsym))
+
+(defun x-symbol-valid-context-charsym (atree &optional prop)
+ "Return first valid charsym for longest context match before point.
+Return (START . CHARSYM) where the buffer substring between START and
+point is the key to the association VALUE in ATREE, see also
+`x-symbol-match-before'. CHARSYM is the VALUE or the next valid charsym
+using PROP, see `x-symbol-next-valid-charsym'."
+ (let* ((pos+charsym (x-symbol-match-before atree (point)))
+ (charsym (and (cdr pos+charsym)
+ (x-symbol-next-valid-charsym (cdr pos+charsym) t prop))))
+ (and charsym (cons (car pos+charsym) charsym))))
+
+(defun x-symbol-next-valid-charsym-before (prop1 prop2)
+ "Return next valid charsym for character before point.
+Return (POS . CHARSYM) where POS is usually the point position. If
+character is an character alias, resolve it. Otherwise, try chain
+according to PROP1, then use the OPPOSITE of the character, see
+`x-symbol-init-cset', then try chain according to PROP2."
+ (let* ((pos+charsym (x-symbol-charsym-after (1- (point))))
+ (charsym (cdr pos+charsym)))
+ (and charsym
+ (setq charsym (or (x-symbol-alias-charsym pos+charsym)
+ (x-symbol-next-valid-charsym
+ (get charsym prop1) t prop1 (list charsym))
+ (x-symbol-next-valid-charsym
+ (caddr (get charsym 'x-symbol-grouping)) t
+ 'x-symbol-modify-to (list charsym))
+ (x-symbol-next-valid-charsym
+ (get charsym prop2) t prop2 (list charsym))))
+ (cons (car pos+charsym) charsym))))
+
+
+;;;===========================================================================
+;;; Text functions
+;;;===========================================================================
+
+(defun x-symbol-prefix-arg-texts (arg)
+ "Return texts for prefix argument ARG."
+ (if (consp arg)
+ '("token" . "once")
+ (cons (if (natnump (setq arg (prefix-numeric-value arg)))
+ "valid character"
+ "character")
+ (if (= (abs arg) 1) "once" (format "%d times" (abs arg))))))
+
+(defun x-symbol-region-text (&optional long)
+ "Return \"Region\", \"Buffer\" or \"Narrowed Part\".
+When non-nil, use format string FORMAT."
+ (cond ((region-active-p) "Region")
+ ((and (= (point-min) 1) (= (point-max) (1+ (buffer-size))))
+ "Buffer")
+ (long "Buffer/narrowed")
+ (t "Buffer/n")))
+
+(defun x-symbol-language-text (&optional format language)
+ "Return text for LANGUAGE, to be presented to the user.
+LANGUAGE defaults to `x-symbol-language'. If LANGUAGE is nil, return
+`x-symbol-charsym-name'. When non-nil, use format string FORMAT."
+ (let ((text (or (x-symbol-language-value 'x-symbol-name language)
+ x-symbol-charsym-name)))
+ (if format (format format text) text)))
+
+(defun x-symbol-coding-text (coding &optional coding2 format)
+ "Return text for coding, to be presented to the user.
+Use association in `x-symbol-coding-name-alist' if `x-symbol-8bits' is
+non-nil, \"Ascii\" otherwise. If both CODING1 and CODING2 are provided
+use format FORMAT with the associations for CODING1 and CODING2,
+otherwise just return text for CODING1."
+ (if format
+ (if (or (null (and coding coding2)) (eq coding coding2))
+ ""
+ (format format
+ (x-symbol-coding-text coding)
+ (x-symbol-coding-text coding2)))
+ (or (cdr (assq (or coding (x-symbol-buffer-coding))
+ x-symbol-coding-name-alist))
+ "Ascii")))
+
+;;;(defvar x-symbol-unsupported-coding-modeline-alist nil)
+
+(defun x-symbol-language-modeline-text (language)
+ "Return text for LANGUAGE, to be presented in the modeline."
+ (or (and (setq language (and (boundp language) (symbol-value language)))
+ (x-symbol-language-value 'x-symbol-modeline-name))
+ x-symbol-modeline-name))
+
+(defun x-symbol-coding-modeline-text (coding)
+ "Return text for symbol value of CODING, to be used in the modeline.
+Use association in `x-symbol-coding-modeline-alist' if value of CODING
+differs from `x-symbol-default-coding', \"\" otherwise."
+ (setq coding (and (boundp coding) (symbol-value coding)))
+ (let ((buffer-coding (x-symbol-buffer-coding)))
+ (cdr (assq (cond ((null buffer-coding)
+ (if x-symbol-8bits 'error (if coding 'info 'none)))
+ ((or (null coding) (eq coding buffer-coding))
+ (if (eq buffer-coding x-symbol-default-coding)
+ 'same
+ buffer-coding))
+ ((and (eq buffer-coding x-symbol-default-coding)
+ (assq coding x-symbol-fchar-tables))
+ coding)
+ (t
+ (if x-symbol-8bits 'error 'info)))
+ x-symbol-coding-modeline-alist))))
+;;; (and (setq coding (and (boundp coding) (symbol-value coding)))
+;;; (null (eq coding x-symbol-default-coding))
+;;; (let ((string (cdr (assq coding x-symbol-coding-modeline-alist))))
+;;; (if (assq coding x-symbol-fchar-tables)
+;;; string
+;;; (format x-symbol-coding-modeline-warning-format (or string ""))))))
+
+;;; (let ((string (assq coding x-symbol-coding-modeline-alist)))
+;;; (if (assq coding x-symbol-fchar-tables)
+;;; (cdr string)
+;;; (or string (setq coding 'error))
+;;; (or (cdr (assq coding x-symbol-unsupported-coding-modeline-alist))
+;;; (let ((fstring (copy-sequence
+;;; (or (cdr (assq coding
+;;; x-symbol-coding-modeline-alist))
+;;; "-err"))))
+;;; (put-text-property 0 (length fstring)
+;;; 'face 'x-symbol-modeline-warning-face
+;;; fstring)
+;;; (push (cons coding fstring)
+;;; x-symbol-unsupported-coding-modeline-alist)
+;;; fstring))))))
+
+
+;;;===========================================================================
+;;; reftex support (could be useful otherwise, too)
+;;;===========================================================================
+
+;;;###autoload
+(defun x-symbol-translate-to-ascii (string)
+ "Translate STRING to an ascii string.
+Non-ascii characters in STRING are converted to charsyms. Their ascii
+representation is determined by:
+
+ * If CHARSYM is a key in `x-symbol-charsym-ascii-alist', use its ASCII.
+ * Charsym is defined in the table to have an ascii representation, see
+ ASCII in `x-symbol-init-cset'.
+ * Compute ascii representation according to the CHARSYM's GROUP,
+ SUBGROUP and `x-symbol-charsym-ascii-groups'.
+ * Use \"\" otherwise."
+ (mapconcat (lambda (item)
+ (if (characterp item)
+ (char-to-string item)
+ (let ((grouping (get item 'x-symbol-grouping)))
+ (or (cdr (assq item x-symbol-charsym-ascii-alist))
+ (cadddr grouping)
+ (and (memq (car grouping)
+ x-symbol-charsym-ascii-groups)
+ (cadr grouping))))))
+ (x-symbol-string-to-charsyms string)
+ ""))
+
+
+;;;===========================================================================
+;;; Key bindings
+;;;===========================================================================
+
+
+;;;===========================================================================
+;;; Package info / bug report
+;;;===========================================================================
+
+;;;###autoload
+(defun x-symbol-package-web ()
+ "Ask a WWW browser to load URL `x-symbol-package-url'."
+ (interactive)
+ (browse-url x-symbol-package-url)
+ (message "Sent URL of package x-symbol to your web browser"))
+
+;;;###autoload
+(defun x-symbol-package-info ()
+ "Read documentation for package X-Symbol in the info system."
+ (interactive)
+ (Info-goto-node "(x-symbol)"))
+
+;;;###autoload
+(defun x-symbol-package-bug (&optional arg)
+ "Send a bug/problem report to the maintainer of package X-Symbol.
+Please try to contact person in `x-symbol-installer-address' first.
+Normal reports are sent without prefix argument ARG.
+
+If you are sure that the problem cannot be solved locally, e.g., by
+contacting the person who has installed package X-Symbol, use prefix
+argument 2 to send the message to `x-symbol-maintainer-address'.
+
+If your message has nothing to do with a problem or a bug, use prefix 9
+to send a short message to `x-symbol-maintainer-address'."
+ (interactive "p")
+ (or (= arg 9)
+ (condition-case nil
+ (progn (Info-goto-node "(x-symbol)Bug Reports") t)
+ (error (setq arg 1) x-symbol-installer-address))
+ (with-output-to-temp-buffer "*Help*"
+ (beep)
+ (set-buffer "*Help*")
+ (princ "\
+The info files for package X-Symbol are not installed.
+
+Please read the manual before contacting the maintainer of package
+X-Symbol. If you want to send a bug/problem report or a question,
+please follow the instructions in the manual.
+
+The manual is also available as an HTML document at the web page of
+package X-Symbol:
+ ")
+ (princ x-symbol-package-url)
+ nil)
+ (null (y-or-n-p "Send URL of package X-Symbol to your web browser? "))
+ (x-symbol-package-web))
+ (require 'reporter)
+ (let ((reporter-prompt-for-summary-p t)) ;# dynamic
+ ;; For some reasons, the package version in the subject line, which I
+ ;; definitely want, is only inserted with value t. Thus, I ignore user
+ ;; wishes here.
+ (reporter-submit-bug-report
+ (or (unless (or (= arg 9) (= arg 2)) x-symbol-installer-address)
+ x-symbol-maintainer-address)
+ (concat "x-symbol " x-symbol-version)
+ (unless (= arg 9)
+ `(command-line-args x-symbol-auto-style-alist
+ x-symbol-default-coding
+ x-symbol-image-converter
+ ,@(and (featurep 'x-symbol-nomule)
+ '(x-symbol-nomule-leading-faces-alist))
+ features)))))
+
+;;;###autoload
+(defun x-symbol-package-reply-to-report ()
+ "Reply to a bug/problem report not using \\[x-symbol-package-bug]."
+ (interactive)
+ (insert "\
+Thank you for trying package X-Symbol. If you have problems, please use
+`M-x x-symbol-package-bug' to contact the maintainer. Do not assume
+that I remember the contents of your message (appended to this reply)...
+er, I have actually deleted it.")
+ (goto-char (point-max))
+ (when (get-buffer " *gnus article copy*")
+ (newline)
+ (insert-buffer " *gnus article copy*")))
+
+
+
+;;;;##########################################################################
+;;;; Conversion, Minor Mode Control, Menu
+;;;;##########################################################################
+
+
+(defvar x-symbol-encode-rchars 1
+ "Internal variable. Is always 1 with Mule support, 1 or 2 without.")
+
+
+;;;===========================================================================
+;;; Conversion
+;;;===========================================================================
+
+(defun x-symbol-even-escapes-before-p (pos esc)
+ (let ((even t))
+ (while (eq (char-before pos) esc)
+ (setq even (not even)
+ pos (1- pos)))
+ even))
+
+;;;###autoload
+(defun x-symbol-decode-region (beg end)
+ "Decode all tokens between BEG and END.
+Make sure that X-Symbol characters are correctly displayed under
+XEmacs/no-Mule even when font-lock is disabled."
+ (save-restriction
+ (narrow-to-region beg end)
+ (x-symbol-decode-all)
+ ;; Is the following really necessary? Anyway, it doesn't hurt...
+ (unless (featurep 'mule) (x-symbol-nomule-fontify-cstrings))
+ ))
+
+;;;###autoload
+(defun x-symbol-decode-all ()
+ "Decode all tokens in buffer to characters.
+Use executables for decoding if buffer is larger than EXEC-THRESHOLD
+which defaults to `x-symbol-exec-threshold'. Before decoding, decode
+8bit characters in CODING which defaults to `x-symbol-coding'."
+ ;; Assumptions: ------------------------------------------------------------
+ ;; * Latin decode alists are ordered, see `x-symbol-init-latin-decoding'
+ ;; * No part of the association is a KEY in the conversion alists
+ ;; * Keys in conversion alists are ordered: long...short
+ (let* ((grammar (x-symbol-language-value 'x-symbol-token-grammar))
+ (decode-obarray (if x-symbol-language
+ (x-symbol-generated-decode-obarray
+ (x-symbol-language-value
+ 'x-symbol-generated-data))))
+ (buffer-coding (x-symbol-buffer-coding))
+ (unique (and x-symbol-unique t)))
+ ;; TODO: recheck. Decode uniquely and do not decode to 8bit if current
+ ;; coding is unknown, otherwise we would wrongly use the same char for a
+ ;; token and an 8bit char in the file. E.g., with latin1 as default and we
+ ;; visit a tex file with latin9 encoding where both the euro character and
+ ;; \textcurrency is used. If you use XEmacs on Windows, there is no latin9
+ ;; font and therefore no recoding would take place, i.e., you would see the
+ ;; euro character as the currency character (as you would w/o X-Symbol).
+ ;; But then it would be very bad if \textcurrency would be decoded to the
+ ;; currency character.
+ (when buffer-coding
+ (let ((fchar-table (assq (or x-symbol-coding buffer-coding)
+ x-symbol-fchar-tables)))
+ (if (eq buffer-coding x-symbol-default-coding)
+ (let* ((case-fold-search nil) ;#dynamic
+ (coding-alist (cdr (assq x-symbol-coding x-symbol-latin-decode-alists)))
+ from to)
+ (while coding-alist
+ (setq from (caar coding-alist)
+ to (cdar coding-alist)
+ coding-alist (cdr coding-alist))
+ (goto-char (point-min))
+ (while (search-forward from nil 'limit)
+ (replace-match to t t))))
+ ;; TODO: unalias only with 8bit would be faster, but if done
+ ;; interactively?
+ (x-symbol-unalias nil nil buffer-coding)
+ (or (null x-symbol-coding) (eq x-symbol-coding buffer-coding)
+ (setq fchar-table nil)))
+ (setq unique (if x-symbol-8bits
+ (if fchar-table
+ (and x-symbol-unique (cdr fchar-table))
+ ;; invalid coding w/ 8bit => unique
+ (cdr (assq buffer-coding x-symbol-fchar-tables)))
+ (and x-symbol-unique t)))))
+ ;; the real decoding -----------------------------------------------------
+ (when decode-obarray
+ (let ((case-fold-search (x-symbol-grammar-case-function
+ grammar)) ;#dynamic
+ (decode-spec (x-symbol-grammar-decode-spec grammar))
+ (decode-regexp (x-symbol-grammar-decode-regexp grammar)))
+ (goto-char (point-min))
+ (if (functionp decode-spec)
+ (funcall decode-spec decode-regexp decode-obarray unique)
+ (x-symbol-decode-lisp decode-spec decode-regexp decode-obarray
+ unique))))))
+
+;;;###autoload
+(defun x-symbol-decode-single-token (string)
+ (when x-symbol-language
+ (let ((token (symbol-value
+ (intern-soft string
+ (x-symbol-generated-decode-obarray
+ (x-symbol-language-value
+ 'x-symbol-generated-data))))))
+ (if token (gethash (car token) x-symbol-cstring-table)))))
+
+(defun x-symbol-decode-lisp (contexts decode-regexp decode-obarray unique)
+ (let ((case-fn (if (functionp case-fold-search) case-fold-search))
+ (before-context (car contexts))
+ (after-context (cdr contexts))
+ charsym esc-char shape bad-regexp)
+ (when (characterp before-context)
+ (or (memq before-context '(?\ ?\t ?\n ?\r nil)) ; or warning?
+ (setq esc-char before-context))
+ (setq before-context nil))
+ (or before-context after-context (setq contexts nil))
+ ;; -----------------------------------------------------------------------
+ (x-symbol-decode-for-charsym ((decode-regexp decode-obarray case-fn)
+ token beg end)
+ nil
+ (cond ((x-symbol-decode-unique-test token unique))
+ ((and esc-char (eq (char-before beg) esc-char)
+ (x-symbol-even-escapes-before-p (1- beg) esc-char)))
+ ((not (and contexts (setq shape (cadr token))))
+ (if (setq charsym (car token))
+ (replace-match (gethash charsym x-symbol-cstring-table) t t)))
+ ((and (setq bad-regexp (assq shape after-context))
+ (not (memq (char-after) '(?\ ?\t ?\n ?\r nil)))
+ (looking-at (cdr bad-regexp))))
+ ((and (setq bad-regexp (assq shape before-context))
+ (not (memq (char-before beg) '(?\ ?\t ?\n ?\r nil)))
+ (string-match (cdr bad-regexp)
+ (char-to-string (char-before beg)))))
+ ((setq charsym (car token))
+ (insert-before-markers (gethash charsym x-symbol-cstring-table))
+ (delete-region beg end))))))
+
+;;;###autoload
+(defun x-symbol-encode-all (&optional buffer start end)
+ "Encode all characters in buffer to tokens.
+Use executables for decoding if buffer is larger than EXEC-THRESHOLD
+which defaults to `x-symbol-exec-threshold'. If CODING is non-nil, do
+not encode 8bit characters in CODING. Otherwise, do not encode 8bit
+characters in `x-symbol-coding' or `x-symbol-default-coding' if
+`x-symbol-8bits' is non-nil. If BUFFER is non-nil, copy contexts
+between START and END to BUFFER, make BUFFER current and do conversion
+there. If BUFFER is non-nil, START and END must be buffer positions or
+START is a string, see kludgy feature of `write-region'."
+ (let ((grammar (x-symbol-language-value 'x-symbol-token-grammar))
+ (encode-table (x-symbol-generated-encode-table
+ (x-symbol-language-value
+ 'x-symbol-generated-data)))
+ (buffer-coding (x-symbol-buffer-coding))
+ (coding (if x-symbol-coding
+ (if (assq x-symbol-coding x-symbol-fchar-tables)
+ x-symbol-coding
+ t)))
+ (store8 x-symbol-8bits))
+ (if buffer
+ (if start
+ (let ((curr-buffer (current-buffer)))
+ (if (featurep 'mule)
+ (let ((coding-system buffer-file-coding-system))
+ (set-buffer buffer)
+ (setq buffer-file-coding-system coding-system))
+ (set-buffer buffer))
+ (x-symbol-set-buffer-multibyte)
+ (if write-region-annotations-so-far
+ (format-insert-annotations write-region-annotations-so-far
+ start))
+ (if (stringp start)
+ (insert start) ; kludgy feature of `write-region'
+ (insert-buffer-substring curr-buffer start end))
+ ;;(set-text-properties (point-min) (point-max) nil)
+ (map-extents (lambda (e dummy) (delete-extent e) nil)))
+ (if (featurep 'mule) ; TODO: should be done by format.el
+ (let ((coding-system buffer-file-coding-system))
+ (set-buffer buffer)
+ (setq buffer-file-coding-system coding-system))
+ (set-buffer buffer))))
+ ;; (set-buffer buffer)))
+ ;; format.el should now set multibyte itself, we'll see
+ ;; (x-symbol-set-buffer-multibyte)))
+ ;; the encoding ----------------------------------------------------------
+ (let* ((case-fold-search (x-symbol-grammar-case-function grammar)) ;#dynamic
+ (encode-spec (x-symbol-grammar-encode-spec grammar))
+ (fchar-fb-table (cdr (if buffer-coding
+ (if (eq buffer-coding x-symbol-default-coding) ; should always be the case for non-mule
+ (or (assq coding x-symbol-fchar-tables) ; valid specified coding
+ (assq buffer-coding x-symbol-fchar-tables)) ; invalid coding or not specified
+ (assq buffer-coding x-symbol-bchar-tables))
+ (assq (or x-symbol-default-coding 'iso-8859-1)
+ x-symbol-fchar-tables))))
+ (fchar-table (if store8 fchar-fb-table)))
+ (goto-char (point-min))
+ (if (functionp encode-spec)
+ (funcall encode-spec encode-table fchar-table fchar-fb-table)
+ (x-symbol-encode-lisp encode-spec encode-table
+ fchar-table fchar-fb-table)))))
+
+(defun x-symbol-encode-lisp (contexts encode-table fchar-table fchar-fb-table)
+ (let ((before-context (car contexts))
+ (after-context (cdr contexts))
+ esc-char shape bad-regexp)
+ (when (characterp before-context)
+ (or (memq before-context '(?\ ?\t ?\n ?\r nil)) ; or warning?
+ (setq esc-char before-context))
+ (setq before-context nil))
+ (or before-context after-context (setq contexts nil))
+
+ (x-symbol-encode-for-charsym ((encode-table fchar-table fchar-fb-table)
+ token)
+ (and esc-char (eq (char-before) esc-char)
+ (x-symbol-even-escapes-before-p (1- (point)) esc-char)
+ (insert ?\ ))
+ (if (not (and contexts (setq shape (cdr token))))
+ (progn
+ (insert (car token))
+ (delete-char x-symbol-encode-rchars))
+ (and (setq bad-regexp (assq shape before-context))
+ (not (memq (char-before) '(?\ ?\t ?\n ?\r nil)))
+ (string-match (cdr bad-regexp) (char-to-string (char-before)))
+ (insert ?\ ))
+ (insert (car token))
+ (delete-char x-symbol-encode-rchars)
+ (and (setq bad-regexp (assq shape after-context))
+ (not (memq (char-after) '(?\ ?\t ?\n ?\r nil)))
+ (looking-at (cdr bad-regexp))
+ (insert-before-markers " "))))))
+
+
+;;;===========================================================================
+;;; Interactive conversion
+;;;===========================================================================
+
+;;;###autoload
+(defun x-symbol-decode-recode (&optional beg end interactive-flag)
+ "Decode all tokens in active region or buffer to characters.
+If called interactively and if the region is active, BEG and END are the
+boundaries of the region. BEG and END default to the buffer boundaries.
+8bit characters are treated according to `x-symbol-coding'. See also
+commands `x-symbol-encode' and `x-symbol-mode'.
+
+Note that in most token languages, different tokens might be decoded to
+the same character, e.g., \\neq and \\ne in `tex', &Auml\; and &#196\;
+in `sgml'!"
+ (interactive (and (region-active-p) (list (region-beginning) (region-end))))
+ (unless x-symbol-language
+ (error "No token language which can be used for decoding"))
+ (or beg (setq beg (point-min)))
+ (or end (setq end (point-max)))
+ (save-excursion
+ (save-restriction
+ (narrow-to-region beg end)
+ (let ((first-change-hook nil) ; no `flyspell-mode' here
+ (after-change-functions nil)) ; no fontification!
+ (x-symbol-decode-all))
+ (if font-lock-mode (x-symbol-fontify (point-min) (point-max)))))
+ (if (or interactive-flag (interactive-p))
+ (message "%sDecoded %s to Character in %s"
+ (x-symbol-coding-text x-symbol-coding x-symbol-default-coding
+ "Recoded %s to %s, ")
+ (x-symbol-language-text)
+ (x-symbol-region-text t))))
+
+;;;###autoload
+(defun x-symbol-decode (&optional beg end)
+ (interactive (and (region-active-p) (list (region-beginning) (region-end))))
+ (if (or (null x-symbol-coding)
+ (eq x-symbol-coding x-symbol-default-coding))
+ (x-symbol-decode-recode beg end t)
+ (let ((x-symbol-coding (or x-symbol-default-coding t)))
+ (x-symbol-decode-recode beg end t))))
+
+;;;###autoload
+(defun x-symbol-encode-recode (&optional beg end interactive-flag)
+ "Encode all characters in active region or buffer to tokens.
+If called interactively and if the region is active, BEG and END are the
+boundaries of the region. BEG and END default to the buffer boundaries.
+Variables `x-symbol-8bits' and `x-symbol-coding' determine whether to
+encode 8bit characters. See also commands `x-symbol-decode' and
+`x-symbol-mode'."
+ (interactive (and (region-active-p) (list (region-beginning) (region-end))))
+ (unless x-symbol-language
+ (error "No token language which can be used for encoding"))
+ (or beg (setq beg (point-min)))
+ (or end (setq end (point-max)))
+ (save-excursion
+ (save-restriction
+ (narrow-to-region beg end)
+ (let ((first-change-hook nil) ; no `flyspell-mode' here
+ (after-change-functions nil)) ; no fontification!
+ (x-symbol-encode-all))
+ (if font-lock-mode (x-symbol-fontify (point-min) (point-max)))))
+ (if (or interactive-flag (interactive-p))
+ (message "Encoded Non-%s to %s in %s%s"
+ (x-symbol-coding-text x-symbol-coding)
+ (x-symbol-language-text)
+ (x-symbol-region-text t)
+ (x-symbol-coding-text x-symbol-coding x-symbol-default-coding
+ ", Recoded %s to %s"))))
+
+;;;###autoload
+(defun x-symbol-encode (&optional beg end)
+;; "Encode all characters in active region or buffer to tokens.
+;;If called interactively and if the region is active, BEG and END are the
+;;boundaries of the region. BEG and END default to the buffer boundaries.
+;;Always encode all 8bit characters, as opposed to \\[x-symbol-encode],
+;;i.e., `x-symbol-8bits' is assumed to be nil here."
+ (interactive (and (region-active-p) (list (region-beginning) (region-end))))
+ (if (or (null x-symbol-coding)
+ (eq x-symbol-coding x-symbol-default-coding))
+ (x-symbol-encode-recode beg end t)
+ (let ((x-symbol-coding (or x-symbol-default-coding t))
+ (x-symbol-8bits nil))
+ (x-symbol-encode-recode beg end t))))
+
+;;;###autoload
+(defun x-symbol-unalias (&optional beg end coding)
+ ;; TODO: use char-tables, noe
+ ;; checkdoc-params: (beg end)
+ "Resolve all character aliases in active region or buffer.
+A char alias is a character which is also a character in a font with
+another registry, e.g., `adiaeresis' is defined in all supported latin
+fonts. XEmacs distinguish between these four characters. In package
+x-symbol, one of them, with `x-symbol-default-coding' if possible, is
+supported by the input methods, the other ones are char aliases to the
+supported one. The character and all the aliases are represented by the
+same charsym. The info in the minibuffer displays char aliases, you can
+resolve a single character before point with \\[x-symbol-modify-key].
+
+8bit characters in files with a file coding `x-symbol-coding' other than
+`x-symbol-default-coding' are converted to the \"normal\" form. E.g.,
+if you have a latin-1 font by default, the `adiaeresis' in a latin-2
+encoded file is a latin-1 `adiaeresis' in the buffer. When saving the
+buffer, its is again the right 8bit character in the latin-2 encoded
+file. But note: CHAR ALIASES ARE NOT ENCODED WHEN SAVING THE FILE.
+Invoke this command before, if your buffers have char aliases! Seven
+positions in latin-3 fonts are not used, the corresponding 8bit bytes in
+latin-3 encoded files are not changed.
+
+In normal cases, buffers do not have char aliases: in XEmacs/Mule, this
+is only possible if you copy characters from buffers with characters
+considered as char aliases by package x-symbol, e.g., from the Mule file
+\"european.el\". In XEmacs/no-Mule, this is only possible if you use
+commands like `\\[universal-argument] 2 3 4'.
+
+The reason why package x-symbol does not support all versions of
+`adiaeresis'es:
+ * It is confusing to the user to choose among four similar characters.
+ * These four versions are not distinguished in Unicode.
+ * There are not different tokens for them, neither in the token
+ language \"TeX macro\", nor \"SGML entity\"."
+ (interactive (and (region-active-p) (list (region-beginning) (region-end))))
+ (or beg (setq beg (point-min)))
+ (or end (setq end (point-max)))
+ (and coding (featurep 'mule)
+ (setq coding (cdr (assq coding
+ '((iso-8859-1 . latin-iso8859-1)
+ (iso-8859-2 . latin-iso8859-2)
+ (iso-8859-3 . latin-iso8859-3)
+ (iso-8859-9 . latin-iso8859-9)
+ (iso-8859-15 . latin-iso8859-15))))))
+ (let ((alist x-symbol-unalias-alist)
+ (case-fold-search nil)
+ (count 0)
+ from to)
+ (save-excursion
+ (save-restriction
+ (narrow-to-region beg end)
+ (while alist
+ (setq from (caar alist)
+ to (cdar alist)
+ alist (cdr alist))
+ ;; with CODING: unalias just for chars with that coding
+ (when (or (null coding)
+ (eq (char-charset (aref from 0)) coding))
+ (goto-char (point-min))
+ (while (search-forward from nil 'limit)
+ (setq count (1+ count))
+ (replace-match to t t))))))
+ (if (interactive-p)
+ (message "Normalized %d Character Aliases in %s"
+ count (x-symbol-region-text t)))))
+
+(defun x-symbol-copy-region-encoded (start end)
+ ;; WARNING: args might change (for prefix arg: kill, append/prepend). No,
+ ;; this command does not append after a kill as `copy-region-as-kill' does.
+ ;; I think it's quite strange to append after a kill, but not after another
+ ;; copy...
+ (interactive "r")
+ (if x-symbol-language ; yes, not `x-symbol-mode'
+ (kill-new
+ (save-excursion
+ (let* ((x-symbol-8bits
+ ;; do not use 8bit chars if not default coding
+ (and (or (null x-symbol-coding)
+ (eq x-symbol-coding x-symbol-default-coding))
+ (eq (x-symbol-buffer-coding) x-symbol-default-coding)
+ x-symbol-8bits))
+ ;; if 8bit chars remain, do not recode, 8bit chars in the
+ ;; `kill-ring' always have default coding
+ (x-symbol-coding (or x-symbol-default-coding t))
+ (write-region-annotations-so-far nil)) ; safety
+ (x-symbol-encode-all (get-buffer-create " x-symbol conversion")
+ start end)
+ (prog1 (buffer-substring (point-min) (point-max))
+ (kill-buffer (current-buffer))))))
+ (copy-region-as-kill start end)))
+
+(defun x-symbol-yank-decoded (&optional arg)
+ ;; Can also be inserted+decoded directly. But it would be much longer when
+ ;; doing it right (`buffer-undo-list', disable font-lock, etc).
+ (interactive "*P")
+ (if x-symbol-mode ; yes, not `x-symbol-language'
+ (let* ((orig-buffer (current-buffer))
+ (string
+ (save-excursion
+ (set-buffer (get-buffer-create " x-symbol conversion"))
+ (x-symbol-inherit-from-buffer orig-buffer)
+ ;; 8bit chars in the `kill-ring' always have default coding
+ (setq x-symbol-coding (or x-symbol-default-coding t))
+ (yank arg)
+ (x-symbol-decode-all)
+ (prog1 (buffer-substring (point-min) (point-max))
+ (kill-buffer (current-buffer))))))
+ (insert string))
+ (yank arg)))
+
+
+;;;===========================================================================
+;;; Modeline
+;;;===========================================================================
+
+(defun x-symbol-update-modeline ()
+ "Update modeline according to `x-symbol-modeline-state-list'."
+ (let ((alist x-symbol-modeline-state-list)
+ strings string sep)
+ (while alist
+ (cond ((stringp (car alist))
+ (or sep (setq sep (car alist))))
+ ((setq string (if (functionp (cdar alist))
+ (funcall (cdar alist) (caar alist))
+ (if (symbol-value (caar alist))
+ (cadar alist)
+ (cddar alist))))
+ (when sep (push sep strings) (setq sep nil))
+ (push string strings)))
+ (setq alist (cdr alist)))
+ (setq x-symbol-modeline-string
+ (apply 'concat (nreverse strings))))
+ (force-mode-line-update))
+
+
+;;;===========================================================================
+;;; Minor mode control
+;;;===========================================================================
+
+;;;###autoload
+(defun x-symbol-auto-coding-alist (alist &optional limit no-match)
+ "Return first match for ALIST in buffer limited by LIMIT.
+Each element in ALIST looks like
+ (REGEXP . RESULT) or (REGEXP MATCH (KEY . RESULT)...)
+
+Search forward from the start of the buffer for a match with REGEXP.
+With the first form, return RESULT. With the second form, return RESULT
+where KEY is equal to the MATCH'th regexp group of the match."
+ (or limit (setq limit x-symbol-auto-coding-search-limit))
+ (if (eq limit 'point-max) (setq limit nil))
+ (let ((lim (if limit
+ (if (eq limit 'point-max) nil limit)
+ x-symbol-auto-coding-search-limit))
+ (alist-copy alist)
+ regexp value result)
+ (save-excursion
+ (save-restriction
+ (widen)
+ (while alist
+ (setq regexp (caar alist)
+ value (cdar alist))
+ (goto-char (point-min))
+ (if (re-search-forward regexp lim t)
+ (setq alist nil
+ no-match nil
+ result (if (consp value)
+ (cdr (assoc (match-string (car value))
+ (cdr value)))
+ value))
+ (setq alist (cdr alist))))
+ (if no-match
+ (funcall no-match alist-copy limit)
+ result)))))
+
+;; TODO: quick hack
+;;;###autoload
+(defun x-symbol-auto-8bit-search (&optional limit)
+ (or limit (setq limit x-symbol-auto-8bit-search-limit))
+ (if (eq limit 'point-max) (setq limit nil))
+ (let ((cs (if (featurep 'mule)
+ (cdr (assq (x-symbol-buffer-coding)
+ '((iso-8859-1 . latin-iso8859-1)
+ (iso-8859-2 . latin-iso8859-2)
+ (iso-8859-3 . latin-iso8859-3)
+ (iso-8859-9 . latin-iso8859-9)
+ (iso-8859-15 . latin-iso8859-15))))
+ 'latin-iso8859-1)))
+ (when cs
+ (save-excursion
+ (save-restriction
+ (widen)
+ (and limit (< limit (point-max))
+ (narrow-to-region (point-min) limit))
+ (goto-char (point-min))
+ (if (eq cs 'latin-iso8859-1)
+ (progn (skip-chars-forward "^\200-\377" limit)
+ (and (< (point) (point-max)) 'buffer))
+ (when cs
+ (block nil
+ (while (not (eobp))
+ (if (eq (char-charset (char-after)) cs) (return 'buffer))
+ (forward-char))))))))))
+
+(defvar x-symbol-font-family-postfixes
+ (if x-symbol-font-lock-with-extra-props '("" "" "") '("" "_sub" "_sup")))
+
+(defvar x-symbol-font-lock-property-alist
+ '((x-symbol-sub-face face x-symbol-sub-face display (raise -0.33))
+ (x-symbol-sup-face face x-symbol-sub-face display (raise 0.5))))
+
+(defvar x-symbol-font-lock-keywords
+ `((x-symbol-font-lock-start)
+ ,(if x-symbol-font-lock-with-extra-props
+ (if (eq x-symbol-font-lock-with-extra-props 'invisible)
+ '(x-symbol-match-subscript
+ (1 '(face x-symbol-revealed-face invisible t) prepend)
+ (2 (or (cdr (assq x-symbol-subscript-type
+ x-symbol-font-lock-property-alist))
+ x-symbol-subscript-type)
+ prepend)
+ (3 '(face x-symbol-revealed-face invisible t) prepend t))
+ '(x-symbol-match-subscript
+ (1 x-symbol-invisible-face t)
+ (2 (or (cdr (assq x-symbol-subscript-type
+ x-symbol-font-lock-property-alist))
+ x-symbol-subscript-type)
+ prepend)
+ (3 x-symbol-invisible-face t t)))
+ '(x-symbol-match-subscript
+ (1 x-symbol-invisible-face t)
+ (2 (progn x-symbol-subscript-type) prepend)
+ (3 x-symbol-invisible-face t t)))
+ ,@(unless (featurep 'mule)
+ '((x-symbol-nomule-match-cstring
+ (0 (progn x-symbol-nomule-font-lock-face) prepend)))))
+ "TODO")
+
+(defvar x-symbol-subscript-matcher nil
+ "Internal")
+
+(defvar x-symbol-subscript-type nil
+ "Internal")
+
+(defun x-symbol-subscripts-available-p ()
+ "Non-nil, if KEYWORDS are a part of `font-lock-keywords'."
+ (x-symbol-font-lock-start nil)
+ (and x-symbol-subscript-matcher
+ (assq 'x-symbol-match-subscript x-symbol-font-lock-keywords)))
+
+(defun x-symbol-font-lock-start (limit)
+ (setq x-symbol-subscript-matcher
+ (and x-symbol-mode x-symbol-subscripts
+ (find-face 'x-symbol-sub-face) ; TODO: not if in Emacs-21.4
+ (find-face 'x-symbol-sup-face) ; ditto
+ (x-symbol-language-value 'x-symbol-subscript-matcher)))
+ (if (eq x-symbol-subscript-matcher 'ignore)
+ (setq x-symbol-subscript-matcher nil)))
+
+(defun x-symbol-match-subscript (limit)
+ (if x-symbol-subscript-matcher
+ (setq x-symbol-subscript-type
+ (funcall x-symbol-subscript-matcher limit))))
+
+(defun x-symbol-init-font-lock ()
+ "Initialize all font-lock keywords for current `major-mode'.
+The additional x-symbol keywords are determined by the language access
+`x-symbol-font-lock-keywords' for `major-mode's symbol property
+`x-symbol-font-lock-language' and the XEmacs/no-Mule cstring
+fontification, if necessary. The font-lock keywords variables are those
+mentioned in `font-lock-defaults' or in the symbol property
+`font-lock-defaults' of `major-mode'."
+ (if (assq 'x-symbol-match-subscript x-symbol-font-lock-keywords)
+ (let ((symbols (car (or font-lock-defaults
+ (if (fboundp 'font-lock-find-font-lock-defaults)
+ (font-lock-find-font-lock-defaults
+ major-mode))))))
+ (dolist (symbol (if (listp symbols) symbols (list symbols)))
+ (or (assq 'x-symbol-match-subscript (symbol-value symbol))
+ (set symbol (append (symbol-value symbol)
+ x-symbol-font-lock-keywords))))
+ (or (null font-lock-keywords)
+ (assq 'x-symbol-match-subscript font-lock-keywords)
+ (setq font-lock-keywords (append font-lock-keywords
+ x-symbol-font-lock-keywords)))
+ (when x-symbol-font-lock-with-extra-props
+ (make-local-variable 'font-lock-extra-managed-props)
+ ;; see `x-symbol-font-lock-keywords':
+ (if (eq x-symbol-font-lock-with-extra-props 'invisible)
+ (pushnew 'invisible font-lock-extra-managed-props))
+ (pushnew 'display font-lock-extra-managed-props)))
+ (when x-symbol-font-lock-keywords
+ (lwarn 'x-symbol 'error
+ "Additional font-lock keywords are invalid, set to nil")
+ (setq x-symbol-font-lock-keywords nil))))
+
+(defun x-symbol-set-image (dummy value)
+ ;; checkdoc-params: (dummy)
+ "Set function for buffer local variable `x-symbol-image'.
+If VALUE is non-nil, call `x-symbol-image-parse-buffer', otherwise
+delete existing x-symbol image extents in buffer."
+ (if (and (setq x-symbol-image (and value (x-symbol-image-available-p)))
+ x-symbol-mode)
+ (progn
+ (make-local-hook 'after-change-functions)
+ (x-symbol-image-parse-buffer)
+ (add-hook 'after-change-functions
+ 'x-symbol-image-after-change-function nil t))
+ (if (local-variable-p 'x-symbol-image-buffer-extents (current-buffer))
+ (x-symbol-image-delete-extents 1 (1+ (buffer-size))))
+ (remove-hook 'after-change-functions 'x-symbol-image-after-change-function
+ t)))
+
+;;;###autoload
+(defun x-symbol-mode-internal (conversion)
+ "Setup X-Symbol mode according to buffer-local variables.
+If CONVERSION is non-nil, do conversion with EXEC-THRESHOLD. See
+command `x-symbol-mode' for details."
+ (unless (featurep 'xemacs)
+ (unless enable-multibyte-characters
+ ;; Emacs: we need to convert the buffer from unibyte to multibyte
+ ;; since we'll use multibyte support for the symbol charset.
+ ;; TODO: try to do it less often
+ (let ((modified (buffer-modified-p))
+ (inhibit-read-only t)
+ (inhibit-modification-hooks t))
+ (unwind-protect
+ (progn
+ (decode-coding-region (point-min) (point-max) 'undecided)
+ (set-buffer-multibyte t))
+ (set-buffer-modified-p modified)))))
+ (if conversion
+ (let ((modified (buffer-modified-p))
+ (buffer-read-only nil) ; always allow conversion
+ (buffer-file-name nil) ; no file-locking, TODO: dangerous?
+ (inhibit-read-only t)
+ (first-change-hook nil) ; no `flyspell-mode' here
+ (after-change-functions nil) ; no fontification!
+ (no-undo (null buffer-undo-list)))
+ (if no-undo (setq buffer-undo-list t))
+ (save-excursion
+ (save-restriction
+ (if x-symbol-mode
+ (let ((buffer-coding (x-symbol-buffer-coding)))
+ ;; cannot do this in `x-symbol-mode': `x-symbol-fchar-tables' might not be defined
+ (if buffer-coding
+ (or (null x-symbol-coding) ; no coding specified
+ (eq x-symbol-coding buffer-coding) ; specified = buffer-file-coding
+ (and (eq buffer-coding x-symbol-default-coding)
+ ; valid coding and buffer-fc = default
+ (assq x-symbol-coding x-symbol-fchar-tables))
+ (setq x-symbol-8bits
+ (x-symbol-auto-8bit-search 'point-max)))
+ (setq x-symbol-8bits nil))
+ (x-symbol-decode-all))
+ (x-symbol-encode-all))
+ (if font-lock-mode (x-symbol-fontify (point-min) (point-max)))))
+ (if no-undo (setq buffer-undo-list nil))
+ (or modified (set-buffer-modified-p nil))))
+ (x-symbol-set-image nil x-symbol-image)
+ (if x-symbol-mode
+ (progn
+ ;; set font-lock keywords
+ (x-symbol-init-font-lock)
+ (make-local-hook 'pre-command-hook)
+ (make-local-hook 'post-command-hook)
+ (add-hook 'pre-command-hook 'x-symbol-pre-command-hook nil t)
+ (add-hook 'post-command-hook 'x-symbol-post-command-hook nil t)
+ (if (assq 'x-symbol format-alist)
+ (pushnew 'x-symbol buffer-file-format))
+ (easy-menu-add x-symbol-menu)
+ (x-symbol-update-modeline))
+ (remove-hook 'pre-command-hook 'x-symbol-pre-command-hook t)
+ (remove-hook 'post-command-hook 'x-symbol-post-command-hook t)
+ (setq buffer-file-format (delq 'x-symbol buffer-file-format))
+ (if (local-variable-p 'current-menubar (current-buffer))
+ ;; XEmacs bug workaround
+ (ignore-errors (easy-menu-remove x-symbol-menu)))))
+
+(defun nuke-x-symbol ()
+ "Turn off X-Symbol mode and make sure that tokens are encoded.
+Used in `change-major-mode-hook'."
+ (when x-symbol-mode
+ (setq x-symbol-mode nil)
+ (x-symbol-mode-internal x-symbol-language)))
+(add-hook 'change-major-mode-hook 'nuke-x-symbol)
+
+
+;;;===========================================================================
+;;; Menu filters
+;;;===========================================================================
+
+(defun x-symbol-options-filter (menu-items)
+ (let (item menu var options)
+ (while (setq item (pop menu-items))
+ (push (if (not (and (vectorp item)
+ (= (length item) 3)
+ (setq var (aref item 1))
+ (symbolp var)
+ (setq options (get var 'x-symbol-options))))
+ item
+ (let ((header (aref item 0))
+ (active (and (eval (aref item 2)) t))
+ (value (symbol-value var))
+ fallback submenu option)
+ (if (functionp options) (setq options (funcall options)))
+ (setq fallback (pop options))
+ ;; VARIABLE with VALUE, allowed OPTIONS with FALLBACK
+ (if (null options)
+ (vector header
+ `(x-symbol-set-variable
+ (quote ,var) ,(if value nil `(quote ,fallback)))
+ :active active
+ :style 'toggle
+ :selected (and value t))
+ (or (assq value options) (setq value fallback))
+ (while (setq option (pop options))
+ (push (vector (cdr option)
+ `(x-symbol-set-variable
+ (quote ,var) (quote ,(car option)))
+ :active active
+ :style 'radio
+ :selected (eq (car option) value))
+ submenu))
+ (cons header (nreverse submenu)))))
+ menu))
+ (nreverse menu)))
+
+(defun x-symbol-extra-filter (menu-items)
+ (let ((extra (assoc (aref (car menu-items) 0)
+ (x-symbol-language-value 'x-symbol-extra-menu-items))))
+ (if extra
+ (append (cdr menu-items) (cdr extra))
+ (cdr menu-items))))
+
+(defun x-symbol-menu-filter (menu-items)
+ "Menu filter `x-symbol-menu'.
+Append the global or token-language specific menu to MENU-ITEMS."
+ (nconc (mapcar (lambda (item)
+ (if (and (consp item)
+ (eq (caddr item) 'x-symbol-extra-filter)
+ (aref (cadddr item) 2))
+ (cons (format (car item)
+ (funcall (aref (cadddr item) 2)))
+ (cdr item))
+ item))
+ menu-items)
+ (or (and x-symbol-local-menu
+ x-symbol-language
+ (x-symbol-generated-menu-alist
+ (x-symbol-language-value 'x-symbol-generated-data)))
+ x-symbol-menu-alist)))
+
+
+
+;;;;##########################################################################
+;;;; Info, List-Mode
+;;;;##########################################################################
+
+
+(put 'x-symbol-list-mode 'mode-class 'special) ; where is it used?
+
+(defvar x-symbol-list-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map " " 'x-symbol-list-selected)
+ (define-key map "\C-m" 'x-symbol-list-selected)
+ (define-key map "q" 'x-symbol-list-bury)
+ (define-key map "?" 'x-symbol-list-info)
+ (define-key map "i" 'x-symbol-list-info)
+ (define-key map "h" 'x-symbol-list-info)
+ ;; TODO: either XEmacs or Emacs bindings
+ ;; Bindings for XEmacs.
+ (when (lookup-key global-map [(button2)])
+ (define-key map 'button2 'x-symbol-list-mouse-selected)
+ (define-key map 'button2up 'undefined)
+ (define-key map 'button3 'x-symbol-list-menu-selected)
+ (define-key map 'button3up 'undefined))
+ ;; Same bindings but for Emacs.
+ (when (lookup-key global-map [(mouse-2)])
+ (define-key map [mouse-2] 'x-symbol-list-mouse-selected)
+ (define-key map [up-mouse-2] 'undefined)
+ (define-key map [down-mouse-3] 'x-symbol-list-menu-selected)
+ (define-key map [mouse-3] 'undefined)
+ (define-key map [up-mouse-3] 'undefined))
+ (set-keymap-parent map list-mode-map)
+ map)
+ "Mode map used in grid buffers and the key completion buffer.")
+
+(defvar x-symbol-list-buffer nil
+ "Internal. Recently used list buffer.")
+(defvar x-symbol-list-win-config nil
+ "Internal buffer-local in list buffer. Win-config before invocation.")
+(defvar x-symbol-invisible-spec nil
+ "Internal. Used by `x-symbol-hide-revealed-at-point'.
+Looks like (BUFFER START END . FACE-OR-FACES) or nil.")
+
+(defvar x-symbol-itimer nil
+ "Internal. Used by `x-symbol-start-itimer-once'.")
+
+(defvar x-symbol-invisible-display-table
+ (let ((table (make-display-table))
+ (i 0))
+ (while (< i 256)
+ (aset table i "")
+ (setq i (1+ i)))
+ table)
+ "Internal variable. Display table for `x-symbol-invisible-face'.")
+
+(defvar x-symbol-invisible-font "-XSYMB-nil-*"
+ ;; Note that the `nil' font uses a `fontspecific' encoding, so we need to go
+ ;; through a fontset to convince Emacs to use this font when displaying ASCII
+ ;; chars.
+ "Internal variable. Font to use for `x-symbol-invisible-face'.
+It is not used if faces can have a property \"display table\", i.e., if
+ `x-symbol-invisible-display-table' has a non-nil value.")
+
+(make-face 'x-symbol-invisible-face
+ "*Face for displaying invisible things like \"_\" and \"^\" in TeX.")
+(unless noninteractive ; CW: see noninteractive below
+ (cond (x-symbol-invisible-display-table
+ (set-face-display-table 'x-symbol-invisible-face
+ x-symbol-invisible-display-table))
+ ((and (fboundp 'create-fontset-from-ascii-font)
+ x-symbol-invisible-font
+ (try-font-name x-symbol-invisible-font))
+ ;; This is a mean and ugly hack. Since Emacs seems unable to create a
+ ;; face that makes text invisible, we simulate it by using a minuscule
+ ;; pseudo-font.
+ (set-face-font 'x-symbol-invisible-face
+ (create-fontset-from-ascii-font
+ x-symbol-invisible-font)))))
+
+(defvar x-symbol-charsym-info-cache nil
+ "Internal. Cache for `x-symbol-charsym-info'.")
+(defvar x-symbol-language-info-caches nil
+ "Internal. Cache for `x-symbol-language-info'.")
+(defvar x-symbol-coding-info-cache nil
+ "Internal. Cache for `x-symbol-coding-info'.")
+(defvar x-symbol-keys-info-cache nil
+ "Internal. Cache for `x-symbol-keys-info'.")
+
+
+;;;===========================================================================
+;;; X-Symbol List Mode (for GRID and KEYBOARD completion)
+;;;===========================================================================
+
+(defun x-symbol-list-bury ()
+ "Bury current buffer while trying to use the old window configuration."
+ (interactive)
+ (setq x-symbol-list-buffer (current-buffer))
+ (x-symbol-list-restore t))
+
+(defun x-symbol-list-restore (&optional bury)
+ "Restore window configuration used before invoking the list buffer.
+If optional argument BURY is non-nil, bury current buffer if
+configuration cannot be restored. See `x-symbol-temp-grid' and
+`x-symbol-temp-help'. Used by `x-symbol-insert-command'."
+ (and x-symbol-list-buffer
+ (get-buffer-window x-symbol-list-buffer)
+ (let ((orig (current-buffer))
+ reference win-config)
+ (set-buffer x-symbol-list-buffer)
+ (setq reference completion-reference-buffer)
+ ;; CW: a first try:
+ (or (and (buffer-live-p reference)
+ (get-buffer-window reference t)
+ (cond ((null x-symbol-use-refbuffer-once))
+ ((functionp x-symbol-use-refbuffer-once)
+ (not (funcall x-symbol-use-refbuffer-once
+ reference)))))
+ (setq completion-reference-buffer nil))
+ (setq win-config x-symbol-list-win-config
+ x-symbol-list-win-config nil)
+ (if (or (eq orig reference)
+ (and (eq orig x-symbol-list-buffer) (buffer-live-p reference)))
+ (if (window-configuration-p win-config)
+ (set-window-configuration win-config)
+ (pop-to-buffer reference))
+ (set-buffer orig)
+ (if bury (bury-buffer)))))
+ (setq x-symbol-list-buffer nil))
+
+(defun x-symbol-list-store (reference win-config)
+ "Store window configuration WIN-CONFIG and reference buffer REFERENCE.
+Used by `x-symbol-list-restore'."
+ (setq x-symbol-list-buffer (and reference (current-buffer)))
+ (make-local-variable 'completion-reference-buffer)
+ (setq completion-reference-buffer reference)
+ (make-local-variable 'x-symbol-list-win-config)
+ (setq x-symbol-list-win-config win-config))
+
+(defun x-symbol-list-mode (&optional language reference win-config)
+ "Major mode for buffers containing x-symbol items.
+Invoked for token language LANGUAGE form buffer REFERENCE. WIN-CONFIG
+is the window configuration before invoking the grid or key completion
+buffer, used by `x-symbol-list-restore'. Runs hook
+`x-symbol-list-mode-hook'.
+
+\\{x-symbol-list-mode-map}"
+ (list-mode)
+ (setq major-mode 'x-symbol-list-mode)
+ (use-local-map x-symbol-list-mode-map)
+ (setq mode-name "XS-List")
+ (setq x-symbol-language language)
+ (x-symbol-list-store reference win-config)
+ (run-hooks 'x-symbol-list-mode-hook))
+
+
+;;;===========================================================================
+;;; List Mode Selection
+;;;===========================================================================
+
+(defun x-symbol-list-scroll (pos buffer)
+ "Scrolls BUFFER up/down according to POS.
+In POS is in the upper half of the window, scroll down, otherwise,
+scroll up."
+ (let ((window (get-buffer-window buffer 'visible)))
+ (if window
+ (progn
+ (select-window window)
+ (set-buffer buffer))
+ (pop-to-buffer buffer)))
+ (let ((old-pos (point)))
+ (move-to-window-line nil)
+ (if (> (point) pos)
+ (scroll-down)
+ (scroll-up)
+ (when (pos-visible-in-window-p (point-max))
+ (goto-char (point-max))
+ (recenter -1)))
+ (if (pos-visible-in-window-p old-pos)
+ (goto-char old-pos)
+ (move-to-window-line nil))))
+
+;;;###autoload
+(defun x-symbol-init-language-interactive (language)
+ "Initialize token language LANGUAGE.
+See `x-symbol-init-language'."
+ (interactive (list (x-symbol-read-language
+ "Initialize Token Language: " nil
+ (lambda (elem)
+ (and (cdr elem)
+ (null (get (cdr elem) 'x-symbol-initialized)))))))
+ (if language
+ (if (get language 'x-symbol-initialized)
+ (message "Token language %S is already initialized"
+ (x-symbol-language-value 'x-symbol-name language))
+ (if (x-symbol-init-language language)
+ (message "Token language %S has been initialized"
+ (x-symbol-language-value 'x-symbol-name language))
+ (error "Failed to initialize token language `%s'" language)))))
+
+(defun x-symbol-list-menu (reference charsym)
+ "Popup menu for the insertion of the character under mouse.
+Insert character or one of its tokens, represented by CHARSYM into
+buffer REFERENCE, see `x-symbol-insert-command'."
+ (let ((keys (where-is-internal (get charsym 'x-symbol-insert-command)
+ nil t))
+ (alist (cons (cons nil x-symbol-charsym-name)
+ x-symbol-language-alist))
+ menu menu1
+ language token)
+ (while alist
+ (if (or (null (car (setq language (pop alist))))
+ (get (car language) 'x-symbol-initialized))
+ (if (setq token (if (car language)
+ (car (gethash charsym
+ (x-symbol-generated-encode-table
+ (x-symbol-language-value
+ 'x-symbol-generated-data
+ (car language)))))
+ (symbol-name charsym)))
+ (push (vector token
+ `(x-symbol-insert-command -1 (quote ,charsym)
+ ,token)
+ :keys (format (if (eq (car language)
+ x-symbol-language)
+ "(%s)*"
+ "(%s)")
+ (cdr language)))
+ menu))
+ (push (vector "Initialize..." `(x-symbol-init-language-interactive
+ (quote ,(car language)))
+ :keys (cdr language))
+ menu1)))
+ (popup-menu
+ (list* (if (symbol-value-in-buffer 'buffer-read-only reference)
+ "Store in kill-ring as:"
+ (if (eq (current-buffer) reference)
+ "Insert as:"
+ (format "Insert in \"%s\" as:" (buffer-name reference))))
+ (vector
+ "Character"
+ `(x-symbol-insert-command -1 (quote ,charsym) nil)
+ :active (gethash charsym x-symbol-cstring-table)
+ :keys (if keys
+ (if (funcall x-symbol-valid-charsym-function charsym)
+ (key-description keys)
+ (concat (key-description
+ (where-is-internal 'negative-argument nil t))
+ " "
+ (key-description keys)))))
+ "---"
+ (nconc (nreverse menu)
+ (and menu1 (cons "--:shadowDoubleEtchedIn"
+ (nreverse menu1))))))))
+
+(defun x-symbol-list-selected (&optional arg pos buffer)
+ "Handle selection of a x-symbol list item at POS in BUFFER.
+When called interactively, insert character with prefix argument ARG for
+list item at point, see `x-symbol-insert-command'. Also called by
+`x-symbol-list-menu-selected' and `x-symbol-list-mouse-selected'."
+ (interactive "P")
+ (or pos (setq pos (point)))
+ ;; SM: we rely too much on list-mode's implementation (and properties). CW:
+ ;; I don't think so, at least these are XEmacs' documented properties...
+ (let* ((extent (extent-at pos buffer 'list-mode-item)))
+ (if extent
+ (let ((charsym (extent-property extent 'list-mode-item-user-data))
+ (reference (or completion-reference-buffer (current-buffer))))
+ ;; current list buffer must be equal
+ (setq x-symbol-list-buffer (or buffer (current-buffer)))
+ (if (and buffer (consp arg))
+ (x-symbol-list-menu reference charsym)
+ (x-symbol-insert-command arg charsym)))
+ (or buffer (error "Not over an x-symbol selection"))
+ (if (consp arg)
+ (popup-menu x-symbol-menu)
+ (let ((selected (selected-window)))
+ (unwind-protect
+ (x-symbol-list-scroll pos buffer)
+ (select-window selected)))))))
+
+(defun x-symbol-list-menu-selected (event)
+ ;; checkdoc-params: (event)
+ "Popup menu for x-symbol list item under mouse.
+If mouse is over a list item, popup menu for the insertion of the
+corresponding character or one of its tokens, see
+`x-symbol-insert-command'. Otherwise, popup the X-Symbol menu."
+ (interactive "e")
+ ;;(run-hooks 'mouse-leave-buffer-hook)
+ (x-symbol-list-selected '(4) (event-closest-point event)
+ (event-buffer event)))
+
+(defun x-symbol-list-mouse-selected (arg event)
+ ;; checkdoc-params: (arg event)
+ "Select x-symbol list item under mouse.
+If mouse is over a list item, insert the corresponding character, see
+`x-symbol-insert-command'. Otherwise, scroll the list buffer down, if
+mouse is in the upper half of the window, scroll up, otherwise."
+ (interactive "P\ne")
+ ;;(run-hooks 'mouse-leave-buffer-hook)
+ (x-symbol-list-selected arg (event-closest-point event)
+ (event-buffer event)))
+(put 'x-symbol-list-mouse-selected 'isearch-command t)
+
+
+;;;===========================================================================
+;;; Character Info Parts
+;;;===========================================================================
+
+(defun x-symbol-charsym-info (charsym)
+ "Return info for CHARSYM describing the charsym."
+ (x-symbol-ensure-hashtable 'x-symbol-charsym-info-cache)
+ (or (gethash charsym x-symbol-charsym-info-cache)
+ (x-symbol-puthash
+ charsym
+ (concat (x-symbol-fancy-string
+ (cons (format (car x-symbol-info-token-charsym) charsym)
+ (cdr x-symbol-info-token-charsym)))
+ (x-symbol-fancy-value 'x-symbol-info-classes-pre)
+ (x-symbol-fancy-value 'x-symbol-info-classes-charsym)
+ (x-symbol-fancy-value 'x-symbol-info-classes-post))
+ x-symbol-charsym-info-cache)))
+
+(defun x-symbol-language-info (charsym language)
+ "Return info for CHARSYM describing the token and classes in LANGUAGE."
+ (let ((cache (plist-get x-symbol-language-info-caches language)))
+ (unless cache
+ (x-symbol-ensure-hashtable 'cache)
+ (setq x-symbol-language-info-caches
+ (plist-put x-symbol-language-info-caches language cache)))
+ (or (gethash charsym cache)
+ (let* ((data (x-symbol-language-value
+ 'x-symbol-generated-data language))
+ (token (gethash charsym
+ (x-symbol-generated-encode-table data))))
+ (x-symbol-puthash
+ charsym
+ (concat (if token
+ (x-symbol-fancy-string
+ (cons (car token)
+ (cdr (x-symbol-charsym-face charsym language))))
+ (x-symbol-fancy-string
+ (cons (format (car x-symbol-info-token-charsym) charsym)
+ (cdr x-symbol-info-token-charsym))))
+ (x-symbol-fancy-associations
+ (gethash charsym
+ (x-symbol-generated-token-classes data))
+ (x-symbol-language-value 'x-symbol-class-alist language)
+ 'x-symbol-info-classes-pre
+ 'x-symbol-info-classes-sep
+ 'x-symbol-info-classes-post
+ (if token 'VALID 'INVALID)))
+ cache)))))
+
+(defun x-symbol-coding-info (charsym)
+ "Return info for CHARSYM describing possible 8bit codings."
+ (x-symbol-ensure-hashtable 'x-symbol-coding-info-cache)
+ (or (gethash charsym x-symbol-coding-info-cache)
+ (let ((tables x-symbol-info-coding-alist) coding table charsym-codings)
+ (while tables
+ (setq coding (car (pop tables)))
+ (and (setq table (assq coding x-symbol-fchar-tables))
+ (gethash charsym (cdr table))
+ (push coding charsym-codings)))
+ (x-symbol-puthash charsym
+ (or (x-symbol-fancy-associations
+ (nreverse charsym-codings)
+ x-symbol-info-coding-alist
+ 'x-symbol-info-coding-pre
+ 'x-symbol-info-coding-sep
+ 'x-symbol-info-coding-post)
+ "")
+ x-symbol-coding-info-cache))))
+
+(defun x-symbol-keys-info (charsym)
+ "Return info for CHARSYM describing key bindings.
+See `x-symbol-info-keys-keymaps'."
+ (x-symbol-ensure-hashtable 'x-symbol-keys-info-cache)
+ (or (gethash charsym x-symbol-keys-info-cache)
+ ;;(if x-symbol-input-initialized
+ (x-symbol-puthash
+ charsym
+ (concat (x-symbol-fancy-value 'x-symbol-info-keys-pre
+ 'substitute-command-keys)
+ (sorted-key-descriptions
+ (where-is-internal
+ (get charsym 'x-symbol-insert-command)
+ (and (functionp x-symbol-info-keys-keymaps)
+ (funcall x-symbol-info-keys-keymaps charsym)))
+ (x-symbol-fancy-value 'x-symbol-info-keys-sep))
+ (x-symbol-fancy-value 'x-symbol-info-keys-post))
+ x-symbol-keys-info-cache)))
+
+
+;;;===========================================================================
+;;; Character Info
+;;;===========================================================================
+
+(defun x-symbol-info (charsym language long intro)
+ "Return info for CHARSYM in LANGUAGE with introduction INTRO.
+See `x-symbol-character-info'. When LONG is nil, do not show info
+describing key bindings."
+ (concat intro
+ (gethash charsym x-symbol-fontified-cstring-table)
+ (x-symbol-fancy-value 'x-symbol-info-token-pre)
+ (if (get language 'x-symbol-name)
+ (x-symbol-language-info charsym language)
+ (x-symbol-charsym-info charsym))
+ (x-symbol-coding-info charsym)
+ (and long (x-symbol-keys-info charsym))))
+
+(defun x-symbol-list-info ()
+ "Display info for character under point in echo area."
+ (interactive)
+ ;; FIXME: we rely too much on list-mode's implementation (and properties).
+ (let* ((extent (extent-at (point) nil 'list-mode-item))
+ (charsym (and extent
+ (extent-property extent 'list-mode-item-user-data))))
+ (if charsym
+ (display-message 'no-log
+ (x-symbol-info charsym x-symbol-language t
+ (x-symbol-fancy-value 'x-symbol-info-intro-list
+ 'substitute-command-keys)))
+ (error "No charsym selected"))))
+
+(defun x-symbol-highlight-echo (extent &optional window pos)
+ "Return info for character covered by EXTENT."
+ ;; CW: check -- seems to work
+ ;; Emacs-21 provides `window' but as the first argument.
+ (if (windowp extent) (let ((w extent)) (setq extent window window w)))
+ ;; FIXME: we rely too much on list-mode's implementation (and properties).
+ (let ((charsym (extent-property extent 'list-mode-item-user-data)))
+ (if charsym
+ (x-symbol-info charsym x-symbol-language t
+ (x-symbol-fancy-value 'x-symbol-info-intro-highlight)))))
+
+(defun x-symbol-point-info (after before)
+ "Return info for characters around point.
+See `x-symbol-character-info' and `x-symbol-context-info'. AFTER and
+BEFORE represent the characters after and before point. They have the
+same type as the return values of `x-symbol-charsym-after'."
+ (let (charsym context pos)
+ (cond ((and x-symbol-character-info (setq charsym (cdr after)))
+ (if (x-symbol-alias-charsym after)
+ (x-symbol-info
+ charsym x-symbol-language nil
+ (x-symbol-fancy-value 'x-symbol-info-alias-after
+ 'substitute-command-keys))
+ (x-symbol-info
+ charsym x-symbol-language t
+ (x-symbol-fancy-value 'x-symbol-info-intro-after))))
+ ((and (eq x-symbol-character-info t) (setq charsym (cdr before)))
+ (if (x-symbol-alias-charsym before)
+ (x-symbol-info
+ charsym x-symbol-language nil
+ (x-symbol-fancy-value 'x-symbol-info-alias-before
+ 'substitute-command-keys))
+ (x-symbol-info
+ charsym x-symbol-language t
+ (x-symbol-fancy-value 'x-symbol-info-intro-before))))
+ ((and x-symbol-context-info
+ (setq pos (or (car after) (point)))
+ (setq before (x-symbol-match-before x-symbol-context-atree pos))
+ (setq charsym (x-symbol-next-valid-charsym
+ (cdr before) t 'x-symbol-modify-to))
+ (null (x-symbol-call-function-or-regexp
+ x-symbol-context-info-ignore
+ (setq context (buffer-substring (car before) pos))
+ charsym)))
+ (x-symbol-info
+ charsym x-symbol-language t
+ ;; no fancy context (too fancy, would break no-Mule cstrings)
+ (concat (x-symbol-fancy-value 'x-symbol-info-context-pre
+ 'substitute-command-keys)
+ context
+ (x-symbol-fancy-value 'x-symbol-info-context-post)))))))
+
+
+;;;===========================================================================
+;;; Hide & Reveal Invisible
+;;;===========================================================================
+
+(defun x-symbol-hide-revealed-at-point ()
+ "Hide characters at point revealed by `x-symbol-reveal-invisible'.
+Used by `x-symbol-pre-command-hook'. To avoid flickering, commands
+which do not change the buffer contents and just move point by a
+predictable number of characters right or left should have a function
+MOVE as the symbol property `x-symbol-point-function'. MOVE is called
+with argument `point' and should return the position of `point' after
+the execution of the command. E.g., `forward-char' uses `1+'."
+ (when x-symbol-invisible-spec
+ (unless (let (fun pos)
+ (and (symbolp this-command)
+ (functionp (setq fun (get this-command
+ 'x-symbol-point-function)))
+ (setq pos (funcall fun (point)))
+ (<= (cadr x-symbol-invisible-spec) pos)
+ (if (eq x-symbol-reveal-invisible t)
+ (>= (caddr x-symbol-invisible-spec) pos)
+ (> (caddr x-symbol-invisible-spec) pos))))
+ (x-symbol-ignore-property-changes
+ (if (eq x-symbol-font-lock-with-extra-props 'invisible)
+ (progn
+ (put-text-property (cadr x-symbol-invisible-spec)
+ (caddr x-symbol-invisible-spec)
+ 'invisible 'hide)
+ (unless (eq this-command 'eval-expression)
+ (setq x-symbol-trace-invisible
+ (text-properties-at (cadr x-symbol-invisible-spec)))))
+ (funcall (if (consp (cdddr x-symbol-invisible-spec))
+ 'put-text-property
+ 'put-nonduplicable-text-property)
+ (cadr x-symbol-invisible-spec)
+ (caddr x-symbol-invisible-spec)
+ 'face (cdddr x-symbol-invisible-spec)
+ (car x-symbol-invisible-spec)))
+ (setq x-symbol-invisible-spec nil)))))
+
+(defun x-symbol-reveal-invisible (after before)
+ "Reveal invisible characters around point.
+See `x-symbol-reveal-invisible'. AFTER and BEFORE represent the
+characters after and before point. They have the same type as the
+return values of `x-symbol-charsym-after'. The characters are hidden
+with `x-symbol-hide-revealed-at-point'."
+ (let ((faces (and after (get-text-property after 'face)))
+ (iface (if (eq x-symbol-font-lock-with-extra-props 'invisible)
+ 'x-symbol-revealed-face
+ 'x-symbol-invisible-face)))
+ (when (setq x-symbol-invisible-spec
+ (or (if (consp faces)
+ (memq iface faces)
+ (eq faces iface))
+ (and (eq x-symbol-reveal-invisible t)
+ (setq after before)
+ (setq faces (get-text-property after 'face))
+ (if (consp faces)
+ (memq iface faces)
+ (eq faces iface)))))
+ (let ((start (previous-single-property-change (1+ after) 'face nil
+ (point-at-bol)))
+ (end (next-single-property-change after 'face nil
+ (point-at-eol))))
+ (setq x-symbol-invisible-spec
+ (list* (current-buffer) start end faces))
+ (x-symbol-ignore-property-changes
+ (if (eq x-symbol-font-lock-with-extra-props 'invisible)
+ (progn (remove-text-properties start end '(invisible nil))
+ (setq x-symbol-trace-invisible (text-properties-at start)))
+ (put-nonduplicable-text-property
+ start end 'face (if (consp faces)
+ (cons 'x-symbol-revealed-face
+ (delq 'x-symbol-invisible-face
+ (copy-sequence faces)))
+ 'x-symbol-revealed-face))))))))
+
+
+;;;===========================================================================
+;;; Entry Points
+;;;===========================================================================
+
+(defun x-symbol-show-info-and-invisible ()
+ "Reveal invisible characters and show info in echo area.
+See `x-symbol-reveal-invisible', `x-symbol-character-info' and
+`x-symbol-context-info'. Expiry function for itimer started with
+`x-symbol-start-itimer-once'."
+ (when x-symbol-mode
+ (let* ((after (x-symbol-charsym-after))
+ (pos (1- (or (car after) (point))))
+ (before (and (null (eq (char-after pos) ?\n))
+ (x-symbol-charsym-after pos)))
+ info)
+ (and x-symbol-reveal-invisible
+ (null x-symbol-invisible-spec)
+ (x-symbol-reveal-invisible (car after) (car before)))
+ (and (null message-stack) ; no message in echo area
+ (not (eq (selected-window) (minibuffer-window)))
+ ;; Quail:
+ (not (and (local-variable-p 'quail-guidance-buf (current-buffer))
+ (buffer-live-p quail-guidance-buf)
+ (> (buffer-size quail-guidance-buf) 0)))
+;; (not (and (local-variable-p 'current-input-method (current-buffer))
+;; current-input-method
+;; (fboundp 'quail-point-in-conversion-region)
+;; (boundp 'quail-conv-overlay)
+;; (setq cw quail-overlay)
+;; (overlayp quail-overlay) ; ehem, this test should be in that function
+;; (setq cw2 quail-overlay)))
+;; ;;(quail-point-in-conversion-region)))
+ (setq info (x-symbol-point-info after before))
+ (display-message 'no-log info)))))
+
+(defun x-symbol-start-itimer-once ()
+ "Start idle timer for function `x-symbol-show-info-and-invisible'.
+Used in `x-symbol-post-command-hook.'"
+ (if (and (numberp x-symbol-idle-delay) (> x-symbol-idle-delay 0))
+ (unless (itimer-live-p x-symbol-itimer)
+ (setq x-symbol-itimer
+ (start-itimer "X-Symbol Idle Timer"
+ 'x-symbol-show-info-and-invisible
+ x-symbol-idle-delay nil t)))
+ (x-symbol-show-info-and-invisible)))
+
+
+;;;===========================================================================
+;;; Minibuffer Setup
+;;;===========================================================================
+
+(defun x-symbol-setup-minibuffer ()
+ "Inherit buffer-local x-symbol variables for minibuffer."
+ (let (mode language)
+ (save-excursion
+ (set-buffer (window-buffer minibuffer-scroll-window))
+ (setq mode x-symbol-mode
+ language x-symbol-language))
+ (setq x-symbol-mode mode
+ x-symbol-language language)))
+(add-hook 'minibuffer-setup-hook 'x-symbol-setup-minibuffer)
+
+
+
+;;;;##########################################################################
+;;;; Input Methods
+;;;;##########################################################################
+
+
+(defvar x-symbol-language-history nil
+ "History of token languages, long form, see access `x-symbol-name'.")
+(defvar x-symbol-token-history nil
+ "History of tokens of any language.")
+
+(defvar x-symbol-last-abbrev ""
+ "Internal. Used by input methods CONTEXT, ELECTRIC, TOKEN.")
+(defvar x-symbol-electric-pos nil
+ "Internal. Used by input method ELECTRIC.")
+
+(defvar x-symbol-command-keys nil
+ "Internal. Key sequence set and used by `x-symbol-help'.
+Also used by temporary functions.")
+
+(defvar x-symbol-help-keys nil
+ "Internal. Key description used by `x-symbol-help-mapper'.")
+(defvar x-symbol-help-language nil
+ "Internal. Token language used for `x-symbol-help-mapper'.")
+(defvar x-symbol-help-completions nil
+ "Internal. Characters displayed prior to others.")
+(defvar x-symbol-help-completions1 nil
+ "Internal. Characters displayed late.")
+
+
+;;;===========================================================================
+;;; Miscellaneous key functions
+;;;===========================================================================
+
+(defun x-symbol-map-default-binding (&optional arg)
+ ;; checkdoc-params: (arg)
+ "Default binding in X-Symbol key map.
+Check `x-symbol-map-default-keys-alist' for commands to execute.
+Otherwise signal error `undefined-keystroke-sequence'."
+ (interactive "P")
+ (let* ((this (this-command-keys))
+ (last (aref this (1- (length this))))
+ (alist x-symbol-map-default-keys-alist)
+ definition)
+ (while alist
+ (if (x-symbol-event-matches-key-specifier-p last (caar alist))
+ (setq definition (car alist)
+ alist nil)
+ (setq alist (cdr alist))))
+ (if definition
+ (let ((cmd (or (cadr definition) (key-binding (vector last)))))
+ (if (caddr definition)
+ (progn
+ (command-execute cmd)
+ (setq prefix-arg arg)
+ (setq unread-command-events x-symbol-command-keys))
+ (setq prefix-arg arg)
+ (command-execute cmd)))
+ (signal-error 'undefined-keystroke-sequence (list this)))))
+
+
+;;;===========================================================================
+;;; self-insert
+;;;===========================================================================
+
+(defun x-symbol-read-charsym-token (charsym)
+ "Read one of the languages for defined tokens of CHARSYM."
+ (let* ((token (if x-symbol-language
+ (car (gethash charsym (x-symbol-generated-encode-table
+ (x-symbol-language-value
+ 'x-symbol-generated-data))))))
+ (language (x-symbol-read-language
+ (format "Insert %s in token language (default %s): "
+ charsym
+ (if token
+ (x-symbol-language-text)
+ x-symbol-charsym-name))
+ (if token x-symbol-language)
+ (lambda (lang)
+ (or (null (setq lang (cdr lang)))
+ (gethash charsym (x-symbol-generated-encode-table
+ (x-symbol-language-value
+ 'x-symbol-generated-data
+ lang))))))))
+ (or (if language
+ (car (gethash charsym (x-symbol-generated-encode-table
+ (x-symbol-language-value
+ 'x-symbol-generated-data
+ language)))))
+ (symbol-name charsym))))
+
+(defun x-symbol-insert-command (arg &optional charsym cstring)
+ "Insert character for CHARSYM.
+If ARG is a cons, e.g., when the current command is preceded by one or
+more \\[universal-argument]'s with no digits, select initialized
+language in minibuffer for token to insert. Otherwise insert character
+abs(ARG) times. If ARG is negative, do not barf if character is not
+valid, see `x-symbol-valid-charsym-function'.
+
+Restore window configuration if necessary, see `x-symbol-list-restore'.
+If buffer is read-only, store in `kill-ring'. If optional argument
+CSTRING is non-nil, insert that string instead the character. Optional
+CHARSYM defaults to `this-command's symbol property `x-symbol-charsym'."
+ (interactive "P")
+ (x-symbol-list-restore)
+ (or charsym (setq charsym (get this-command 'x-symbol-charsym)))
+ (if cstring
+ (setq charsym nil)
+ (if (consp arg)
+ (setq cstring (x-symbol-read-charsym-token charsym)
+ charsym nil
+ arg -1)
+ (setq cstring (gethash charsym x-symbol-cstring-table))))
+ (cond (isearch-mode
+ (if cstring (isearch-process-search-string cstring cstring)))
+ ((null cstring)
+ (error "Charsym %s has no character" charsym))
+ (buffer-read-only
+ (kill-new cstring)
+ (display-message 'message
+ (if charsym
+ (x-symbol-info charsym x-symbol-language nil
+ (x-symbol-fancy-value 'x-symbol-info-intro-yank
+ 'substitute-command-keys))
+ (concat (x-symbol-fancy-value 'x-symbol-info-intro-yank
+ 'substitute-command-keys)
+ cstring))))
+ (t
+ (if (natnump (setq arg (prefix-numeric-value arg)))
+ (or buffer-read-only
+ (null charsym)
+ (funcall x-symbol-valid-charsym-function charsym)
+ (error "Charsym %s not valid in current buffer" charsym))
+ (setq arg (- arg)))
+ (while (>= (decf arg) 0) (insert cstring)))))
+
+
+;;;===========================================================================
+;;; Read token
+;;;===========================================================================
+
+;;;###autoload
+(defun x-symbol-read-language (prompt default &optional predicate)
+ "Read token language in the minibuffer with completion.
+Use PROMPT in minibuffer. If the inserted string is empty, use DEFAULT
+as return value. If PREDICATE non-nil, only match languages if
+PREDICATE with argument (NAME . LANGUAGE) returns non-nil."
+ (let* ((languages (cons (cons x-symbol-charsym-name nil)
+ (mapcar (lambda (x) (cons (cdr x) (car x)))
+ x-symbol-language-alist)))
+ (completion-ignore-case t)
+ (language (completing-read prompt languages predicate t nil
+ 'x-symbol-language-history)))
+ (if (string-equal language "")
+ default
+ (cdr (assoc language languages)))))
+
+(defun x-symbol-read-token (&optional arg currentp)
+ "Select language and token to insert a character.
+Use `x-symbol-language' if optional CURRENTP is non-nil. If a number or
+nil, argument ARG is passed to `x-symbol-insert-command'."
+ (interactive "P")
+ (let* ((arg-strings (x-symbol-prefix-arg-texts arg))
+ (language (if currentp
+ x-symbol-language
+ (x-symbol-read-language
+ (format "Select %s by token language (current %s): "
+ (car arg-strings) (x-symbol-language-text))
+ x-symbol-language)))
+ (decode-obarray (if language
+ (x-symbol-generated-decode-obarray
+ (x-symbol-language-value
+ 'x-symbol-generated-data language))
+ x-symbol-charsym-decode-obarray))
+ (completion (try-completion "" decode-obarray))
+ (completion-ignore-case (if language
+ (x-symbol-grammar-case-function
+ (x-symbol-language-value
+ 'x-symbol-token-grammar language))))
+ (cstring (completing-read
+ (format "Insert %s %s: " (car arg-strings) (cdr arg-strings))
+ decode-obarray
+ (and (or (null arg) (natnump arg))
+ (lambda (x)
+ (funcall x-symbol-valid-charsym-function
+ (car (symbol-value x)))))
+ t
+ (and (stringp completion) completion)
+ 'x-symbol-token-history)))
+ (if (string-equal cstring "")
+ (error "No token entered")
+ (if (consp arg)
+ (x-symbol-insert-command -1 nil cstring)
+ (x-symbol-insert-command
+ arg (car (symbol-value (intern-soft cstring decode-obarray))))))))
+
+(defun x-symbol-read-token-direct (&optional arg)
+ "Select token in current language to insert a character.
+Argument ARG is passed to `x-symbol-insert-command'."
+ (interactive "P")
+ (x-symbol-read-token arg t))
+
+
+;;;===========================================================================
+;;; GRID
+;;;===========================================================================
+
+;;;###autoload
+(defun x-symbol-grid (&optional arg)
+ "Displays characters in a grid-like fashion for mouse selection.
+Display global or language dependent grid, see `x-symbol-local-grid'.
+See `x-symbol-list-mode' for key and mouse bindings. Without optional
+argument ARG and non-nil `x-symbol-grid-reuse', just popup old grid
+buffer if it already exists, but is not displayed. Store window
+configuration current before the invocation if `x-symbol-temp-grid' is
+non-nil, see `x-symbol-list-restore'."
+ (interactive "P")
+ (let* ((grid-alist (and x-symbol-local-grid
+ x-symbol-language
+ (x-symbol-generated-grid-alist
+ (x-symbol-language-value
+ 'x-symbol-generated-data))))
+ (language (and grid-alist x-symbol-language))
+ (win-config (and x-symbol-temp-grid (current-window-configuration)))
+ ;;(ref-buffer (and x-symbol-temp-grid (current-buffer)))
+ (ref-buffer (current-buffer))
+ (default-enable-multibyte-characters t)
+ (buffer (x-symbol-language-text x-symbol-grid-buffer-format))
+ (font (and (fboundp 'face-font-instance)
+ (face-font-instance 'x-symbol-heading-face))))
+ (x-symbol-init-input)
+ (or grid-alist (setq grid-alist x-symbol-grid-alist))
+ (and (null arg)
+ (get-buffer buffer)
+ (not (get-buffer-window buffer 'visible)) ; CW: new `visible'
+ (save-excursion
+ (set-buffer buffer)
+ ;; CW: in XEmacs, `pop-up-frames'=t seems to be broken.
+ (x-symbol-list-store ref-buffer win-config)
+ (funcall (or temp-buffer-show-function 'display-buffer) buffer)
+ (setq grid-alist nil))) ; exit
+ (when grid-alist
+ (save-excursion
+ (ignore-errors
+ ;; CW: in XEmacs, `pop-up-frames'=t seems to be broken, ignore error
+ (with-output-to-temp-buffer buffer))
+ (set-buffer buffer)
+ (if (featurep 'scrollbar)
+ (set-specifier scrollbar-height 0 (current-buffer)))
+ (setq truncate-lines t)
+ (and font (featurep 'xemacs)
+ (set-face-font 'default font (current-buffer)))
+ (setq tab-width x-symbol-grid-tab-width)
+ (let ((max (- (x-symbol-window-width
+ (get-buffer-window buffer 'visible))
+ x-symbol-grid-tab-width))
+ charsyms charsym pos extent face
+ (inhibit-read-only t))
+ (while grid-alist
+ (setq extent (insert-face (concat (caar grid-alist) ": ")
+ 'x-symbol-heading-face))
+ (set-extent-end-glyph extent x-symbol-heading-strut-glyph)
+
+ (set-extent-property extent 'help-echo
+ (x-symbol-fancy-value
+ 'x-symbol-grid-header-echo))
+ (insert "\t")
+ (setq charsyms (cdar grid-alist)
+ grid-alist (cdr grid-alist))
+ (while charsyms
+ (unless (memq (setq charsym (pop charsyms))
+ x-symbol-grid-ignore-charsyms)
+ (if (>= (current-column) max) (insert "\n\t"))
+ (setq pos (point))
+ (insert (gethash charsym x-symbol-fontified-cstring-table)
+ "\t")
+ (setq extent (add-list-mode-item pos (point) nil t charsym))
+ ;; for no-Mule -- CW: cannot be avoided, in x-symbol-nomule?
+ (if (fboundp 'set-extent-priority)
+ (set-extent-priority extent -10))
+ (set-extent-property extent 'help-echo 'x-symbol-highlight-echo)
+ (and language
+ (setq face (car (x-symbol-charsym-face charsym language)))
+ (set-extent-face extent face))))
+ (if grid-alist (insert "\n"))))
+ (set-buffer-modified-p nil)
+ (x-symbol-list-mode language ref-buffer win-config)
+ (setq tab-width x-symbol-grid-tab-width)
+ (and font (featurep 'xemacs)
+ (set-face-font 'default font (current-buffer)))))))
+
+
+;;;===========================================================================
+;;; General Insertion
+;;;===========================================================================
+
+(defun x-symbol-replace-from (from cstring &optional ignore)
+ "Replace buffer contents between FROM and `point' by CSTRING.
+If IGNORE is non-nil, the current command, which should be a
+self-inserting character, is ignored by providing a zero prefix
+argument. Also prepare the use of `undo' and `unexpand-abbrev'."
+ (or (stringp cstring)
+ (setq cstring (gethash cstring x-symbol-cstring-table)))
+ (when cstring
+ (and ignore
+ (null prefix-arg)
+ (self-insert-command 1))
+ (undo-boundary)
+ (let ((pos (point)))
+ (if (listp buffer-undo-list) ; put point position on undo-list...
+ (push pos buffer-undo-list)) ; ...necessary for aggressive CONTEXT
+ (setq x-symbol-last-abbrev cstring ; allow use of `unexpand-abbrev'
+ last-abbrev-location from
+ last-abbrev 'x-symbol-last-abbrev
+ last-abbrev-text (buffer-substring from pos))
+ ;; `replace-region': first insert, then delete (reason: markers)
+ (insert-before-markers cstring)
+ (delete-region from pos)
+ (if ignore (setq prefix-arg 0))
+ (setq abbrev-start-location pos ; this hack stops expand-abbrev
+ abbrev-start-location-buffer (current-buffer)))
+ (undo-boundary)
+ t))
+
+
+;;;===========================================================================
+;;; Input method TOKEN
+;;;===========================================================================
+
+;; Hint: if you trace one of these function in XEmacs, you break the handling
+;; of consecutive `self-insert-command's...
+
+(defvar x-symbol-token-search-prelude-size 10)
+
+(defun x-symbol-replace-token (&optional command-char)
+ "Replace token by corresponding character.
+If COMMAND-STRING is non-nil, check token shape."
+ (let* ((grammar (x-symbol-language-value 'x-symbol-input-token-grammar))
+ (generated (x-symbol-language-value 'x-symbol-generated-data))
+ (decode-obarray (x-symbol-generated-decode-obarray generated))
+ (case-fold-search (x-symbol-grammar-case-function ;#dynamic
+ (x-symbol-language-value 'x-symbol-token-grammar)))
+ (input-regexp (car grammar))
+ (input-spec (cdr grammar))
+ (beg (- (point) (x-symbol-generated-max-token-len generated)
+ x-symbol-token-search-prelude-size))
+ (res (save-excursion
+ (save-restriction
+ (narrow-to-region (max beg (point-at-bol)) (point))
+ (if (functionp input-spec)
+ (funcall input-spec input-regexp decode-obarray
+ command-char)
+ (x-symbol-match-token-before input-spec
+ (list input-regexp)
+ decode-obarray
+ command-char))))))
+ (if res (x-symbol-replace-from (car res) (cadr res)))))
+
+(defun x-symbol-match-token-before (contexts token-regexps decode-obarray
+ command-char)
+ (let ((case-fn (if (functionp case-fold-search) case-fold-search))
+ (before-context (car contexts))
+ (after-context (cdr contexts))
+ token charsym beg esc-char shape bad-regexp)
+ (when (characterp before-context)
+ (or (memq before-context '(?\ ?\t ?\n ?\r nil)) ; or warning?
+ (setq esc-char before-context))
+ (setq before-context nil))
+ (or before-context after-context (setq contexts nil))
+
+ (while token-regexps
+ (goto-char (point-min))
+ (and (re-search-forward (pop token-regexps) nil t)
+ (setq beg (match-beginning 0))
+ (eobp) ; regexp should always end with \\'
+ (setq token
+ (symbol-value
+ (intern-soft
+ (if case-fn
+ (funcall case-fn (buffer-substring beg (point-max)))
+ (buffer-substring beg (point-max)))
+ decode-obarray)))
+ (cond ((and esc-char (eq (char-before beg) esc-char)
+ (x-symbol-even-escapes-before-p (1- beg) esc-char)))
+ ((not (and contexts (setq shape (cadr token))))
+ (if (setq charsym (car token)) (setq token-regexps nil)))
+ ((and (setq bad-regexp (assq shape after-context))
+ (not (memq command-char '(?\ ?\t ?\n ?\r nil)))
+ (string-match (cdr bad-regexp)
+ (char-to-string command-char))))
+ ((and (setq bad-regexp (assq shape before-context))
+ (not (memq (char-before beg) '(?\ ?\t ?\n ?\r nil)))
+ (string-match (cdr bad-regexp)
+ (char-to-string (char-before beg)))))
+ ((setq charsym (car token))
+ (setq token-regexps nil)))))
+ (and charsym
+ (not (and x-symbol-unique (cddr token)))
+ (funcall x-symbol-valid-charsym-function charsym)
+ (cons beg token))))
+
+(defun x-symbol-token-input ()
+ "Provide input method TOKEN.
+Called in `x-symbol-pre-command-hook', see `x-symbol-token-input'."
+ (cond ((not (and x-symbol-language x-symbol-token-input)))
+ ((and prefix-arg (not (zerop (prefix-numeric-value prefix-arg)))))
+ ((and (symbolp this-command)
+ (fboundp this-command)
+ (or (get this-command 'x-symbol-input)
+ (and (symbolp (symbol-function this-command))
+ (get (symbol-function this-command) 'x-symbol-input))))
+ (x-symbol-replace-token))
+ ((not (eq this-command 'self-insert-command)))
+ (t
+ (x-symbol-replace-token (if prefix-arg nil last-command-char)))))
+
+
+;;;===========================================================================
+;;; Input method context
+;;;===========================================================================
+
+;;;###autoload
+(defun x-symbol-modify-key (&optional beg end)
+ "Modify key for input method CONTEXT.
+If character before point is a char alias, resolve alias, see
+\\[x-symbol-unalias]. If character before point is a character
+supported by package x-symbol, replace it by the next valid character in
+the modify-to chain.
+
+Otherwise replace longest context before point by a character which
+looks similar to it. See also \\[x-symbol-rotate-key] and
+`x-symbol-electric-input'. If called interactively and if the region is
+active, restrict context to the region between BEG and END."
+ (interactive (and (region-active-p)
+ (list (region-beginning) (region-end))))
+ (if (and beg end)
+ (save-excursion
+ (save-restriction
+ (narrow-to-region beg end)
+ (goto-char (point-max))
+ (x-symbol-modify-key)))
+ (x-symbol-init-input)
+ (let ((pos+charsym (or (x-symbol-valid-context-charsym
+ x-symbol-context-atree 'x-symbol-modify-to)
+ (x-symbol-next-valid-charsym-before
+ 'x-symbol-modify-to 'x-symbol-rotate-to))))
+ (if (and pos+charsym
+ (null (x-symbol-call-function-or-regexp
+ x-symbol-context-ignore
+ (buffer-substring (car pos+charsym) (point))
+ (cdr pos+charsym))))
+ (x-symbol-replace-from (car pos+charsym) (cdr pos+charsym))
+ (error "Nothing to modify")))))
+
+;;;###autoload
+(defun x-symbol-rotate-key (&optional arg beg end)
+ "Rotate key for input method CONTEXT.
+If character before point is a char alias, resolve alias, see
+\\[x-symbol-unalias]. If character before point is a character
+supported by package x-symbol, replace it by the next valid character in
+the rotate-to chain. With optional prefix argument ARG, the
+\"direction\" of the new character should be according to ARG and
+`x-symbol-rotate-prefix-alist'.
+
+Otherwise replace longest context before point by a character which
+looks similar to it, assuming an additional context suffix
+`x-symbol-rotate-suffix-char'. See also \\[x-symbol-modify-key] and
+`x-symbol-electric-input'. If called interactively and if the region is
+active, restrict context to the region between BEG and END."
+ (interactive (cons current-prefix-arg
+ (and (region-active-p)
+ (list (region-beginning) (region-end)))))
+ (if (and beg end)
+ (save-excursion
+ (save-restriction
+ (narrow-to-region beg end)
+ (goto-char (point-max))
+ (x-symbol-rotate-key arg)))
+ (x-symbol-init-input)
+ (if arg
+ (let* ((pos+charsym (x-symbol-charsym-after (1- (point))))
+ (charsym (cdr pos+charsym))
+ (direction (assq (prefix-numeric-value arg)
+ x-symbol-rotate-prefix-alist)))
+ (if charsym
+ (if direction
+ (if (setq charsym
+ (x-symbol-next-valid-charsym
+ charsym (cdr direction) 'x-symbol-rotate-to))
+ (x-symbol-replace-from (car pos+charsym) charsym)
+ (error "Cannot rotate %s to direction %s"
+ (cdr pos+charsym) (cdr direction)))
+ (error "Prefix argument %s does not represent a valid direction"
+ arg))
+ (error "Nothing to rotate")))
+ (let ((pos+charsym (or (x-symbol-valid-context-charsym
+ (assq x-symbol-rotate-suffix-char
+ x-symbol-context-atree)
+ 'x-symbol-modify-to)
+ (x-symbol-next-valid-charsym-before
+ 'x-symbol-rotate-to 'x-symbol-modify-to))))
+ (if (and pos+charsym
+ (null (x-symbol-call-function-or-regexp
+ x-symbol-context-ignore
+ (buffer-substring (car pos+charsym) (point))
+ (cdr pos+charsym))))
+ (x-symbol-replace-from (car pos+charsym) (cdr pos+charsym))
+ (error "Nothing to rotate"))))))
+
+(defun x-symbol-electric-input ()
+ "Provide input method ELECTRIC.
+Called in `x-symbol-post-command-hook', see `x-symbol-electric-input'."
+ (setq x-symbol-electric-pos
+ (and x-symbol-electric-input
+ x-symbol-mode
+ (symbolp this-command)
+ (fboundp this-command)
+ (or (eq this-command 'self-insert-command)
+ (get this-command 'x-symbol-input)
+ (and (symbolp (symbol-function this-command))
+ (get (symbol-function this-command) 'x-symbol-input)))
+ (null current-prefix-arg)
+ (not (and (local-variable-p 'current-input-method (current-buffer))
+ (equal current-input-method "x-symbol")))
+ (or x-symbol-electric-pos (1- (point)))))
+ (if x-symbol-electric-pos
+ (let ((pos+charsym (x-symbol-valid-context-charsym
+ x-symbol-electric-atree))
+ context)
+ (and pos+charsym
+ (>= (car pos+charsym) x-symbol-electric-pos)
+ (setq context (buffer-substring (car pos+charsym) (point)))
+ (or (let ((pos+charsym2 (x-symbol-valid-context-charsym
+ x-symbol-context-atree)))
+ (and pos+charsym2
+ (> (car pos+charsym) (car pos+charsym2)))) ; suffix
+ (x-symbol-call-function-or-regexp
+ x-symbol-context-ignore context (cdr pos+charsym))
+ (x-symbol-call-function-or-regexp
+ x-symbol-electric-ignore context (cdr pos+charsym))
+ (x-symbol-call-function-or-regexp
+ (x-symbol-language-value 'x-symbol-electric-ignore)
+ context (cdr pos+charsym))
+ (x-symbol-replace-from (car pos+charsym)
+ (cdr pos+charsym)))))))
+
+
+;;;===========================================================================
+;;; Keyboard Completion Help
+;;;===========================================================================
+
+(defun x-symbol-help-mapper (key binding)
+ "Collect help for specific KEY with BINDING."
+ (let ((x-symbol-help-keys (cons (single-key-description key)
+ x-symbol-help-keys))
+ charsym)
+ (if (keymapp binding)
+ (map-keymap #'x-symbol-help-mapper binding t)
+ (and (commandp binding)
+ (symbolp binding)
+ (setq charsym (get binding 'x-symbol-charsym))
+ (or (eq x-symbol-help-language t)
+ (funcall x-symbol-valid-charsym-function charsym
+ x-symbol-help-language))
+ (if (or (cdr x-symbol-help-keys)
+ (null (member (car x-symbol-help-keys)
+ (eval-when-compile
+ (mapcar 'single-key-description
+ (append "1234567890" nil))))))
+ (push (cons x-symbol-help-keys charsym)
+ x-symbol-help-completions)
+ (push (cons x-symbol-help-keys charsym)
+ x-symbol-help-completions1))))))
+
+(defun x-symbol-help-output (arg keys)
+ "Popup completions buffer for KEYS with prefix argument ARG."
+ (let ((win-config (and x-symbol-temp-help (current-window-configuration)))
+ (ref-buffer (current-buffer))
+ (read-only buffer-read-only)
+ (mode-on x-symbol-mode)
+ (language x-symbol-language)
+ (default-enable-multibyte-characters t)
+ (arg-texts (x-symbol-prefix-arg-texts arg)))
+ (with-output-to-temp-buffer x-symbol-completions-buffer
+ (save-excursion
+ (set-buffer x-symbol-completions-buffer)
+ (message "Working...")
+ (setq ctl-arrow 'ts) ; non-t-non-nil
+ (insert "You are typing a x-symbol key sequence to insert a "
+ (car arg-texts) " " (cdr arg-texts)
+ (if read-only "\ninto read-only buffer \"" "\ninto buffer \"")
+ (buffer-name ref-buffer)
+ (if language
+ (x-symbol-language-text
+ (if mode-on "\" (%s)" "\" (%s, turned-off)")
+ language)
+ "\"")
+ ".\nSo far you have typed \""
+ (key-description keys)
+ "\". "
+ (if (eq x-symbol-help-language t)
+ "Completions from here are:\n"
+ "Valid completions from here are:\n"))
+ (while x-symbol-help-completions
+ (insert "\n")
+ (let ((completion (pop x-symbol-help-completions))
+ (start (point)))
+ (when completion
+ (insert (mapconcat #'identity (reverse (car completion)) " "))
+ ;; no nreverse!
+ (indent-to 16)
+ (insert (x-symbol-info (cdr completion) language nil ""))
+ (set-extent-property
+ (add-list-mode-item start (point) nil t (cdr completion))
+ 'help-echo 'x-symbol-highlight-echo))))
+ (x-symbol-list-mode language ref-buffer win-config)))))
+
+(defun x-symbol-help (&optional arg)
+ ;; checkdoc-params: (arg)
+ "Display some help during a x-symbol key sequence.
+Displays some info for all characters which can be inserted by a key
+sequence starting with the current one. See `x-symbol-temp-help'."
+ (interactive "P")
+ (setq x-symbol-command-keys
+ (or (nbutlast (append (this-command-keys) nil))
+ x-symbol-command-keys))
+ (setq x-symbol-help-language
+ (or (consp arg) (< (prefix-numeric-value arg) 0)
+ (and x-symbol-mode x-symbol-language)))
+ (let* ((keys (apply 'vector x-symbol-command-keys))
+ (map (key-binding keys)))
+ (while (and x-symbol-command-keys (not (keymapp map)))
+ (setq x-symbol-command-keys (cdr x-symbol-command-keys)
+ keys (apply 'vector x-symbol-command-keys)
+ map (key-binding keys)))
+ (or x-symbol-command-keys
+ (error "Can't find map? %s" (this-command-keys)))
+ (setq x-symbol-help-completions nil
+ x-symbol-help-completions1 nil)
+ (map-keymap #'x-symbol-help-mapper map t)
+ (setq x-symbol-help-completions
+ (if x-symbol-help-completions1
+ (nconc (nreverse x-symbol-help-completions1)
+ (list nil) ; not! '(nil)
+ (nreverse x-symbol-help-completions))
+ (nreverse x-symbol-help-completions))
+ x-symbol-help-completions1 nil)
+ (if x-symbol-help-completions
+ (progn
+ (x-symbol-help-output arg keys)
+ ;; the code in x11/x-compose doesn't work here, this is easier anyway
+ (setq prefix-arg arg)
+ (setq unread-command-events x-symbol-command-keys))
+ (ding) ; CW: was (ding nil 'no-completion), not that important...
+ (message (if (eq x-symbol-help-language t)
+ "%s [No completions]"
+ "%s [No valid completions]")
+ (key-description keys))
+ ;; don't remember key sequence prefix until now
+ (setq x-symbol-command-keys nil
+ unread-command-events nil))))
+ ;;;(x-symbol-shrink-grid-buffer display))
+
+
+
+;;;;##########################################################################
+;;;; Init code
+;;;;##########################################################################
+
+
+(defvar x-symbol-face-docstrings
+ '("Face used for normal characters."
+ "Face used for subscripts."
+ "Face used for superscripts.")
+ "Docstrings for special x-symbol faces.")
+
+(defvar x-symbol-all-key-prefixes nil
+ "Internal. Key prefixes not shorter than `x-symbol-key-min-length'.")
+(defvar x-symbol-all-key-chain-alist nil
+ "Internal. Alist with elements (CONTEXT CHARSYM...).")
+(defvar x-symbol-all-horizontal-chain-alist nil
+ "Internal. Alist with elements (MODIFY-CONTEXT CHARSYM...).")
+(defvar x-symbol-all-chain-subchains-alist nil
+ "Internal. Alist with elements (CHAIN-REP (FIRST . LAST)...).")
+(defvar x-symbol-all-exclusive-context-alist nil
+ "Internal. Alist with elements (MODIFY-CONTEXT . CHAIN-REP).")
+
+
+;;;===========================================================================
+;;; Tiny functions
+;;;===========================================================================
+
+(defalias 'x-symbol-table-grouping 'car)
+(defalias 'x-symbol-table-aspects 'cadr)
+(defalias 'x-symbol-table-score 'caddr)
+(defalias 'x-symbol-table-input 'cadddr)
+(defsubst x-symbol-table-prefixes (xs) (nth 4 xs))
+(defsubst x-symbol-table-junk (xs) (nthcdr 5 xs))
+
+(defsubst x-symbol-charsym-defined-p (charsym)
+ (get charsym 'x-symbol-score))
+
+
+;;;===========================================================================
+;;; Init code per cset, called from x-symbol-{mule/nomule}
+;;;===========================================================================
+
+(defun x-symbol-try-font-name-0 (font raise)
+ (let ((sizes x-symbol-font-sizes)
+ (idx 0)
+ size args)
+ (while sizes
+ (if (string-match (caar sizes) font)
+ (setq size (cdar sizes)
+ sizes nil)
+ (setq sizes (cdr sizes))))
+ (setq size (or (nth raise size) (car (last size))
+ (if (zerop raise) 14 12)))
+ (while (string-match "%d" font idx)
+ (push size args)
+ (setq idx (match-end 0)))
+ (when (string-match "%s" font)
+ (push (nth raise x-symbol-font-family-postfixes) args))
+ (if args (apply 'format font args) font)))
+
+(defun x-symbol-try-font-name (fonts &optional raise)
+ "Return name of first valid font in FONTS."
+ (when fonts
+ (let ((fonts1 fonts) result)
+ (while fonts1
+ (if (setq result (try-font-name
+ (x-symbol-try-font-name-0 (car fonts1) (or raise 0))))
+ (setq fonts1 nil)
+ (setq fonts1 (cdr fonts1))))
+ (unless (or result (null raise))
+ (lwarn 'x-symbol 'warning
+ "Cannot find font in %s"
+ (mapconcat (lambda (f) (x-symbol-try-font-name-0 f raise))
+ fonts
+ ", ")))
+ result)))
+
+(defun x-symbol-set-cstrings (charsym coding cstring fchar face)
+ "Set cstrings of CHARSYM to CSTRING.
+Set string with duplicatable text property FACE. Also set file and buffer
+cstrings if CODING is non-nil. File cstrings are the representation as
+8bit characters in file with encoding CODING. Buffer cstrings are the
+representation in the buffer. Prefer using the buffer-cstring in
+`x-symbol-default-coding' as the default cstring, all other cstrings
+will be considered as char aliases, see \\[x-symbol-unalias]."
+ (unless (and coding
+ (let ((fchar-table (cdr (assq coding x-symbol-fchar-tables)))
+ (bchar-table (cdr (assq coding x-symbol-bchar-tables))))
+ (unless fchar-table ; for 96 chars
+ (setq fchar-table
+ ;; Emacs uses :size directly, XEmacs uses higher prime
+ (make-hash-table :size 113 :test 'eq)) ; (primep 113)
+ (setq x-symbol-fchar-tables
+ (nconc x-symbol-fchar-tables
+ (list (cons coding fchar-table)))))
+ (puthash charsym fchar fchar-table)
+
+ (unless bchar-table ; for 96 chars
+ (setq bchar-table
+ ;; Emacs uses :size directly, XEmacs uses higher prime
+ (make-hash-table :size 113 :test 'eq)) ; (primep 113)
+ (setq x-symbol-bchar-tables
+ (nconc x-symbol-bchar-tables
+ (list (cons coding bchar-table)))))
+ (puthash charsym cstring bchar-table)
+ (not (eq coding (or x-symbol-default-coding 'iso-8859-1))))
+ (gethash charsym x-symbol-cstring-table))
+ (or (stringp cstring) (setq cstring (char-to-string cstring)))
+ (puthash charsym cstring x-symbol-cstring-table)
+ (puthash charsym
+ (if face
+ (let ((copy (copy-sequence cstring)))
+ (put-text-property 0 (length copy) 'face face copy)
+ copy)
+ cstring)
+ x-symbol-fontified-cstring-table)))
+
+
+;;;===========================================================================
+;;; Init code per cset, MAIN: `x-symbol-init-cset'
+;;;===========================================================================
+
+(defun x-symbol-init-charsym-command (charsym)
+ "Init self insert command for CHARSYM. See `x-symbol-insert-command'."
+ (let ((command (intern (format "x-symbol-INSERT-%s" charsym))))
+ (fset command 'x-symbol-insert-command)
+ (put charsym 'x-symbol-insert-command command)
+ (put command 'isearch-command t)
+ (put command 'x-symbol-charsym charsym)))
+
+(defun x-symbol-init-charsym-input (charsym grouping score cset-score input
+ prefixes)
+ "Check and init input definitions for CHARSYM.
+Set GROUPING, SCORE, CSET-SCORE, INPUT, PREFIXES according to
+`x-symbol-init-cset'."
+ (let* ((group (car grouping))
+ (ginput (cdr (assq group x-symbol-group-input-alist)))
+ (subgroup (cadr grouping))
+ (opposite (caddr grouping))
+ (ascii (cadddr grouping))
+ (syntax (cdr (assq group x-symbol-group-syntax-alist)))
+ (syntax-special (assq subgroup (cdr syntax)))
+ context-strings electric-strings electric-ok
+ (case-fold-search nil))
+ (unless ginput
+ (warn "X-Symbol charsym %s: undefined group %S" charsym group)
+ (setq group nil
+ ginput '(0)))
+ (and subgroup (symbolp subgroup)
+ (setq subgroup (cdr (assq subgroup x-symbol-subgroup-string-alist))))
+ (unless (or (stringp subgroup) (null subgroup))
+ (warn "X-Symbol charsym %s: illegal subgroup %S" charsym (cadr grouping))
+ (setq subgroup nil))
+ (unless (symbolp opposite)
+ (warn "X-Symbol charsym %s: illegal opposite %S" charsym opposite)
+ (setq opposite nil))
+ (unless (or (stringp ascii) (null ascii))
+ (warn "X-Symbol charsym %s: illegal Ascii representation %S"
+ charsym ascii)
+ (setq ascii nil))
+ (if (numberp score)
+ (setq score (+ score (car ginput)))
+ (if score (warn "X-Symbol charsym %s: illegal score %S" charsym score))
+ (setq score (car ginput)))
+ (and (null input)
+ (stringp subgroup)
+ (progn
+ (setq input (mapcar (lambda (x)
+ (if (stringp x) (format x subgroup) x))
+ (cdr ginput)))
+ ;; accents: not only use "' " and " '", use "'" also
+ (and (string-equal subgroup " ")
+ (progn
+ (while (eq (car (setq ginput (cdr ginput))) t))
+ (stringp (car ginput)))
+ (push (format (car ginput) "") input))))
+ (dolist (context (reverse input))
+ (cond ((stringp context)
+ (push context context-strings)
+ (setq electric-ok t))
+ ((not (eq context t))
+ (warn "X-Symbol charsym %s: illegal input element %S"
+ charsym context))
+ (electric-ok
+ (push (car context-strings) electric-strings)
+ (setq electric-ok nil))
+ (t
+ (warn "X-Symbol charsym %s: misuse of input tag `t'" charsym))))
+ (put charsym 'x-symbol-grouping
+ (and group (list group subgroup opposite ascii)))
+ (put charsym 'x-symbol-syntax
+ (and syntax (cons (car syntax)
+ (and syntax-special opposite
+ (cons (cdr syntax-special) opposite)))))
+ (put charsym 'x-symbol-score (+ cset-score score))
+ (put charsym 'x-symbol-context-strings context-strings)
+ (put charsym 'x-symbol-electric-strings electric-strings)
+ (put charsym 'x-symbol-electric-prefixes prefixes)))
+
+(defun x-symbol-init-charsym-aspects (charsym aspects)
+ "Check and init ASPECTS of CHARSYM. See `x-symbol-init-cset'."
+ (let (modify-aspects
+ rotate-aspects
+ aspect value type)
+ (while (consp aspects)
+ (setq aspect (pop aspects)
+ value (and (consp aspects) (pop aspects)))
+ (cond ((setq type (assq aspect x-symbol-modify-aspects-alist))
+ (if (assq value (cdr type))
+ (setq modify-aspects (plist-put modify-aspects aspect value))
+ (warn "X-Symbol charsym %s: illegal modify aspect %s:%s"
+ charsym aspect value)))
+ ((setq type (assq aspect x-symbol-rotate-aspects-alist))
+ (if (assq value (cdr type))
+ (setq rotate-aspects (plist-put rotate-aspects aspect value))
+ (warn "X-Symbol charsym %s: illegal rotate aspect %s:%s"
+ charsym aspect value)))
+ (t
+ (warn "X-Symbol charsym %s: illegal aspect %s:%s"
+ charsym aspect value))))
+ (unless (symbolp aspects)
+ (warn "X-Symbol charsym %s: illegal parent %S" charsym aspects)
+ (setq aspects nil))
+ (put charsym 'x-symbol-modify-aspects (cons nil modify-aspects))
+ (put charsym 'x-symbol-rotate-aspects (cons nil rotate-aspects))
+ (put charsym 'x-symbol-parent (or aspects charsym))))
+
+(eval-when-compile (defvar x-symbol-no-of-charsyms))
+
+(defun x-symbol-init-cset (cset fonts table)
+ "Define and initialize a new character set.
+CSET looks like
+ (((REGISTRY . CODING) LEADING CSET-SCORE) MULE-LEFT . MULE-RIGHT)
+
+REGISTRY is the charset registry of the fonts in FONTS. If CODING is
+non-nil, characters defined in TABLE are considered to be 8bit
+characters if `x-symbol-coding' has value CODING. CSET-SCORE is the
+base score for characters defined in TABLE, see below.
+
+Under XEmacs/no-Mule, cstrings for characters defined in TABLE consist
+of the character LEADING and the octet ENCODING, explained below, if
+CODING is different to `x-symbol-default-coding'. LEADING should be in
+the range \\200-\\237.
+
+Under XEmacs/Mule, MULE-LEFT and MULE-RIGHT are used. They look like
+ nil or (NAME) or (NAME DOCSTRING CHARS FINAL)
+With the first form, no charset is used in that half of the font. With
+the second form, it is assumed that there exists a charset NAME. The
+third forms defines a new charset with name NAME, docstring DOCSTRING
+and the charset properties CHARS and FINAL, see `make-charset' for
+details.
+
+FONTS look like (NORMAL-FONT SUBSCRIPT-FONT SUPERSCRIPT-FONT) where each
+FONT is a list of fonts. They are tried until the first which is
+installed on your system, see `try-font-name'.
+
+Each element of TABLE looks like:
+ (CHARSYM ENCODING GROUPING ASPECTS SCORE INPUT PREFIXES) or
+ (CHARSYM ENCODING . t)
+Its character descriptions, not the ENCODING, can be shadowed by
+elements in `x-symbol-user-table'.
+
+Define a character with \"descriptions\" in current cset with encoding
+ENCODING. It is represented by the symbol CHARSYM. If CHARSYM already
+represents another character, the second form is used. This is only
+useful if both definitions were defined for csets with non-nil CODING.
+In this case, only one of the characters are normally used, the others
+are char aliases, see \\[x-symbol-unalias].
+
+GROUPING = (GROUP SUBGROUP OPPOSITE ASCII). GROUP defines the grid and
+submenu headers of the character, see `x-symbol-header-groups-alist'.
+SUBGROUP with `x-symbol-subgroup-string-alist' defines some order in the
+grid. OPPOSITE is used for \\[x-symbol-rotate-key] if no other
+character in the rotate chain has been defined. ASCII is the ascii
+representation, see `x-symbol-translate-to-ascii'.
+
+GROUP and SUBGROUP define the default INPUT and SCORE, see below and
+`x-symbol-group-input-alist', and default ascii representations, see
+`x-symbol-charsym-ascii-groups'. GROUP, SUBGROUP and OPPOSITE define
+the char syntax under XEmacs/Mule, see `x-symbol-group-syntax-alist'.
+
+ASPECTS = PARENT | (ASPECT VALUE . PARENT). Define modify and rotate
+aspects with corresponding values, see `x-symbol-modify-aspects-alist'
+and `x-symbol-rotate-aspects-alist'. If PARENT is non-nil, CHARSYM and
+PARENT are in the same component and CHARSYM inherits all remaining
+aspects from PARENT which should be defined in the same or earlier csets
+as the original definition of CHARSYM. See `x-symbol-init-input'.
+
+The charsym score is the addition of SCORE, or 0 if nil, the GROUP
+SCORE, see `x-symbol-group-input-alist', and CSET-SCORE, see above.
+
+INPUT = nil | (CONTEXT . INPUT) | (t CONTEXT . INPUT). Contexts
+defining key bindings and contexts for input method context. If CONTEXT
+is prefixed by t, it is also a context for input method electric. The
+first CONTEXT is called modify context and determines the modify-to
+chain. If INPUT is nil, use INPUT from `x-symbol-group-input-alist'
+with substitutions SUBGROUP/%s. See `x-symbol-init-input' for details.
+
+PREFIXES are charsyms which are considered prefixes for input method
+electric. Default prefixes are provided, though."
+ (let ((size (if (featurep 'xemacs)
+ x-symbol-no-of-charsyms
+ (x-symbol-get-prime-for x-symbol-no-of-charsyms))))
+ (unless x-symbol-cstring-table
+ (setq x-symbol-cstring-table
+ (make-hash-table :size size :test 'eq)))
+ (unless x-symbol-fontified-cstring-table
+ (setq x-symbol-fontified-cstring-table
+ (make-hash-table :size size :test 'eq)))
+ (unless x-symbol-charsym-decode-obarray
+ (setq x-symbol-charsym-decode-obarray
+ (make-vector (x-symbol-get-prime-for x-symbol-no-of-charsyms) 0))))
+ ;;--------------------------------------------------------------------------
+ (setq x-symbol-input-initialized nil)
+ (let* ((faces (x-symbol-make-cset cset
+ (if (stringp (car fonts))
+ (list fonts fonts fonts)
+ fonts)))
+ (cset-score (x-symbol-cset-score cset))
+ (coding (x-symbol-cset-coding cset))
+ (force-use (or x-symbol-latin-force-use
+ (eq (or x-symbol-default-coding 'iso-8859-1) coding)))
+ new-charsyms)
+ (unless faces
+ (when fonts
+ (warn (if (and coding force-use)
+ "X-Symbol characters with registry %S will look strange"
+ "X-Symbol characters with registry %S are not used")
+ (x-symbol-cset-registry cset))))
+ (dolist (entry table)
+ (let ((charsym (car entry))
+ definition)
+ (if (or faces (and coding force-use))
+ (x-symbol-make-char cset (cadr entry) charsym (car faces) coding))
+ (set (intern (symbol-name charsym) x-symbol-charsym-decode-obarray)
+ (list charsym))
+ (if (memq (cddr entry) '(t unused))
+ (if coding
+ (if (x-symbol-charsym-defined-p charsym)
+ (if (eq (cddr entry) 'unused)
+ (warn "X-Symbol charsym %s: redefinition as unused"
+ charsym))
+ (if (eq (cddr entry) 'unused)
+ (push charsym new-charsyms)
+ (warn "X-Symbol charsym %s: alias without definition"
+ charsym)))
+ (warn "X-Symbol charsym %s: alias or unused without coding system"
+ charsym))
+ (if (x-symbol-charsym-defined-p charsym)
+ (progn
+ (warn "X-Symbol charsym %s: redefinition (not used)" charsym)
+ (or (assq charsym new-charsyms)
+ (assq charsym x-symbol-all-charsyms)
+ (push charsym new-charsyms))) ; ie, re-run
+ (push charsym new-charsyms)
+ (setq definition (cddr (or (assq charsym x-symbol-user-table)
+ entry)))
+ (when (x-symbol-table-junk definition)
+ (warn "X-Symbol charsym %s: unused elements in definition"
+ charsym))
+ (x-symbol-init-charsym-command charsym)
+ (x-symbol-init-charsym-input charsym
+ (x-symbol-table-grouping definition)
+ (x-symbol-table-score definition)
+ cset-score
+ (x-symbol-table-input definition)
+ (x-symbol-table-prefixes definition))
+ (x-symbol-init-charsym-aspects charsym
+ (x-symbol-table-aspects
+ definition))))))
+ (x-symbol-init-charsym-syntax new-charsyms) ; after all (reason: opposite)
+ (setq x-symbol-all-charsyms ; cosmetic reverse
+ (nconc x-symbol-all-charsyms (nreverse new-charsyms)))))
+
+
+;;;===========================================================================
+;;; New data-type atree
+;;;===========================================================================
+
+(defun x-symbol-make-atree ()
+ "Create a new association tree."
+ (list nil))
+
+(defun x-symbol-atree-push (value key atree)
+ "Insert VALUE as the association for KEY in ATREE.
+KEY should be a string, VALUE is typically recovered by calling
+`x-symbol-match-before'."
+ (let ((path (nreverse (append key nil)))
+ branch)
+ (while path
+ (if (setq branch (assoc (car path) (cdr atree)))
+ (setq atree (cdr branch))
+ (setq branch (list (car path) nil))
+ (setcdr atree (cons branch (cdr atree)))
+ (setq atree (cdr branch)))
+ (setq path (cdr path)))
+ (setcar atree value)))
+
+
+;;;===========================================================================
+;;; Charsym components
+;;;===========================================================================
+
+(defun x-symbol-component-root-p (node)
+ "Non-nil, if NODE is the root of a symbol component."
+ (listp (get node 'x-symbol-component)))
+
+(defun x-symbol-component-elements (node)
+ "Return all elements in symbol component of NODE."
+ (or (listp (get node 'x-symbol-component))
+ (setq node (get node 'x-symbol-component)))
+ (or (get node 'x-symbol-component)
+ (list node)))
+
+(defun x-symbol-component-merge (node1 node2)
+ "Merge components of NODE1 and NODE2, return root of merged component."
+ (or (listp (get node1 'x-symbol-component))
+ (setq node1 (get node1 'x-symbol-component)))
+ (or (eq node1 node2)
+ (eq node1 (get node2 'x-symbol-component))
+ (let ((elements2 (x-symbol-component-elements node2)))
+ (when node1
+ (put node1 'x-symbol-component
+ (nconc (x-symbol-component-elements node1) elements2))
+ (while elements2
+ (put (pop elements2) 'x-symbol-component node1)))))
+ node1)
+
+(defun x-symbol-component-space (root prop)
+ "Classify component of ROOT according to symbol property PROP.
+Return an alist with elements (PROP-VALUE NODE...) where `cdr' of the
+symbol property PROP of all NODEs are `equal' to PROP-VALUE."
+ (let (space)
+ (dolist (charsym (x-symbol-component-elements root))
+ (x-symbol-push-assoc charsym (cdr (get charsym prop)) space))
+ space))
+
+
+;;;===========================================================================
+;;; Code for charsym aspects
+;;;===========================================================================
+
+(defun x-symbol-modify-less-than (charsym1 charsym2)
+ "Non-nil, if CHARSYM1 has a lower modify score than CHARSYM2."
+ (< (car (get charsym1 'x-symbol-modify-aspects))
+ (car (get charsym2 'x-symbol-modify-aspects))))
+
+(defun x-symbol-inherit-aspects (charsym prop parent)
+ "CHARSYM inherits all aspects in `cdr' of property PROP from PARENT.
+The `cdr' of properties PROP of CHARSYM and PARENT should be plists."
+ (let ((aspects (cdr (get charsym prop))))
+ (x-symbol-do-plist (aspect value (cdr (get parent prop)))
+ (or (plist-member aspects aspect)
+ (setq aspects (plist-put aspects aspect value))))
+ (put charsym prop (cons nil aspects))))
+
+(defun x-symbol-compute-aspects (charsym prop score-alists score)
+ "Compute CHARSYM's aspects stored in PROP with their scores.
+Each element of SCORE-ALISTS looks like (ASPECT (VALUE . VSCORE)...).
+Order aspects according to SCORE-ALISTS. For all ASPECTs with their
+VALUEs, add corresponding VSCOREs to SCORE. Finally, set car of PROP to
+the sum."
+ (let* ((aspect-plist (cdr (get charsym prop)))
+ (aspect-alist
+ (mapcar (lambda (elem)
+ (let ((type (assq (plist-get aspect-plist (car elem))
+ (cdr elem))))
+ (if type (setq score (+ score (cdr type))))
+ (cons (car elem) (car type))))
+ score-alists)))
+ (put charsym prop (cons score (destructive-alist-to-plist aspect-alist)))))
+
+(defun x-symbol-init-aspects ()
+ "Initialize the aspects of all currently defined charsyms.
+This includes component merging, inheritance and aspect scores."
+ (let (parent)
+ ;; Check parents ---------------------------------------------------------
+ (dolist (charsym x-symbol-all-charsyms)
+ (when (setq parent (get charsym 'x-symbol-parent))
+ (put charsym 'x-symbol-component nil)
+ (if (eq charsym parent)
+ (remprop charsym 'x-symbol-parent)
+ (unless (x-symbol-charsym-defined-p parent)
+ (warn "X-Symbol charsym %s: undefined parent %s" charsym parent)
+ (remprop charsym 'x-symbol-parent)))))
+ ;; Aspects inheritance, component building -------------------------------
+ (dolist (charsym
+ ;; Maximum path length is small enough => fast enough
+ (x-symbol-dolist-delaying (charsym x-symbol-all-charsyms)
+ (and (setq parent (get charsym 'x-symbol-parent))
+ (get parent 'x-symbol-parent))
+ (when parent
+ (x-symbol-inherit-aspects charsym 'x-symbol-modify-aspects
+ parent)
+ (x-symbol-inherit-aspects charsym 'x-symbol-rotate-aspects
+ parent)
+ (x-symbol-component-merge parent charsym)
+ (remprop charsym 'x-symbol-parent))))
+ (warn "X-Symbol charsym %s: circular inheritance %s"
+ charsym (get charsym 'x-symbol-parent))))
+ ;; Compute aspects scores --------------------------------------------------
+ (dolist (charsym x-symbol-all-charsyms)
+ (when (get charsym 'x-symbol-insert-command)
+ (x-symbol-compute-aspects charsym 'x-symbol-modify-aspects
+ x-symbol-modify-aspects-alist
+ (get charsym 'x-symbol-score))
+ (x-symbol-compute-aspects charsym 'x-symbol-rotate-aspects
+ x-symbol-rotate-aspects-alist 0)
+ (remprop charsym 'x-symbol-parent)
+ (remprop charsym 'x-symbol-modify-to)
+ (remprop charsym 'x-symbol-rotate-to))))
+
+
+;;;===========================================================================
+;;; Init global modify chain/subchain alists
+;;;===========================================================================
+
+(defun x-symbol-sort-modify-chain (chain)
+ "Sort charsyms in CHAIN according to modify score.
+Issue warning of two charsyms have the same score."
+ (setq chain (sort chain 'x-symbol-modify-less-than))
+ (let (score previous-score previous-charsym)
+ (dolist (charsym chain)
+ (setq score (car (get charsym 'x-symbol-modify-aspects)))
+ (and previous-charsym
+ (= previous-score score)
+ (warn "X-Symbol charsyms %s and %s: same modify score %d"
+ previous-charsym charsym score))
+ (setq previous-score score
+ previous-charsym charsym)))
+ chain)
+
+(defun x-symbol-init-horizontal/key-alist (chain contexts)
+ "Create horizontal and key chains for all charsyms in CHAIN.
+Do it for all contexts in CHAIN starting with CONTEXTS. The first
+context in CONTEXTS is the modify context. Also set key prefixes."
+ (dolist (charsym chain)
+ (setq contexts (or (get charsym 'x-symbol-context-strings)
+ contexts))
+ (x-symbol-push-assoc charsym (car contexts)
+ x-symbol-all-horizontal-chain-alist)
+ (dolist (key contexts)
+ (unless (x-symbol-push-assoc charsym key x-symbol-all-key-chain-alist)
+ (while (and (> (length key) x-symbol-key-min-length)
+ (null (member (setq key (substring key 0 -1))
+ x-symbol-all-key-prefixes)))
+ (push key x-symbol-all-key-prefixes))))))
+
+(defun x-symbol-init-exclusive-alist (chain context)
+ "Check whether CHAIN uses its CONTEXT exclusively.
+If so, store all subchains in `x-symbol-all-chain-subchains-alist', in
+reverse order. If not, delete previously stored subchains for CONTEXT."
+ (let ((chain-rep (car chain))
+ subchain-beg subchain-end subchains
+ (exclusive t)
+ charsym next-context temp)
+ (while chain
+ (setq subchain-beg (pop chain)
+ subchain-end subchain-beg)
+ (while (and (setq charsym (car chain))
+ (or (null (setq next-context
+ (car (get charsym
+ 'x-symbol-context-strings))))
+ (string-equal next-context context)))
+ (setq subchain-end charsym)
+ (setq chain (cdr chain)))
+ (push (cons subchain-beg subchain-end) subchains)
+ ;; Delete subchains for chain which previously used the same context
+ ;; exclusively.
+ (if (setq temp (assoc context x-symbol-all-exclusive-context-alist))
+ (progn
+ (setq exclusive nil)
+ (x-symbol-set-assq nil (cdr temp)
+ x-symbol-all-chain-subchains-alist)
+ (setcdr temp nil)) ; for debugging
+ (push (cons context chain-rep) x-symbol-all-exclusive-context-alist))
+ (setq context next-context))
+ ;; Store begin and end of subchains, if all contexts were used exclusively.
+ (x-symbol-set-assq (and exclusive subchains) chain-rep
+ x-symbol-all-chain-subchains-alist)))
+
+
+;;;===========================================================================
+;;; Init modify and rotate chains, context and electric atrees, keys
+;;;===========================================================================
+
+(defun x-symbol-init-horizontal-chain (chain previous)
+ "Set modify-to behavior for all charsyms in CHAIN.
+PREVIOUS modifies to the first charsym in CHAIN."
+ ;; Warning about same scores will appear when defining key bindings
+ (dolist (charsym chain)
+ (put previous 'x-symbol-modify-to charsym)
+ (setq previous charsym)))
+
+(defun x-symbol-init-exclusive-chain (subchains previous)
+ "Connect SUBCHAINS since all their contexts are used exclusively.
+PREVIOUS should be the first charsym of the chain."
+ (dolist (subchain subchains) ; subchains are reversed
+ (put (cdr subchain) 'x-symbol-modify-to previous)
+ (setq previous (car subchain))))
+
+(defun x-symbol-init-rotate-chain (chain)
+ "Set rotate-to behavior for all charsyms in CHAIN.
+Divide CHAIN in blocks containing charsyms with the same rotate score
+which are sorted according to their modify score. The blocks are sorted
+according to their rotate score. All charsyms in a block rotate to the
+first charsym in the next block."
+ (let (blocks)
+ (dolist (charsym chain)
+ (x-symbol-push-assq charsym
+ (car (get charsym 'x-symbol-rotate-aspects))
+ blocks))
+ (setq blocks (mapcar (lambda (block)
+ (sort (cdr block) 'x-symbol-modify-less-than))
+ (sort blocks 'car-less-than-car)))
+ ;; For each CHARSYM in a BLOCK, set `rotate-to' to (circular) next BLOCK.
+ (let ((last-block (car (last blocks))))
+ (dolist (block blocks)
+ (dolist (charsym last-block)
+ (put charsym 'x-symbol-rotate-to block))
+ (setq last-block block)))))
+
+(defun x-symbol-init-context-atree (context chain)
+ "Init atrees for input method CONTEXT and ELECTRIC for CONTEXT.
+\\[x-symbol-modify-key] modifies CONTEXT to the first charsym in CHAIN.
+Prefixes of CONTEXT could have been already converted to x-symbol
+characters. Contexts with these prefixes being replaced by the
+corresponding cstring of the x-symbol character are also considered."
+ (let ((charsym (car chain))) ; lowest score
+ (x-symbol-atree-push charsym context x-symbol-context-atree)
+ (if (member context (get charsym 'x-symbol-electric-strings))
+ (x-symbol-atree-push charsym context x-symbol-electric-atree)))
+ (let ((len (length context))
+ prefix-chain prefix-cstring)
+ (while (> (decf len) 0)
+ (when (setq prefix-chain (assoc (substring context 0 len)
+ x-symbol-all-key-chain-alist))
+ (dolist (prefix (cdr prefix-chain))
+ (catch 'x-symbol-init-context-atree
+ (or (setq prefix-cstring (gethash prefix x-symbol-cstring-table))
+ (throw 'x-symbol-init-context-atree t))
+ (let ((context1 (concat prefix-cstring (substring context len))))
+ ;; If any of the charsyms defines PREFIX as an electric prefix,
+ ;; use that one as the target.
+ (dolist (charsym chain)
+ (when (memq prefix (get charsym 'x-symbol-electric-prefixes))
+ (x-symbol-atree-push charsym context1 x-symbol-context-atree)
+ (x-symbol-atree-push charsym context1 x-symbol-electric-atree)
+ (throw 'x-symbol-init-context-atree t)))
+ ;; Otherwise, use charsym with same aspects as target.
+ (dolist (charsym chain)
+ (when (and (plists-eq
+ (cdr (get charsym 'x-symbol-modify-aspects))
+ (cdr (get prefix 'x-symbol-modify-aspects)))
+ (plists-eq
+ (cdr (get charsym 'x-symbol-rotate-aspects))
+ (cdr (get prefix 'x-symbol-rotate-aspects))))
+ (x-symbol-atree-push charsym context1 x-symbol-context-atree)
+ (if (member context (get charsym 'x-symbol-electric-strings))
+ (x-symbol-atree-push charsym context1
+ x-symbol-electric-atree))
+ (throw 'x-symbol-init-context-atree t)))
+ ;; Otherwise, use first charsym in chain (the one with the
+ ;; lowest score), but never for input method ELECTRIC.
+ (x-symbol-atree-push (car chain) context1
+ x-symbol-context-atree))))))))
+
+(defun x-symbol-init-key-bindings (context chain)
+ "Define key bindings for all charsyms in key chain CHAIN.
+The key bindings use CONTEXT and, if necessary, a digit."
+ (if (or (cdr chain) ; more than one charsym
+ (< (length context) x-symbol-key-min-length)
+ (member context x-symbol-all-key-prefixes))
+ (let ((suffix (eval-when-compile
+ (mapcar 'char-to-string (append "1234567890" nil)))))
+ (dolist (charsym chain)
+ (if suffix
+ (define-key x-symbol-map
+ (concat context (pop suffix))
+ (get charsym 'x-symbol-insert-command))
+ (warn "X-Symbol charsym %s: more than 10 bindings for key prefix %S"
+ charsym context))))
+ (define-key x-symbol-map context
+ (get (car chain) 'x-symbol-insert-command))))
+
+
+;;;===========================================================================
+;;; Grid and Menu
+;;;===========================================================================
+
+(defun x-symbol-rotate-modify-less-than (charsym1 charsym2)
+ "Non-nil, if the scores of CHARSYM1 are lower than those in CHARSYM2.
+The rotate score is more important than the modify score."
+ (let ((diff (- (car (get charsym1 'x-symbol-rotate-aspects))
+ (car (get charsym2 'x-symbol-rotate-aspects)))))
+ (or (< diff 0)
+ (and (zerop diff) (x-symbol-modify-less-than charsym1 charsym2)))))
+
+(defun x-symbol-subgroup-less-than (charsym1 charsym2)
+ "Non-nil, if subgroup string of CHARSYM1 is less than that of CHARSYM2."
+ (string-lessp (or (cadr (get charsym1 'x-symbol-grouping)) "\377")
+ (or (cadr (get charsym2 'x-symbol-grouping)) "\377")))
+
+(defun x-symbol-header-charsyms (&optional language)
+ "Return an alists with headers and their charsyms.
+If optional argument LANGUAGE is non-nil, only collect valid charsym in
+that language. Used for menu and grid. See variable and language
+access `x-symbol-header-groups-alist'."
+ (let (group-alist)
+ (dolist (charsym x-symbol-all-charsyms)
+ (when (or (null language)
+ ;; This is part of the initialization, we rely on the semantics
+ ;; => no (funcall x-symbol-valid-charsym-function ...)
+ (x-symbol-default-valid-charsym charsym language))
+ (x-symbol-push-assq charsym (car (get charsym 'x-symbol-grouping))
+ group-alist)))
+ (mapcar (lambda (header-groups)
+ (cons (car header-groups)
+ (apply #'nconc
+ (mapcar (lambda (group)
+ (sort (nreverse
+ (cdr (assq group group-alist)))
+ #'x-symbol-subgroup-less-than))
+ (cdr header-groups)))))
+ (or (and language
+ (symbol-value
+ (get language 'x-symbol-header-groups-alist)))
+ x-symbol-header-groups-alist))))
+
+(defun x-symbol-init-grid/menu (&optional language)
+ "Initialize the grid and the menu.
+If optional argument LANGUAGE is non-nil, init local grid/menu for that
+language."
+ (let (grid-alist menu-alist)
+ (dolist (header-charsyms (x-symbol-header-charsyms language))
+ (when (cdr header-charsyms)
+ (let ((header (car header-charsyms))
+ (charsyms (cdr header-charsyms)))
+ ;; Grid ------------------------------------------------------------
+ (let (charsyms1 charsyms2)
+ (dolist (charsym charsyms)
+ (unless (memq charsym charsyms1)
+ (setq charsyms1
+ (nconc charsyms1
+ (sort (intersection
+ (x-symbol-component-elements charsym)
+ charsyms)
+ 'x-symbol-rotate-modify-less-than)))))
+ (dolist (charsym charsyms1)
+ (if (gethash charsym x-symbol-cstring-table)
+ (push charsym charsyms2)))
+ (if charsyms2
+ (push (cons header (nreverse charsyms2)) grid-alist)))
+ ;; Menu ------------------------------------------------------------
+ (setq charsyms
+ (sort (mapcar
+ (lambda (charsym)
+ (vector (if language
+ (car (x-symbol-default-valid-charsym
+ charsym language))
+ (symbol-name charsym))
+ (get charsym 'x-symbol-insert-command)
+ t))
+ charsyms)
+ (lambda (a b) (string-lessp (aref a 0) (aref b 0)))))
+ (if (<= (length charsyms) x-symbol-menu-max-items)
+ (push (cons header charsyms) menu-alist)
+ (let* ((len (length charsyms))
+ (submenus (1+ (/ (1- len) x-symbol-menu-max-items)))
+ (items (/ len submenus))
+ (submenus (% len items))
+ (number 0)
+ charsyms1 i)
+ (while charsyms
+ (if (= submenus number) (decf items))
+ (setq charsyms1 nil
+ i items)
+ (while (>= i 0)
+ (decf i)
+ (push (pop charsyms) charsyms1))
+ (push (cons (format "%s %d" header (incf number))
+ (nreverse charsyms1))
+ menu-alist)))))))
+ ;; Set alists ------------------------------------------------------------
+ (setq grid-alist (nreverse grid-alist)
+ menu-alist (nreverse menu-alist))
+ (if language
+ (let ((generated (symbol-value
+ (get language 'x-symbol-generated-data))))
+ (setf (x-symbol-generated-menu-alist generated) menu-alist)
+ (setf (x-symbol-generated-grid-alist generated) grid-alist))
+ (setq x-symbol-menu-alist menu-alist
+ x-symbol-grid-alist grid-alist))))
+
+
+;;;===========================================================================
+;;; Init code for all charsyms. MAIN: `x-symbol-init-input'
+;;;===========================================================================
+
+;;;###autoload
+(defun x-symbol-init-input ()
+ "Initialize all input methods for all charsyms defined so far.
+Run `x-symbol-after-init-input-hook' afterwards. This function should
+be called if new charsyms have been added, but not too often since it
+takes some time to complete. Input methods TOKEN and READ-TOKEN are
+defined with `x-symbol-init-language'.
+
+As explained in the docstring of `x-symbol-init-cset', charsyms are
+defined with \"character descriptions\" which consist of different
+\"aspects\" and \"contexts\", which can also be inherited from a
+\"parent\" character. All characters which are connected with parents,
+form a \"component\". Aspects and contexts are used to determine the
+Modify-to and Rotate-to chain for characters, the contexts for input
+method CONTEXT and ELECTRIC, the key bindings, and the position in the
+MENU and the GRID.
+
+If a table entry of a charsym does not define its own contexts, they are
+the same as the contexts of the charsym in an earlier position in the
+\"modify chain\" (see below), or the contexts of the first charsym with
+defined contexts in the modify chain. The modify context of a charsym
+is the first context.
+
+Characters in the same component whose aspects only differ by their
+\"direction\" (east,...), a key in `x-symbol-rotate-aspects-alist', are
+circularly connected by \"rotate-to\". The sequence in the \"rotate
+chain\" is determined by rotate scores depending on the values in the
+rotate aspects. Charsyms with the same \"rotate-aspects\" are not
+connected (charsyms with the smallest modify scores are preferred).
+
+Characters in the same components whose aspects only differ by their
+\"size\" (big,...), \"shape\" (round, square,...) and/or \"shift\" (up,
+down,...), keys in `x-symbol-modify-aspects-alist', are circularly
+connected by \"modify-to\", if all their modify contexts are used
+exclusively, i.e., no other modify chain uses any of them. The sequence
+in the \"modify chain\" is determined by modify scores depending on the
+values in the modify aspects and the charsym score.
+
+Otherwise, the \"modify chain\" is divided into modify subchains, which
+are those charsyms sharing the same modify context. All modify
+subchains using the same modify context, build a \"horizontal chain\"
+whose charsyms are circularly connected by \"modify-to\".
+
+We build a \"key chain\" for all contexts (not just modify contexts),
+consisting of all charsyms (sorted according to modify scores) having
+the context. Input method CONTEXT modifies the context to the first
+charsym in the \"key chain\".
+
+If there is only one charsym in the key chain, `x-symbol-compose-key'
+plus the context inserts the charsym. Otherwise, we use a digit \(1..9,
+0\) as a suffix for each charsym in the key chain.
+`x-symbol-compose-key' plus the context plus the optional suffix inserts
+the charsym."
+ (unless x-symbol-input-initialized
+ (let ((gc-cons-threshold most-positive-fixnum)
+ (quail-ignore (regexp-quote x-symbol-quail-suffix-string)))
+ (setq x-symbol-input-initialized t)
+ (x-symbol-init-aspects)
+ (setq x-symbol-all-key-prefixes nil)
+ (setq x-symbol-all-key-chain-alist nil)
+ (setq x-symbol-all-horizontal-chain-alist nil)
+ (setq x-symbol-all-chain-subchains-alist nil)
+ (setq x-symbol-all-exclusive-context-alist nil)
+ (dolist (root x-symbol-all-charsyms)
+ (when (and (get root 'x-symbol-insert-command)
+ (x-symbol-component-root-p root))
+ (dolist (chain (x-symbol-component-space root
+ 'x-symbol-modify-aspects))
+ (x-symbol-init-rotate-chain (cdr chain)))
+ (dolist (chain (x-symbol-component-space root
+ 'x-symbol-rotate-aspects))
+ (setq chain (x-symbol-sort-modify-chain (cdr chain)))
+ (let ((input (some (lambda (charsym)
+ (get charsym 'x-symbol-context-strings))
+ chain)))
+ (if input
+ (progn
+ (x-symbol-init-horizontal/key-alist chain input)
+ (x-symbol-init-exclusive-alist chain (car input)))
+ (dolist (charsym chain)
+ (warn "X-Symbol charsym %s: no input" charsym)))))))
+ (dolist (chain x-symbol-all-horizontal-chain-alist)
+ ;; Do not use `x-symbol-sort-modify-chain', since same warnings will
+ ;; appear later again.
+ (setq chain (setcdr chain ; do not destroy horizontal chain
+ (sort (cdr chain) 'x-symbol-modify-less-than)))
+ (x-symbol-init-horizontal-chain chain (car (last chain))))
+ (dolist (entry x-symbol-all-chain-subchains-alist)
+ (x-symbol-init-exclusive-chain (cdr entry) (car entry)))
+ (setq x-symbol-context-atree (x-symbol-make-atree)
+ x-symbol-electric-atree (x-symbol-make-atree))
+ (setq x-symbol-map (make-keymap))
+ (dolist (entry x-symbol-all-key-chain-alist) ; first sort
+ (setcdr entry (x-symbol-sort-modify-chain (cdr entry))))
+ (if x-symbol-define-input-method-quail
+ (x-symbol-init-quail-bindings nil nil))
+ (dolist (entry x-symbol-all-key-chain-alist) ; then use
+ (let ((context (car entry))
+ (chain (cdr entry)))
+ (or (and x-symbol-context-init-ignore
+ (string-match x-symbol-context-init-ignore context))
+ (x-symbol-init-context-atree context chain))
+ (unless (string-match "[0-9]" context 1) ; no digit from 2nd char on
+ (or (null x-symbol-define-input-method-quail)
+ (string-match quail-ignore context 1) ; no semi from 2nd char
+ (and x-symbol-quail-init-ignore
+ (string-match x-symbol-quail-init-ignore context))
+ (x-symbol-init-quail-bindings context chain))
+ (or (and x-symbol-key-init-ignore
+ (string-match x-symbol-key-init-ignore context))
+ (x-symbol-init-key-bindings context chain))))))
+ (or (featurep 'xemacs) ; CW: is OK in XEmacs, but slow
+ (dolist (m (mapcar 'cdr (accessible-keymaps x-symbol-map)))
+ (set-keymap-default-binding m 'x-symbol-map-default-binding)))
+ (defalias 'x-symbol-map x-symbol-map)
+ (x-symbol-init-grid/menu)
+ (substitute-key-definition 'x-symbol-map-autoload 'x-symbol-map global-map)
+ (dolist (binding x-symbol-map-default-bindings)
+ (define-key x-symbol-map
+ (or (car binding) (vector x-symbol-compose-key))
+ (cadr binding)))
+ ;; always set the following (or only if `x-symbol-map-default-keys-alist'
+ ;; is non-nil?):
+ (set-keymap-default-binding x-symbol-map 'x-symbol-map-default-binding)
+ (run-hooks 'x-symbol-after-init-input-hook)))
+
+
+;;;===========================================================================
+;;; Latin recoding
+;;;===========================================================================
+
+(defun x-symbol-init-latin-decoding ()
+ "Init alists for latin decoding and \\[x-symbol-unalias].
+This function should be run after all csets with CODING have been
+defined, see `x-symbol-init-cset'."
+ (let (normalize-alist decode-alists)
+ ;; set alists ------------------------------------------------------------
+ (dolist (charsym (reverse x-symbol-all-charsyms)) ; rev cosmetic
+ (let ((cstring (gethash charsym x-symbol-cstring-table)) bfstring)
+ (dolist (table x-symbol-bchar-tables)
+ (and (setq bfstring (gethash charsym (cdr table)))
+ (not (equal (if (stringp bfstring)
+ bfstring
+ (setq bfstring (char-to-string bfstring)))
+ cstring))
+ (push (cons bfstring cstring) normalize-alist)))
+ (dolist (table x-symbol-fchar-tables)
+ (and (setq bfstring (gethash charsym (cdr table)))
+ (not (equal (setq bfstring (char-to-string bfstring)) cstring))
+ (x-symbol-push-assq (cons bfstring cstring) (car table)
+ decode-alists)))))
+ (setq x-symbol-unalias-alist (nreverse normalize-alist))
+ ; rev cosmetic
+ ;; order recodings in decoding -------------------------------------------
+ (setq x-symbol-latin-decode-alists nil)
+ (dolist (coding+alist decode-alists)
+ (let (decode-alist)
+ (when (x-symbol-dolist-delaying
+ (decode-elem (nreverse (cdr coding+alist)) working delayed)
+ (let ((octet (substring (cdr decode-elem) -1)))
+ (or (assoc octet (cdr working)) (assoc octet delayed)))
+ (push decode-elem decode-alist))
+ (error "Circular recoding between latin characters"))
+ (push (cons (car coding+alist)
+ (nreverse decode-alist)) ; rev important
+ x-symbol-latin-decode-alists)))))
+
+
+;;;===========================================================================
+;;; Token languages
+;;;===========================================================================
+
+(defun x-symbol-get-prime-for (size)
+ (setq size (/ (* size 5) 4))
+ ;; not all primes
+ (let ((primes '(127 149 173 197 223 251 283 317 359 409 463 523 599 683 773
+ 883 1009 1151 1307 1493 1709 1951 2341 2819 3389 4073))
+ result)
+ (while (and (setq result (pop primes)) (< result size)))
+ (or result size)))
+
+(defun x-symbol-alist-to-obarray (alist)
+ (let ((ob-array (make-vector (x-symbol-get-prime-for (length alist)) 0)))
+ (dolist (elt alist)
+ (set (intern (car elt) ob-array) (cdr elt)))
+ ob-array))
+
+(defun x-symbol-alist-to-hash-table (alist)
+ (let ((hash-table (make-hash-table
+ :size (if (featurep 'xemacs)
+ (length alist) ; does already use higher prime
+ (x-symbol-get-prime-for (length alist)))
+ :test 'eq)))
+ (dolist (elt alist)
+ (puthash (car elt) (cdr elt) hash-table))
+ hash-table))
+
+(defun x-symbol-init-language (language)
+ "Load and init token language LANGUAGE.
+Set language dependent accesses in `x-symbol-language-access-alist'.
+Set conversion alists according to table and initialize executables, see
+`x-symbol-init-executables'. Initialize all input methods, see
+`x-symbol-init-input'. LANGUAGE should have been registered with
+`x-symbol-register-language' before.
+
+Each element in TABLE, the language access `x-symbol-table', looks like
+ (CHARSYM CLASSES . TOKEN-SPEC) or nil.
+
+With the first form, pass TOKEN-SPEC to the language aspect
+`x-symbol-token-list' to get a list of TOKENs. Decoding converts all
+TOKENs to the cstring of CHARSYM, encoding converts the cstring to the
+first TOKEN.
+
+IF CHARSYM or the first TOKEN is used a second time in the table, issue
+a warning and do not define entries for decoding and encoding. If any
+TOKEN appears a second time, do not define the corresponding entry for
+decoding. If the third form nil has appeared in TABLE, do not issue a
+warning for the next entries in TABLE.
+
+CLASSES are a list of symbols which are used for the character info in
+the echo are, see `x-symbol-character-info', the grid coloring scheme,
+and probably by the token language dependent control of input method
+ELECTRIC, see `x-symbol-electric-input'. They are used by the language
+accesses `x-symbol-class-alist' and `x-symbol-class-face-alist'.
+
+If non-nil, the language aspect `x-symbol-input-token-ignore' \"hides\"
+some tokens from input method token. `x-symbol-call-function-or-regexp'
+uses it with TOKEN and CHARSYM."
+ (when (get language 'x-symbol-feature)
+ (require (get language 'x-symbol-feature))
+ (x-symbol-init-language-accesses language x-symbol-language-access-alist)
+ (put language 'x-symbol-initialized t)
+ (dolist (feature (x-symbol-language-value 'x-symbol-required-fonts
+ language))
+ (require feature))
+ (x-symbol-init-input)
+ (let ((grammar (x-symbol-language-value 'x-symbol-token-grammar language)))
+ (when (eq (car-safe grammar) 'x-symbol-make-grammar)
+ (setq grammar (apply 'x-symbol-make-grammar (cdr grammar)))
+ (set (get language 'x-symbol-token-grammar) grammar))
+ (let ((token-list (x-symbol-grammar-token-list grammar))
+ (after-init (x-symbol-grammar-after-init grammar))
+ (class-alist (x-symbol-language-value 'x-symbol-class-alist
+ language))
+ decode-alist encode-alist classes-alist
+ (warn-double t)
+ used-charsyms used-tokens secondary
+ (max-token-len 0) tlen)
+ (dolist (entry (x-symbol-language-value 'x-symbol-table language))
+ (if (null entry)
+ (setq warn-double nil)
+ (let* ((charsym (car entry))
+ (classes (cadr entry))
+ (tokens (if token-list
+ (funcall token-list (cddr entry))
+ (mapcar #'list (cddr entry)))))
+ ;; Check entries, set charsym properties -----------------------
+ (cond ((null charsym))
+ ((memq charsym used-charsyms)
+ (if warn-double
+ (warn "X-Symbol charsym %s: used twice in language %s"
+ charsym language))
+ (setq charsym nil))
+ ((memq charsym x-symbol-all-charsyms)
+ (push charsym used-charsyms))
+ (t
+ (warn "X-Symbol: used undefined charsym %s in language %s"
+ charsym language)))
+ (dolist (class classes)
+ (unless (assq class class-alist)
+ (warn "X-Symbol charsym %s: undefined %s class %s"
+ (car entry) language class)))
+ (and charsym
+ (or (null tokens)
+ (member (caar tokens) used-tokens)
+ (not (gethash charsym x-symbol-cstring-table)))
+ (setq charsym nil))
+ ;;--------------------------------------------------------------
+ ;; TODO: allow (nil nil TOKEN...) to shadow tokens
+ (when charsym
+ (push (cons charsym classes) classes-alist)
+ (push (cons charsym (car tokens)) encode-alist)
+ (setq secondary nil)
+ (dolist (token tokens)
+ (if (member (car token) used-tokens)
+ (if warn-double
+ (warn "X-Symbol charsym %s: used %s token %S twice"
+ (car entry) language (car token)))
+ (push (car token) used-tokens)
+ (push (list* (car token) charsym (cdr token) secondary)
+ decode-alist)
+ (if (> (setq tlen (length (car token))) max-token-len)
+ (setq max-token-len tlen))
+ (setq secondary t)))))))
+ ;; set vars ----------------------------------------------------------
+ (set (get language 'x-symbol-generated-data)
+ (x-symbol-make-generated-data
+ :encode-table (x-symbol-alist-to-hash-table encode-alist)
+ :decode-obarray (x-symbol-alist-to-obarray decode-alist)
+ :token-classes (x-symbol-alist-to-hash-table classes-alist)
+ :max-token-len max-token-len))
+ (if (functionp after-init) (funcall after-init))))
+ (x-symbol-init-grid/menu language)
+ t))
+
+
+
+;;;;##########################################################################
+;;;; The Tables
+;;;;##########################################################################
+
+;; ISO 2022/2375 final char/byte (for charset extension/switching): 0x30-0x3F
+;; are reserved as user-defined. Emacs keeps 0x3A-0x3F [:;<=>?] free for
+;; users, although XEmacs defines the charset `thai-xtis' with final ??...
+
+(defvar x-symbol-latin1-cset
+ '((("iso8859-1" . iso-8859-1) ?\237 -3750)
+ nil .
+ (latin-iso8859-1))
+ "Cset with registry \"iso8859-1\", see `x-symbol-init-cset'.")
+
+(defvar x-symbol-latin2-cset
+ '((("iso8859-2" . iso-8859-2) ?\236 -3750)
+ nil .
+ (latin-iso8859-2))
+ "Cset with registry \"iso8859-2\", see `x-symbol-init-cset'.")
+
+(defvar x-symbol-latin3-cset
+ '((("iso8859-3" . iso-8859-3) ?\235 -3750)
+ nil .
+ (latin-iso8859-3))
+ "Cset with registry \"iso8859-3\", see `x-symbol-init-cset'.")
+
+(defvar x-symbol-latin5-cset
+ '((("iso8859-9". iso-8859-9) ?\234 -3750)
+ nil .
+ (latin-iso8859-9))
+ "Cset with registry \"iso8859-9\", see `x-symbol-init-cset'.")
+
+(defvar x-symbol-latin9-cset
+ '((("iso8859-15". iso-8859-15) ?\231 -3750)
+ nil .
+ (latin-iso8859-15 "ISO8859-15 (Latin-9)" 96 ?b) )
+ "Cset with registry \"iso8859-15\", see `x-symbol-init-cset'.")
+
+(defvar x-symbol-xsymb0-cset
+ '((("adobe-fontspecific") ?\233 -3600)
+ (xsymb0-left "X-Symbol characters 0, left" 94 ?:) .
+ (xsymb0-right "X-Symbol characters 0, right" 94 ?\;))
+ "Cset with registry \"fontspecific\", see `x-symbol-init-cset'.")
+
+(defvar x-symbol-xsymb1-cset
+ '((("xsymb-xsymb1") ?\232 -3500)
+ (xsymb1-left "X-Symbol characters 1, left" 94 ?<) .
+ (xsymb1-right "X-Symbol characters 1, right" 96 ?=))
+ "Cset with registry \"xsymb1\", see `x-symbol-init-cset'.")
+
+(defvar x-symbol-latin1-table
+ '((nobreakspace 160 (white) nil nil (" "))
+ (exclamdown 161 (punctuation) nil nil ("!"))
+ (cent 162 (currency "c") nil nil ("C|" "|C"))
+ (sterling 163 (currency "L") nil nil ("L-" "-L"))
+ (currency 164 (currency "x") nil nil ("ox" "xo"))
+ (yen 165 (currency "Y") nil nil ("Y=" "=Y"))
+ (brokenbar 166 (line) nil nil ("!!"))
+ (section 167 (symbol) nil nil ("SS"))
+ (diaeresis 168 (diaeresis accent))
+ (copyright 169 (symbol "C") nil nil ("CO" "cO"))
+ (ordfeminine 170 (symbol "a") (shift up) nil ("a_" "_a"))
+ (guillemotleft 171 (quote open guillemotright)
+ (direction west . guillemotright) nil (t "<<"))
+ (notsign 172 (symbol) nil nil ("-,"))
+ (hyphen 173 (line) (size sml) nil ("-"))
+ (registered 174 (symbol "R") nil nil ("RO"))
+ (macron 175 (line) (shift up) nil ("-"))
+ (degree 176 (symbol "0") (shift up) nil ("o^" "^o"))
+ (plusminus 177 (operator) (direction north) nil (t "+-" t "+_"))
+ (twosuperior 178 (symbol "2") (shift up) nil ("2^" "^2"))
+ (threesuperior 179 (symbol "3") (shift up) nil ("3^" "^3"))
+ (acute 180 (acute accent))
+ (mu1 181 (greek1 "m" nil "mu"))
+ (paragraph 182 (symbol "P") nil nil ("q|"))
+ (periodcentered 183 (dots) (shift up) nil ("." ".^" t "^."))
+ (cedilla 184 (cedilla accent))
+ (onesuperior 185 (symbol "1") (shift up) nil ("1^" "^1"))
+ (masculine 186 (symbol "o") (shift up) nil ("o_" "_o"))
+ (guillemotright 187 (quote close guillemotleft) (direction east) nil
+ (t ">>"))
+ (onequarter 188 (symbol "1") nil nil ("1Q" "1/4"))
+ (onehalf 189 (symbol "2") nil nil ("1H" "1/2"))
+ (threequarters 190 (symbol "3") nil nil ("3Q" "3/4"))
+ (questiondown 191 (punctuation) nil nil ("?"))
+ (Agrave 192 (grave "A" agrave))
+ (Aacute 193 (acute "A" aacute))
+ (Acircumflex 194 (circumflex "A" acircumflex))
+ (Atilde 195 (tilde "A" atilde))
+ (Adiaeresis 196 (diaeresis "A" adiaeresis))
+ (Aring 197 (ring "A" aring))
+ (AE 198 (letter "AE" ae))
+ (Ccedilla 199 (cedilla "C" ccedilla))
+ (Egrave 200 (grave "E" egrave))
+ (Eacute 201 (acute "E" eacute))
+ (Ecircumflex 202 (circumflex "E" ecircumflex))
+ (Ediaeresis 203 (diaeresis "E" ediaeresis))
+ (Igrave 204 (grave "I" igrave))
+ (Iacute 205 (acute "I" iacute))
+ (Icircumflex 206 (circumflex "I" icircumflex))
+ (Idiaeresis 207 (diaeresis "I" idiaeresis))
+ (ETH 208 (slash "D" eth) nil 120)
+ (Ntilde 209 (tilde "N" ntilde))
+ (Ograve 210 (grave "O" ograve))
+ (Oacute 211 (acute "O" oacute))
+ (Ocircumflex 212 (circumflex "O" ocircumflex))
+ (Otilde 213 (tilde "O" otilde))
+ (Odiaeresis 214 (diaeresis "O" odiaeresis))
+ (multiply 215 (operator) (shift up) nil ("x"))
+ (Ooblique 216 (slash "O" oslash))
+ (Ugrave 217 (grave "U" ugrave))
+ (Uacute 218 (acute "U" uacute))
+ (Ucircumflex 219 (circumflex "U" ucircumflex))
+ (Udiaeresis 220 (diaeresis "U" udiaeresis))
+ (Yacute 221 (acute "Y" yacute))
+ (THORN 222 (letter "TH" thorn))
+ (ssharp 223 (letter "ss" nil))
+ (agrave 224 (grave "a" Agrave))
+ (aacute 225 (acute "a" Aacute))
+ (acircumflex 226 (circumflex "a" Acircumflex))
+ (atilde 227 (tilde "a" Atilde))
+ (adiaeresis 228 (diaeresis "a" Adiaeresis))
+ (aring 229 (ring "a" Aring))
+ (ae 230 (letter "ae" AE))
+ (ccedilla 231 (cedilla "c" Ccedilla))
+ (egrave 232 (grave "e" Egrave))
+ (eacute 233 (acute "e" Eacute))
+ (ecircumflex 234 (circumflex "e" Ecircumflex))
+ (ediaeresis 235 (diaeresis "e" Ediaeresis))
+ (igrave 236 (grave "i" Igrave))
+ (iacute 237 (acute "i" Iacute))
+ (icircumflex 238 (circumflex "i" Icircumflex))
+ (idiaeresis 239 (diaeresis "i" Idiaeresis))
+ (eth 240 (slash "d" ETH) nil 120)
+ (ntilde 241 (tilde "n" Ntilde))
+ (ograve 242 (grave "o" Ograve))
+ (oacute 243 (acute "o" Oacute))
+ (ocircumflex 244 (circumflex "o" Ocircumflex))
+ (otilde 245 (tilde "o" Otilde))
+ (odiaeresis 246 (diaeresis "o" Odiaeresis))
+ (division 247 (operator) nil nil (":-" "-:"))
+ (oslash 248 (slash "o" Ooblique))
+ (ugrave 249 (grave "u" Ugrave))
+ (uacute 250 (acute "u" Uacute))
+ (ucircumflex 251 (circumflex "u" Ucircumflex))
+ (udiaeresis 252 (diaeresis "u" Udiaeresis))
+ (yacute 253 (acute "y" Yacute))
+ (thorn 254 (letter "th" THORN))
+ (ydiaeresis 255 (diaeresis "y" Ydiaeresis)))
+ "Table for registry \"iso8859-1\", see `x-symbol-init-cset'.")
+
+(defvar x-symbol-latin2-table
+ '((nobreakspace 160 . t)
+ (Aogonek 161 (ogonek "A" aogonek))
+ (breve 162 (breve accent))
+ (Lslash 163 (slash "L" lslash))
+ (currency 164 . t)
+ (Lcaron 165 (caron "L" lcaron))
+ (Sacute 166 (acute "S" sacute))
+ (section 167 . t)
+ (diaeresis 168 . t)
+ (Scaron 169 (caron "S" scaron))
+ (Scedilla 170 (cedilla "S" scedilla))
+ (Tcaron 171 (caron "T" tcaron))
+ (Zacute 172 (acute "Z" zacute))
+ (hyphen 173 . t)
+ (Zcaron 174 (caron "Z" zcaron))
+ (Zdotaccent 175 (dotaccent "Z" zdotaccent))
+ (degree 176 . t)
+ (aogonek 177 (ogonek "a" Aogonek))
+ (ogonek 178 (ogonek accent))
+ (lslash 179 (slash "l" Lslash))
+ (acute 180 . t)
+ (lcaron 181 (caron "l" Lcaron))
+ (sacute 182 (acute "s" Sacute))
+ (caron 183 (caron accent) (shift up))
+ (cedilla 184 . t)
+ (scaron 185 (caron "s" Scaron))
+ (scedilla 186 (cedilla "s" Scedilla))
+ (tcaron 187 (caron "t" Tcaron))
+ (zacute 188 (acute "z" Zacute))
+ (hungarumlaut 189 (hungarumlaut accent))
+ (zcaron 190 (caron "z" Zcaron))
+ (zdotaccent 191 (dotaccent "z" Zdotaccent))
+ (Racute 192 (acute "R" racute))
+ (Aacute 193 . t)
+ (Acircumflex 194 . t)
+ (Abreve 195 (breve "A" abreve))
+ (Adiaeresis 196 . t)
+ (Lacute 197 (acute "L" lacute))
+ (Cacute 198 (acute "C" cacute))
+ (Ccedilla 199 . t)
+ (Ccaron 200 (caron "C" ccaron))
+ (Eacute 201 . t)
+ (Eogonek 202 (ogonek "E" eogonek))
+ (Ediaeresis 203 . t)
+ (Ecaron 204 (caron "E" ecaron))
+ (Iacute 205 . t)
+ (Icircumflex 206 . t)
+ (Dcaron 207 (caron "D" dcaron))
+ (Dbar 208 (slash "D" dbar))
+ (Nacute 209 (acute "N" nacute))
+ (Ncaron 210 (caron "N" ncaron))
+ (Oacute 211 . t)
+ (Ocircumflex 212 . t)
+ (Ohungarumlaut 213 (hungarumlaut "O" ohungarumlaut))
+ (Odiaeresis 214 . t)
+ (multiply 215 . t)
+ (Rcaron 216 (caron "R" rcaron))
+ (Uring 217 (ring "U" uring))
+ (Uacute 218 . t)
+ (Uhungarumlaut 219 (hungarumlaut "U" uhungarumlaut))
+ (Udiaeresis 220 . t)
+ (Yacute 221 . t)
+ (Tcedilla 222 (cedilla "T" tcedilla))
+ (ssharp 223 . t)
+ (racute 224 (acute "r" Racute))
+ (aacute 225 . t)
+ (acircumflex 226 . t)
+ (abreve 227 (breve "a" Abreve))
+ (adiaeresis 228 . t)
+ (lacute 229 (acute "l" Lacute))
+ (cacute 230 (acute "c" Cacute))
+ (ccedilla 231 . t)
+ (ccaron 232 (caron "c" Ccaron))
+ (eacute 233 . t)
+ (eogonek 234 (ogonek "e" Eogonek))
+ (ediaeresis 235 . t)
+ (ecaron 236 (caron "e" Ecaron))
+ (iacute 237 . t)
+ (icircumflex 238 . t)
+ (dcaron 239 (caron "d" Dcaron))
+ (dbar 240 (slash "d" Dbar))
+ (nacute 241 (acute "n" Nacute))
+ (ncaron 242 (caron "n" Ncaron))
+ (oacute 243 . t)
+ (ocircumflex 244 . t)
+ (ohungarumlaut 245 (hungarumlaut "o" Ohungarumlaut))
+ (odiaeresis 246 . t)
+ (division 247 . t)
+ (rcaron 248 (caron "r" Rcaron))
+ (uring 249 (ring "u" Uring))
+ (uacute 250 . t)
+ (uhungarumlaut 251 (hungarumlaut "u" Uhungarumlaut))
+ (udiaeresis 252 . t)
+ (yacute 253 . t)
+ (tcedilla 254 (cedilla "t" Tcedilla))
+ (dotaccent 255 (dotaccent accent) (shift up)))
+ "Table for registry \"iso8859-2\", see `x-symbol-init-cset'.")
+
+(defvar x-symbol-latin3-table
+ '((nobreakspace 160 . t)
+ (Hbar 161 (slash "H" hbar))
+ (breve 162 . t)
+ (sterling 163 . t)
+ (currency 164 . t)
+ (unused-l3/165 165 . unused)
+ (Hcircumflex 166 (circumflex "H" hcircumflex))
+ (section 167 . t)
+ (diaeresis 168 . t)
+ (Idotaccent 169 (dotaccent "I" dotlessi))
+ (Scedilla 170 . t)
+ (Gbreve 171 (breve "G" gbreve))
+ (Jcircumflex 172 (circumflex "J" jcircumflex))
+ (hyphen 173 . t)
+ (unused-l3/174 174 . unused)
+ (Zdotaccent 175 . t)
+ (degree 176 . t)
+ (hbar 177 (slash "h" Hbar))
+ (twosuperior 178 . t)
+ (threesuperior 179 . t)
+ (acute 180 . t)
+ (mu1 181 . t)
+ (hcircumflex 182 (circumflex "h" hcircumflex))
+ (periodcentered 183 . t)
+ (cedilla 184 . t)
+ (dotlessi 185 (dotaccent "i" Idotaccent))
+ (scedilla 186 . t)
+ (gbreve 187 (breve "g" Gbreve))
+ (jcircumflex 188 (circumflex "j" Jcircumflex))
+ (onehalf 189 . t)
+ (unused-l3/190 190 . unused)
+ (zdotaccent 191 . t)
+ (Agrave 192 . t)
+ (Aacute 193 . t)
+ (Acircumflex 194 . t)
+ (unused-l3/195 195 . unused)
+ (Adiaeresis 196 . t)
+ (Cdotaccent 197 (dotaccent "C" cdotaccent))
+ (Ccircumflex 198 (circumflex "C" ccircumflex))
+ (Ccedilla 199 . t)
+ (Egrave 200 . t)
+ (Eacute 201 . t)
+ (Ecircumflex 202 . t)
+ (Ediaeresis 203 . t)
+ (Igrave 204 . t)
+ (Iacute 205 . t)
+ (Icircumflex 206 . t)
+ (Idiaeresis 207 . t)
+ (unused-l3/208 208 . unused)
+ (Ntilde 209 . t)
+ (Ograve 210 . t)
+ (Oacute 211 . t)
+ (Ocircumflex 212 . t)
+ (Gdotaccent 213 (dotaccent "G" gdotaccent))
+ (Odiaeresis 214 . t)
+ (multiply 215 . t)
+ (Gcircumflex 216 (circumflex "G" gcircumflex))
+ (Ugrave 217 . t)
+ (Uacute 218 . t)
+ (Ucircumflex 219 . t)
+ (Udiaeresis 220 . t)
+ (Ubreve 221 (breve "U" ubreve))
+ (Scircumflex 222 (circumflex "S" scircumflex))
+ (ssharp 223 . t)
+ (agrave 224 . t)
+ (aacute 225 . t)
+ (acircumflex 226 . t)
+ (unused-l3/227 227 . unused)
+ (adiaeresis 228 . t)
+ (cdotaccent 229 (dotaccent "c" Cdotaccent))
+ (ccircumflex 230 (circumflex "c" Ccircumflex))
+ (ccedilla 231 . t)
+ (egrave 232 . t)
+ (eacute 233 . t)
+ (ecircumflex 234 . t)
+ (ediaeresis 235 . t)
+ (igrave 236 . t)
+ (iacute 237 . t)
+ (icircumflex 238 . t)
+ (idiaeresis 239 . t)
+ (unused-l3/240 240 . unused)
+ (ntilde 241 . t)
+ (ograve 242 . t)
+ (oacute 243 . t)
+ (ocircumflex 244 . t)
+ (gdotaccent 245 (dotaccent "g" Gdotaccent))
+ (odiaeresis 246 . t)
+ (division 247 . t)
+ (gcircumflex 248 (circumflex "g" Gcircumflex))
+ (ugrave 249 . t)
+ (uacute 250 . t)
+ (ucircumflex 251 . t)
+ (udiaeresis 252 . t)
+ (ubreve 253 (breve "u" Ubreve))
+ (scircumflex 254 (circumflex "s" Scircumflex))
+ (dotaccent 255 . t))
+ "Table for registry \"iso8859-3\", see `x-symbol-init-cset'.")
+
+(defvar x-symbol-latin5-table
+ '((nobreakspace 160 . t)
+ (exclamdown 161 . t)
+ (cent 162 . t)
+ (sterling 163 . t)
+ (currency 164 . t)
+ (yen 165 . t)
+ (brokenbar 166 . t)
+ (section 167 . t)
+ (diaeresis 168 . t)
+ (copyright 169 . t)
+ (ordfeminine 170 . t)
+ (guillemotleft 171 . t)
+ (notsign 172 . t)
+ (hyphen 173 . t)
+ (registered 174 . t)
+ (macron 175 . t)
+ (degree 176 . t)
+ (plusminus 177 . t)
+ (twosuperior 178 . t)
+ (threesuperior 179 . t)
+ (acute 180 . t)
+ (mu1 181 . t)
+ (paragraph 182 . t)
+ (periodcentered 183 . t)
+ (cedilla 184 . t)
+ (onesuperior 185 . t)
+ (masculine 186 . t)
+ (guillemotright 187 . t)
+ (onequarter 188 . t)
+ (onehalf 189 . t)
+ (threequarters 190 . t)
+ (questiondown 191 . t)
+ (Agrave 192 . t)
+ (Aacute 193 . t)
+ (Acircumflex 194 . t)
+ (Atilde 195 . t)
+ (Adiaeresis 196 . t)
+ (Aring 197 . t)
+ (AE 198 . t)
+ (Ccedilla 199 . t)
+ (Egrave 200 . t)
+ (Eacute 201 . t)
+ (Ecircumflex 202 . t)
+ (Ediaeresis 203 . t)
+ (Igrave 204 . t)
+ (Iacute 205 . t)
+ (Icircumflex 206 . t)
+ (Idiaeresis 207 . t)
+ (Gbreve 208 . t)
+ (Ntilde 209 . t)
+ (Ograve 210 . t)
+ (Oacute 211 . t)
+ (Ocircumflex 212 . t)
+ (Otilde 213 . t)
+ (Odiaeresis 214 . t)
+ (multiply 215 . t)
+ (Ooblique 216 . t)
+ (Ugrave 217 . t)
+ (Uacute 218 . t)
+ (Ucircumflex 219 . t)
+ (Udiaeresis 220 . t)
+ (Idotaccent 221 . t)
+ (Scedilla 222 . t)
+ (ssharp 223 . t)
+ (agrave 224 . t)
+ (aacute 225 . t)
+ (acircumflex 226 . t)
+ (atilde 227 . t)
+ (adiaeresis 228 . t)
+ (aring 229 . t)
+ (ae 230 . t)
+ (ccedilla 231 . t)
+ (egrave 232 . t)
+ (eacute 233 . t)
+ (ecircumflex 234 . t)
+ (ediaeresis 235 . t)
+ (igrave 236 . t)
+ (iacute 237 . t)
+ (icircumflex 238 . t)
+ (idiaeresis 239 . t)
+ (gbreve 240 . t)
+ (ntilde 241 . t)
+ (ograve 242 . t)
+ (oacute 243 . t)
+ (ocircumflex 244 . t)
+ (otilde 245 . t)
+ (odiaeresis 246 . t)
+ (division 247 . t)
+ (oslash 248 . t)
+ (ugrave 249 . t)
+ (uacute 250 . t)
+ (ucircumflex 251 . t)
+ (udiaeresis 252 . t)
+ (dotlessi 253 . t)
+ (scedilla 254 . t)
+ (ydiaeresis 255 . t))
+ "Table for registry \"iso8859-9\", see `x-symbol-init-cset'.")
+
+(defvar x-symbol-latin9-table
+ '((nobreakspace 160 . t)
+ (exclamdown 161 . t)
+ (cent 162 . t)
+ (sterling 163 . t)
+ (euro 164 (currency "C") nil nil ("C="))
+ (yen 165 . t)
+ (Scaron 166 . t) ; latin-2
+ (section 167 . t)
+ (scaron 168 . t) ; latin-2
+ (copyright 169 . t)
+ (ordfeminine 170 . t)
+ (guillemotleft 171 . t)
+ (notsign 172 . t)
+ (hyphen 173 . t)
+ (registered 174 . t)
+ (macron 175 . t)
+ (degree 176 . t)
+ (plusminus 177 . t)
+ (twosuperior 178 . t)
+ (threesuperior 179 . t)
+ (Zcaron 180 . t) ; latin-2
+ (mu1 181 . t)
+ (paragraph 182 . t)
+ (periodcentered 183 . t)
+ (zcaron 184 . t) ; latin-2
+ (onesuperior 185 . t)
+ (masculine 186 . t)
+ (guillemotright 187 . t)
+ (OE 188 (letter "OE" oe))
+ (oe 189 (letter "oe" OE))
+ (Ydiaeresis 190 (diaeresis "Y" ydiaeresis))
+ (questiondown 191 . t)
+ (Agrave 192 . t)
+ (Aacute 193 . t)
+ (Acircumflex 194 . t)
+ (Atilde 195 . t)
+ (Adiaeresis 196 . t)
+ (Aring 197 . t)
+ (AE 198 . t)
+ (Ccedilla 199 . t)
+ (Egrave 200 . t)
+ (Eacute 201 . t)
+ (Ecircumflex 202 . t)
+ (Ediaeresis 203 . t)
+ (Igrave 204 . t)
+ (Iacute 205 . t)
+ (Icircumflex 206 . t)
+ (Idiaeresis 207 . t)
+ (ETH 208 . t)
+ (Ntilde 209 . t)
+ (Ograve 210 . t)
+ (Oacute 211 . t)
+ (Ocircumflex 212 . t)
+ (Otilde 213 . t)
+ (Odiaeresis 214 . t)
+ (multiply 215 . t)
+ (Ooblique 216 . t)
+ (Ugrave 217 . t)
+ (Uacute 218 . t)
+ (Ucircumflex 219 . t)
+ (Udiaeresis 220 . t)
+ (Yacute 221 . t)
+ (THORN 222 . t)
+ (ssharp 223 . t)
+ (agrave 224 . t)
+ (aacute 225 . t)
+ (acircumflex 226 . t)
+ (atilde 227 . t)
+ (adiaeresis 228 . t)
+ (aring 229 . t)
+ (ae 230 . t)
+ (ccedilla 231 . t)
+ (egrave 232 . t)
+ (eacute 233 . t)
+ (ecircumflex 234 . t)
+ (ediaeresis 235 . t)
+ (igrave 236 . t)
+ (iacute 237 . t)
+ (icircumflex 238 . t)
+ (idiaeresis 239 . t)
+ (eth 240 . t)
+ (ntilde 241 . t)
+ (ograve 242 . t)
+ (oacute 243 . t)
+ (ocircumflex 244 . t)
+ (otilde 245 . t)
+ (odiaeresis 246 . t)
+ (division 247 . t)
+ (oslash 248 . t)
+ (ugrave 249 . t)
+ (uacute 250 . t)
+ (ucircumflex 251 . t)
+ (udiaeresis 252 . t)
+ (yacute 253 . t)
+ (thorn 254 . t)
+ (ydiaeresis 255 . t))
+ "Table for registry \"iso8859-15\", see `x-symbol-init-cset'.")
+
+(defvar x-symbol-xsymb0-table
+ '(;;(exclam1 33) ; Adobe:exclam
+ ;;(universal 34 (symbol) nil nil ("A"))
+ (numbersign1 35 (symbol) nil nil ("#")) ; Adobe:numbersign, TeX
+ ;;(existential 36 (symbol) nil nil ("E"))
+ ;;(percent1 37 (symbol) nil nil ("%")) ; Adobe:percent
+ ;;(ampersand1 38 (symbol) nil nil ("&"))
+ (suchthat 39 (relation) (direction east . element) nil ("-)"))
+ ;;(parenleft1 40) ; Adobe:parenleft
+ ;;(parenright1 41) ; Adobe:parenright
+ (asterisk1 42 (operator) nil nil ("*")) ; Adobe:asteriskmath
+ ;;(plus1 43) ; Adobe:plus
+ ;;(comma1 44 (quote) nil (",")) ; Adobe:comma
+ (minus1 45 (operator) nil nil ("-")) ; Adobe:minus
+ (period1 46 (dots) nil nil (".")) ; Adobe:period
+ ;;(slash1 47) ; Adobe:slash
+ ;; 48..57 = ascii 0-9
+ (colon1 58 (dots) nil nil (":")) ; Adobe:colon, TeX
+ ;;(semicolon1 59) ; Adobe:semicolon
+ ;;(less1 60 (relation) (direction west . greater1) nil ("<"))
+ ;;(equal1 61) ; Adobe:equal
+ ;;(greater1 62 (relation) (direction east) nil (">"))
+ ;;(question1 63) ; Adobe:question
+ (congruent 64 (relation) nil nil (t "~="))
+ (Delta 68 (greek "D" delta "Delta"))
+ (Phi 70 (greek "F" phi "Phi"))
+ (Gamma 71 (greek "G" gamma "Gamma"))
+ (theta1 74 (greek1 "q" Theta "theta"))
+ (Lambda 76 (greek "L" lambda "Lambda"))
+ (Pi 80 (greek "P" pi "Pi"))
+ (Theta 81 (greek "Q" theta "Theta"))
+ (Sigma 83 (greek "S" sigma "Sigma"))
+ (sigma1 86 (greek1 "s" Sigma "sigma"))
+ (Omega 87 (greek "W" omega "Omega"))
+ (Xi 88 (greek "X" xi "Xi"))
+ (Psi 89 (greek "Y" psi "Psi"))
+ ;;(bracketleft1 91) ; Adobe:bracketleft
+ ;;(therefore 92 (dots) (direction nil . ellipsis) nil (".:"))
+ ;;(bracketright1 93) ; Adobe:bracketright
+ (perpendicular 94 (arrow) (direction north) nil (t "_|_")) ; (TeX)
+ (underscore1 95 (line) nil nil ("_")) ; Adobe:underscore, TeX
+ (radicalex 96 (line) (shift up) nil ("-^" "^-"))
+ (alpha 97 (greek "a" nil "alpha"))
+ (beta 98 (greek "b" nil "beta"))
+ (chi 99 (greek "c" nil "chi"))
+ (delta 100 (greek "d" Delta "delta"))
+ (epsilon 101 (greek "e" nil "epsilon"))
+ (phi 102 (greek "f" Phi "phi"))
+ (gamma 103 (greek "g" Gamma "gamma"))
+ (eta 104 (greek "h" nil "eta"))
+ (iota 105 (greek "i" nil "iota"))
+ (phi1 106 (greek1 "f" Phi "phi"))
+ (kappa 107 (greek "k" nil "kappa"))
+ (lambda 108 (greek "l" Lambda "lambda"))
+ (mu 109 (greek "m" nil "mu"))
+ (nu 110 (greek "n" nil "nu"))
+ (pi 112 (greek "p" Pi "pi"))
+ (theta 113 (greek "q" Theta "theta"))
+ (rho 114 (greek "r" nil "rho"))
+ (sigma 115 (greek "s" Sigma "sigma"))
+ (tau 116 (greek "t" nil "tau"))
+ (upsilon 117 (greek "u" Upsilon1 "upsilon"))
+ (omega1 118 (greek1 "w" Omega "omega"))
+ (omega 119 (greek "w" Omega "omega"))
+ (xi 120 (greek "x" Xi "xi"))
+ (psi 121 (greek "y" Psi "psi"))
+ (zeta 122 (greek "z" nil "zeta"))
+;;; (braceleft1 123 (parenthesis open braceright1)
+;;; (direction west . braceright1) nil ("{"))
+ (bar1 124 (line) brokenbar 120 ("|")) ; Adobe:bar, TeX
+;;; (braceright1 125 (parenthesis close braceleft1) (direction east) nil ("}"))
+ (similar 126 (relation) nil nil ("~"))
+ (Upsilon1 161 (greek1 "U" upsilon "Upsilon"))
+ (minute 162 (symbol) nil nil ("'"))
+ (lessequal 163 (relation) (direction west . greaterequal) nil (t "<_"))
+ (fraction 164 (operator) nil nil ("/"))
+ (infinity 165 (symbol) nil nil ("oo"))
+ (florin 166 (currency "f") nil nil ("f"))
+ (club 167 (shape) (direction north . diamond) nil ("{#}"))
+ (diamond 168 (shape) (direction east . lozenge) nil ("<#>"))
+ (heart 169 (shape) (direction south . diamond) nil ("(#)"))
+ (spade 170 (shape) (direction west . diamond) nil ("/#\\"))
+ (arrowboth 171 (arrow) (direction horizontal . arrowright) nil
+ (t "<->") (arrowleft))
+ (arrowleft 172 (arrow) (direction west . arrowright) nil (t "<-"))
+ (arrowup 173 (arrow) (direction north . arrowright) nil ("|^"))
+ (arrowright 174 (arrow) (direction east) nil (t "->"))
+ (arrowdown 175 (arrow) (direction south . arrowright) nil ("|v"))
+ (ring 176 (ring accent)) ; Adobe:degree, TeX
+ ;;(plusminus1 177) ; Adobe:plusminus
+ (second 178 (symbol) nil nil ("''")) ; NEW
+ (greaterequal 179 (relation) (direction east) nil (t ">_"))
+ ;;(times1 180) ; Adobe:times
+ (proportional 181 (relation) nil nil ("oc"))
+ (partialdiff 182 (mathletter "d"))
+ (bullet 183 (operator) nil 240 ("*"))
+ ;;(divide1 184) ; Adobe:divide
+ (notequal 185 (relation) nil nil (t "=/"))
+ (equivalence 186 (relation) nil nil (t "=_"))
+ (approxequal 187 (relation) nil nil (t "~~"))
+ (ellipsis 188 (dots) (direction east) nil (t "..."))
+ ;;(arrowhorizex 190 (line) (size big) nil ("-"))
+ (carriagereturn 191 (arrow) (direction west) nil ("<-|")) ; NEW
+ (aleph 192 (mathletter "N"))
+ (Ifraktur 193 (mathletter "I"))
+ (Rfraktur 194 (mathletter "R"))
+ (weierstrass 195 (mathletter "P"))
+ (circlemultiply 196 (operator) nil nil (t "xO") (multiply))
+ (circleplus 197 (operator) nil nil (t "+O"))
+ (emptyset 198 (shape) nil nil ("0/" "O/"))
+ (intersection 199 (operator) (shape round . logicaland))
+ (union 200 (operator) (shape round . logicalor))
+ (propersuperset 201 (relation) (direction east . union) nil (">"))
+ (reflexsuperset 202 (relation) (shape round . greaterequal) nil
+ nil (propersuperset))
+ (notsubset 203 (relation) (shape round direction west) nil
+ ("</") (propersubset))
+ (propersubset 204 (relation) (direction west . propersuperset) nil ("<"))
+ (reflexsubset 205 (relation) (shape round . lessequal) nil
+ nil (propersubset))
+ (element 206 (relation) (direction west) nil ("(-"))
+ (notelement 207 (relation) (direction west) nil (t "(-/") (element))
+ (angle 208 (symbol) nil nil ("/_"))
+ (gradient 209 (triangle) (direction south . Delta) nil (t "\\-/"))
+ ;;(register1 210) ; Adobe:registerserif
+ ;;(copyright1 211) ; Adobe:copyrightserif
+ ;;(trademark1 212) ; Adobe:trademarkserif
+ (product 213 (bigop) (size big . Pi) nil ("TT"))
+ (radical 214 (symbol) nil nil ("v/"))
+ (periodcentered1 215 (dots) periodcentered 120) ; Adobe:dotmath, (TeX)
+ ;;(logicalnot1 216) ; Adobe:logicalnot
+ (logicaland 217 (operator) (direction north . logicalor) nil (t "/\\"))
+ (logicalor 218 (operator) (direction south) nil (t "\\/"))
+ (arrowdblboth 219 (arrow) (direction horizontal . arrowdblright) nil
+ (t "<=>") (arrowdblleft))
+ (arrowdblleft 220 (arrow) (direction west . arrowdblright) nil (t "<="))
+ (arrowdblup 221 (arrow) (direction north . arrowdblright) nil ("||^"))
+ (arrowdblright 222 (arrow) (direction east) nil (t "=>"))
+ (arrowdbldown 223 (arrow) (direction south . arrowdblright) nil ("||v"))
+ (lozenge 224 (shape) nil nil ("<>"))
+ (angleleft 225 (parenthesis open angleright)
+ (direction west . angleright) 120 ("{"))
+ ;;(registered2 226) ; Adobe:registersans
+ ;;(copyright2 227) ; Adobe:copyrightsans
+ (trademark 228 (symbol "T") nil nil ("TM")) ; Adobe:trademarksans
+ (summation 229 (bigop) (size big . Sigma))
+ (angleright 241 (parenthesis close angleleft) (direction east) 120 ("}"))
+ (integral 242 (bigop) (size big) nil (t "|'")))
+ "Table for registry \"fontspecific\", see `x-symbol-init-cset'.")
+
+(defvar x-symbol-xsymb1-table
+ '((verticaldots 33 (dots) (direction north . ellipsis) nil (":."))
+ (backslash1 34 (line) nil nil ("\\"))
+ (dagger 35 (symbol) (direction north) nil ("|+"))
+ ;;(unused36 36)
+ ;;(unused36 37)
+ (percent2 38 (symbol) nil nil ("%"))
+ (guilsinglright 39 (quote close guilsinglleft) (direction east) 3000 (">"))
+ ; should be after the relations
+ (NG 40 (letter "NG" ng))
+ ;;(OE 41 (letter "OE" oe)) ; now latin-9
+ (dotlessj 42 (dotaccent "j" nil))
+ (ng 43 (letter "ng" NG))
+ ;;(oe 44 (letter "oe" OE)) ; now latin-9
+ (sharp 45 (symbol) nil nil ("#"))
+ (ceilingleft 46 (parenthesis open ceilingright) (shift up . floorleft)
+ nil ("["))
+ (ceilingright 47 (parenthesis close ceilingleft) (shift up . floorright)
+ nil ("]"))
+ (zero1 48 (digit1 "0"))
+ (one1 49 (digit1 "1"))
+ (two1 50 (digit1 "2"))
+ (three1 51 (digit1 "3"))
+ (four1 52 (digit1 "4"))
+ (five1 53 (digit1 "5"))
+ (six1 54 (digit1 "6"))
+ (seven1 55 (digit1 "7"))
+ (eight1 56 (digit1 "8"))
+ (nine1 57 (digit1 "9"))
+ (star 58 (operator) nil nil ("*"))
+ (lozenge1 59 (shape) lozenge -240 ("<>"))
+ (braceleft2 60 (parenthesis open braceright2)
+ (direction west . braceright2) nil ("{"))
+ (circleslash 61 (operator) nil nil ("/O"))
+ (braceright2 62 (parenthesis close braceleft2) (direction east) nil ("}"))
+ (triangle1 63 (triangle) triangle 120)
+ (smltriangleright 64 (triangle) (size sml . triangleright))
+ (triangleleft 65 (triangle) (direction west . gradient) nil ("<|"))
+ (triangle 66 (triangle) (direction north . gradient) nil (t "/_\\"))
+ (triangleright 67 (triangle) (direction east . gradient) nil ("|>"))
+ (trianglelefteq 68 (triangle) (direction west . trianglerighteq) nil
+ ("<|_") (triangleleft))
+ (trianglerighteq 69 (triangle) (direction east) nil ("|>_") (triangleright))
+ (periodcentered2 70 (dots) periodcentered 240)
+ (dotequal 71 (relation) nil nil ("=."))
+ (wrong 72 (relation) (direction south . similar) 1500 ("~"))
+ (natural 73 (symbol) nil 120 ("#"))
+ (flat 74 (symbol) nil nil ("b"))
+ (epsilon1 75 (greek1 "e" nil "epsilon"))
+ (hbarmath 76 (mathletter "h"))
+ (imath 77 (mathletter "i"))
+ (kappa1 78 (greek1 "k" nil "kappa"))
+ (jmath 79 (mathletter "j"))
+ (ell 80 (mathletter "l"))
+ (amalg 81 (bigop) (size sml . coproduct))
+ (rho1 82 (greek1 "r" nil "rho"))
+ (top 83 (arrow) (direction south . perpendicular) nil ("T"))
+ (Mho 84 (greek1 "M" nil "Mho") (direction south . Omega))
+ (floorleft 85 (parenthesis open floorright) (direction west . floorright)
+ nil ("["))
+ (floorright 86 (parenthesis close floorleft) (direction east) nil ("]"))
+ (perpendicular1 87 (arrow) perpendicular 120)
+ (box 88 (shape) nil nil ("[]"))
+ (asciicircum1 89 (symbol) nil nil ("^"))
+ (asciitilde1 90 (symbol) nil nil ("~"))
+ (leadsto 91 (arrow) (direction east) nil ("~>"))
+ (quotedbl1 92 (quote) nil nil ("\""))
+ (longarrowleft 93 (arrow) (size big . arrowleft) nil
+ ("<-" t "<--") (arrowleft))
+ (arrowupdown 94 (arrow) (direction vertical . arrowright) nil
+ ("|v^" "|^v") (arrowup arrowdown))
+ (longarrowright 95 (arrow) (size big . arrowright) nil
+ ("->" t "-->") (emdash))
+ (longmapsto 96 (arrow) (size big . mapsto) nil ("|->" t "|-->"))
+ (longarrowdblboth 97 (arrow) (size big . arrowdblboth) nil ("<=>" t "<==>")
+ (longarrowdblleft))
+ (longarrowdblleft 98 (arrow) (size big . arrowdblleft) nil ("<=" t "<==")
+ (arrowdblleft))
+ (arrowdblupdown 99 (arrow) (direction vertical . arrowdblright) nil
+ ("||v^" "||^v") (arrowdblup arrowdbldown))
+ (longarrowdblright 100 (arrow) (size big . arrowdblright) nil
+ ("=>" t "==>"))
+ (mapsto 101 (arrow) (direction east) nil (t "|->"))
+ (iff 102 (arrow) longarrowdblboth 120)
+ (hookleftarrow 103 (arrow) (direction west . hookrightarrow) nil
+ ("<-`") (leftarrow))
+ (hookrightarrow 104 (arrow) (direction east) nil ("'->") (leftharpoonup))
+ (arrownortheast 105 (arrow) (direction north-east . arrowright) nil ("/>"))
+ (arrowsoutheast 106 (arrow) (direction south-east . arrowright) nil ("\\>"))
+ (arrownorthwest 107 (arrow) (direction north-west . arrowright) nil ("\\<"))
+ (arrowsouthwest 108 (arrow) (direction south-west . arrowright) nil ("/<"))
+ (rightleftharpoons 109 (arrow) (direction horizontal . rightharpoonup) nil
+ (",=`"))
+ (leftharpoondown 110 (arrow) (direction south-west . rightharpoondown) nil
+ (",-"))
+ (rightharpoondown 111 (arrow) (direction south-east . rightharpoonup) nil
+ ("-,"))
+ (leftharpoonup 112 (arrow) (direction north-west . rightharpoonup) nil
+ ("'-"))
+ (rightharpoonup 113 (arrow) (direction north-east) nil ("-`"))
+ (bardbl 114 (line) (direction east) nil (t "||"))
+ (bardbl1 115 (line) bardbl 120 nil (bar1))
+ (backslash2 116 (line) nil 240 ("\\"))
+ (backslash3 117 (line) nil 120 ("\\"))
+ (diagonaldots 118 (dots) (direction south-east . ellipsis) 300 (":."))
+ (simequal 119 (relation) nil nil (t "~_") (similar))
+ (digamma 120 (mathletter "F"))
+ (asym 121 (relation) (direction vertical . smile) nil (">=<"))
+ (minusplus 122 (operator) (direction south . plusminus) nil (t "-+"))
+ (less2 123 (relation) (direction west . greater2) nil ("<")) ; SGML
+ (bowtie 124 (triangle) (direction horizontal . triangle) nil ("|X|"))
+ (greater2 125 (relation) (direction east) nil (">")) ; SGML
+ (centraldots 126 (dots) (shift up . ellipsis))
+ (visiblespace 160 (white) nil nil ("_" ",_," " "))
+ (dagger1 161 (symbol) dagger 120)
+ (circledot 162 (operator) nil nil (t ".O") (periodcentered))
+ (propersqsuperset 163 (relation) (shape square . propersuperset))
+ (reflexsqsuperset 164 (relation) (shape square . reflexsuperset) nil
+ nil (propersuperset))
+ (gradient1 165 (triangle) gradient 120)
+ (propersqsubset 166 (relation) (shape square . propersubset) nil ("<"))
+ (reflexsqsubset 167 (relation) (shape square . reflexsubset) nil
+ nil (propersqsubset))
+ (smllozenge 168 (shape) (size sml . lozenge))
+ (lessless 169 (relation) (direction west . greatergreater) nil ("<<"))
+ (greatergreater 170 (relation) (direction east) nil (">>"))
+ (unionplus 171 (operator) (shape round direction south) nil
+ (t "\\/+") (union))
+ (sqintersection 172 (operator) (shape square . logicaland))
+ (squnion 173 (operator) (shape square . logicalor))
+ (frown 174 (relation) (direction north . smile) nil (",-,"))
+ (smile 175 (relation) (direction south) nil ("`-'"))
+ (reflexprec 176 (relation) (shape curly . lessequal) nil nil (properprec))
+ (reflexsucc 177 (relation) (shape curly . greaterequal) nil nil
+ (propersucc))
+ (properprec 178 (relation) (shape curly . propersubset))
+ (propersucc 179 (relation) (shape curly . propersuperset))
+ (bardash 180 (arrow) (direction east . perpendicular) nil ("|-"))
+ (dashbar 181 (arrow) (direction west . perpendicular) nil ("-|"))
+ (bardashdbl 182 (arrow) (direction east) nil ("|="))
+ (smlintegral 183 (bigop) (size sml . integral))
+ (circleintegral 184 (bigop) (size big) nil (t "|'O") (integral))
+ (coproduct 185 (bigop) (direction south . product) nil (t "|_|"))
+ (bigcircledot 186 (bigop) (size big . circledot))
+ (bigcirclemultiply 187 (bigop) (size big . circlemultiply))
+ (bigcircleplus 188 (bigop) (size big . circleplus))
+ (biglogicaland 189 (bigop) (size big . logicaland))
+ (biglogicalor 190 (bigop) (size big . logicalor))
+ (bigintersection 191 (bigop) (size big . intersection))
+ (bigunion 192 (bigop) (size big . union))
+ (bigunionplus 193 (bigop) (size big . unionplus) nil nil (bigunion))
+ (bigsqunion 194 (bigop) (size big . squnion))
+ (bigcircle 195 (operator) (size big . circ) nil ("O"))
+;;; (quotedblbase 196 (quote) (shift down) nil ("\""))
+;;; (quotedblleft 197 (quote open quotedblright)
+;;; (direction west . quotedblright) nil ("``"))
+;;; (quotedblright 198 (quote close quotedblleft) (direction east) nil ("''"))
+ (guilsinglleft 196 (quote open guilsinglright)
+ (direction west . guilsinglright) nil ("<"))
+ (circleminus 197 (operator) Theta 120 ("-O"))
+ (smltriangleleft 198 (triangle) (size sml . triangleleft))
+ (perthousand 199 (symbol) nil nil ("%."))
+ (existential1 200 (symbol) nil nil ("E"))
+ (daggerdbl1 201 (symbol) daggerdbl 120 nil (dagger1))
+ (daggerdbl 202 (symbol) (direction vertical . dagger) nil
+ (t "|++") (dagger))
+ (bigbowtie 203 (triangle) (size big . bowtie))
+ (circ 204 (operator) (shift up) nil ("o"))
+ (grave 205 (grave accent))
+ (circumflex 206 (circumflex accent))
+ (tilde 207 (tilde accent))
+ (longarrowboth 208 (arrow) (size big . arrowboth) nil ("<->" t "<-->")
+ (longarrowleft))
+ (endash 209 (line) nil nil ("-" "--")) ; TeX
+ (emdash 210 (line) (size big) nil ("-" "--" "---")) ; TeX
+ ;;(Ydiaeresis 211 (diaeresis "Y" ydiaeresis)) ; now latin-9
+ (ampersand2 212 (symbol) nil nil ("&")) ; TeX, SGML
+ (universal1 213 (symbol) nil nil ("A"))
+ (booleans 214 (setsymbol "B"))
+ (complexnums 215 (setsymbol "C"))
+ (natnums 216 (setsymbol "N"))
+ (rationalnums 217 (setsymbol "Q"))
+ (realnums 218 (setsymbol "R"))
+ (integers 219 (setsymbol "Z"))
+ (lesssim 220 (relation) (direction west . greatersim) nil (t "<~"))
+ (greatersim 221 (relation) (direction east) nil (t ">~"))
+ (lessapprox 222 (relation) (direction west . greaterapprox) nil (t "<~~"))
+ (greaterapprox 223 (relation) (direction east) nil (t ">~~"))
+ (definedas 224 (relation) nil nil (t "/_\\=" "^=") (triangle))
+ (circleminus1 225 (operator) circleminus 240)
+ (circleasterisk 226 (operator) nil nil ("*O") (asterisk1))
+ (circlecirc 227 (operator) nil nil ("oO") (circ))
+ (dollar1 228 (currency "$") nil nil ("$"))
+ ;;(euro 229 (currency "C") nil nil ("C=")) ; now latin-9
+ (therefore1 230 (dots) (direction nil . ellipsis) nil (".:"))
+ (coloncolon 231 (dots) nil nil ("::"))
+ (bigsqintersection 232 (bigop) (size big . sqintersection))
+ (semanticsleft 233 (parenthesis open semanticsright)
+ (direction west . semanticsright) nil ("[[" t "[|"))
+ (semanticsright 234 (parenthesis close semanticsleft)
+ (direction east) nil ("]]" t "|]"))
+ (cataleft 235 (parenthesis open cataright)
+ (direction west . cataright) nil (t "(|"))
+ (cataright 236 (parenthesis close cataleft)
+ (direction east) nil (t "|)"))
+ )
+ "Table for registry \"xsymb1\", see `x-symbol-init-cset'.")
+
+(defvar x-symbol-no-of-charsyms (+ 179 274)) ; latin{1,2,3,5,9}, xsymb{0,1}
+
+
+;;;===========================================================================
+;;; Calling the init code
+;;;===========================================================================
+
+(unless noninteractive
+ ;; necessary for batch compilation of x-symbol-image.el etc. CW: maybe
+ ;; calling the init code here isn't that good after all (see info node
+ ;; "Miscellaneous Questions"), we'll see later...
+ (x-symbol-initialize)
+ (setq x-symbol-all-charsyms nil)
+
+ ;; temp hack for console. TODO: find better ways to prevent warnings etc
+ (unless (console-type)
+ (unless x-symbol-default-coding
+ (warn "X-Symbol: only limited support on a console"))
+ (unless (eq x-symbol-latin-force-use 'console-user)
+ (setq x-symbol-latin1-fonts nil)
+ (setq x-symbol-latin2-fonts nil)
+ (setq x-symbol-latin3-fonts nil)
+ (setq x-symbol-latin5-fonts nil)
+ (setq x-symbol-latin9-fonts nil)
+ (setq x-symbol-xsymb0-fonts nil)
+ (setq x-symbol-xsymb1-fonts nil)))
+
+ (x-symbol-init-cset x-symbol-latin1-cset x-symbol-latin1-fonts
+ x-symbol-latin1-table)
+ (x-symbol-init-cset x-symbol-latin2-cset x-symbol-latin2-fonts
+ x-symbol-latin2-table)
+ (x-symbol-init-cset x-symbol-latin3-cset x-symbol-latin3-fonts
+ x-symbol-latin3-table)
+ (x-symbol-init-cset x-symbol-latin5-cset x-symbol-latin5-fonts
+ x-symbol-latin5-table)
+ (x-symbol-init-cset x-symbol-latin9-cset x-symbol-latin9-fonts
+ x-symbol-latin9-table)
+ (x-symbol-init-latin-decoding)
+
+ (x-symbol-init-cset x-symbol-xsymb0-cset x-symbol-xsymb0-fonts
+ x-symbol-xsymb0-table)
+ (x-symbol-init-cset x-symbol-xsymb1-cset x-symbol-xsymb1-fonts
+ x-symbol-xsymb1-table))
+
+;; (when x-symbol-mule-change-default-face
+;; (set-face-font 'default (face-attribute 'x-symbol-face :font)))
+
+(easy-menu-define x-symbol-menu-map x-symbol-mode-map
+ "X-Symbol menu." x-symbol-menu)
+
+
+;;; Local IspellPersDict: .ispell_xsymb
+;;; x-symbol.el ends here