4 Feb 00:47
unicode-disp.el v.5
Kevin Ryde <user42 <at> zip.com.au>
2012-02-03 23:47:59 GMT
2012-02-03 23:47:59 GMT
This is a bit of a window display table hack I've used for a while to mangle unicode chars to something viewable on a latin1 tty. It's very limited but might inspire other or similar things. Exactly what you want to see for undisplayables tends to be a matter of personal preference and/or how often you strike offending chars. The quote marks are probably the most common nonsense encountered. Multi-char replacements tend to make a mess of table columns etc.
;;; unicode-disp.el --- display-table fallbacks for some unicode chars ;; Copyright 2008, 2009, 2010, 2011, 2012 Kevin Ryde ;; ;; Author: Kevin Ryde <user42 <at> zip.com.au> ;; Version: 5 ;; Keywords: i18n, unicode, display ;; URL: http://user42.tuxfamily.org/unicode-disp/index.html ;; ;; unicode-disp.el 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 3, or (at your option) any later ;; version. ;; ;; unicode-disp.el 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 can get a copy of the GNU General Public License online at ;; <http://www.gnu.org/licenses/>. ;;; Commentary: ;; M-x unicode-disp changes the display table to show some unicode chars as ;; ASCII equivalents or near equivalents. ;; ;; The characters handled are a personal selection of the worst bits of ;; unicode encountered, just with the aim of making them displayable on an ;; ASCII or Latin-1 tty. If nothing else it might give you ideas for ;; display table mangling of your own. ;; ;; See latin1-disp.el for similar display table setups for otherwise ;; undisplayable characters from the iso-8859-N charsets, and some cyrillic. ;; ;; Quite to transform and how prominent it should be is a matter of personal ;; preference. Displaying a char as a sequence like "->" can make text ;; lines come out too long, or tables etc not align, sometimes very badly. ;; A face like `escape-glyph' can make it clear you're looking at non-ascii, ;; except it becomes distracting if the screen is littered with it. ;; ;; The variant hyphens and quotes currently treated by `unicode-disp' are on ;; the whole fairly pointless and might as well display as plain ascii "-" ;; etc as necessary, with no special highlighting. ;;; Emacsen: ;; Designed for Emacs 21 and up, does nothing in XEmacs 21. ;;; Install: ;; Put unicode-disp.el in one of your `load-path' directories, and in your ;; .emacs add ;; ;; (autoload 'unicode-disp "unicode-disp" nil t) ;; (add-hook 'term-setup-hook 'unicode-disp) ;; ;; There's an autoload cookie for the function, if you know how to use ;; `update-file-autoloads' and friends, after which just add or customize ;; the hook (or use M-x unicode-disp when desired). ;;; History: ;; Version 1 - the first version ;; Version 2 - act on window and buffer display tables too ;; Version 3 - express dependency on 'advice rather than maybe reloading it ;; Version 4 - term-setup-hook isn't customizable ;; Version 5 - some more chars ;;; Code: ;; for `ad-find-advice' macro when running uncompiled ;; (don't unload 'advice before our -unload-function) (require 'advice) ;;----------------------------------------------------------------------------- ;; emacs22 new stuff ;; unicode-disp--char-displayable-p (eval-and-compile (if (eval-when-compile (fboundp 'char-displayable-p)) ;; emacs22 up (defalias 'unicode-disp--char-displayable-p 'char-displayable-p) ;; emacs21 (put 'unicode-disp--char-displayable-p 'side-effect-free t) (defun unicode-disp--char-displayable-p (window) "Return non-nil if CHAR can be shown on the current display. It's assumed everything is displayable on X and on a utf8 tty \(if `terminal-coding-system' is utf-8)." (or window-system (eq 'utf-8 (terminal-coding-system)))))) ;; unicode-disp--make-glyph-code (eval-and-compile (if (eval-when-compile (fboundp 'make-glyph-code)) ;; emacs22 up (defalias 'unicode-disp--make-glyph-code 'make-glyph-code) ;; emacs21 (put 'unicode-disp--make-glyph-code 'side-effect-free t) (defun unicode-disp--make-glyph-code (c &optional face) "Return a glyph code for CHAR displayed with FACE." (logior c (* 524288 (if face (face-id face) 0)))))) ;;----------------------------------------------------------------------------- ;; emacs23 new stuff ;; unicode-disp--with-selected-frame (eval-and-compile (if (eval-when-compile (fboundp 'with-selected-frame)) ;; emacs23 up, and xemacs21 (defalias 'unicode-disp--with-selected-frame 'with-selected-frame) ;; emacs21,emacs22 ;; the NO-ENTER parameter in emacs21 gone in emacs22 (defmacro unicode-disp--with-selected-frame (frame &rest body) "Evaluate BODY with FRAME as the `selected-frame'." ;; (declare (debug t)) ;; emacs22,xemacs21, or 'cl `(let ((unicode-disp--with-selected-frame--old (selected-frame))) (unwind-protect (progn (select-frame ,frame) ,@body) (select-frame unicode-disp--with-selected-frame--old)))))) ;;----------------------------------------------------------------------------- (defun unicode-disp-attr-displayable-p (attr &optional display) "Return non-nil if ATTR can be shown on DISPLAY. ATTR is a keyword like :overline. DISPLAY is a display name, a frame, or nil for the selected frame." (cond ((eval-when-compile (fboundp 'display-supports-face-attributes-p)) ;; emacs22 up (display-supports-face-attributes-p (list attr t) display)) ((eval-when-compile (boundp 'face-attribute-name-alist)) ;; emacs21 (assq attr face-attribute-name-alist)) ((progn (eval-and-compile (require 'cus-face)) (eval-when-compile (boundp 'custom-face-attributes))) ;; xemacs21, emacs20 ;; suppose this is all possible attributes, or close enough (assq attr custom-face-attributes)))) (defun unicode-disp-overline-face (&optional display) "Return an overline face for DISPLAY, or nil. If the display can't show an overline face the return is nil. DISPLAY is a display name, a frame, or nil for the selected frame." (when (unicode-disp-attr-displayable-p :overline display) (unless (facep 'unicode-disp-overline) (make-face 'unicode-disp-overline) (set-face-attribute 'unicode-disp-overline nil :overline t)) 'unicode-disp-overline)) ;; is `facep' side-effect-free ? (defun unicode-disp-escape-face () "Return 'escape-glyph if that face exists, otherwise 'default. DISPLAY is a display name, a frame, or nil for the selected frame." (if (facep 'escape-glyph) ;; not in emacs21,xemacs21 'escape-glyph 'default)) (defconst unicode-disp-default-character-list '( (#x2010 "-") ;; HYPHEN (#x2212 "-") ;; MINUS SIGN (#x2014 "-") ;; EM DASH (#x2500 "-" ;; BOX DRAWINGS LIGHT HORIZONTAL unicode-disp-escape-face) (#x2502 "|") ;; BOX DRAWINGS LIGHT VERTICAL ;; (#x250C "+" ;; BOX DRAWINGS LIGHT DOWN AND RIGHT unicode-disp-escape-face) (#x2514 "+" ;; BOX DRAWINGS LIGHT UP AND RIGHT unicode-disp-escape-face) (#x2018 "`") ;; LEFT SINGLE QUOTATION MARK (#x2019 "'") ;; RIGHT SINGLE QUOTATION MARK (#x201C "\"") ;; LEFT DOUBLE QUOTATION MARK (#x201D "\"") ;; RIGHT DOUBLE QUOTATION MARK (#x2190 "<-" ;; LEFTWARDS ARROW unicode-disp-escape-face) (#x2192 "->" ;; RIGHTWARDS ARROW unicode-disp-escape-face) (#x221E "inf" ;; INFINITY unicode-disp-escape-face) (#x25C0 "<" ;; BLACK LEFT-POINTING TRIANGLE unicode-disp-escape-face) (#x25B6 ">" ;; BLACK RIGHT-POINTING TRIANGLE unicode-disp-escape-face) (#x203E " " ;; OVERLINE as face unicode-disp-overline-face))) (defun unicode-disp-table (table) "Apply unicode display to TABLE. TABLE is a display table, or nil to act on as-yet uninitialized `standard-display-table'. The `selected-frame' is used to check which characters are displayable." (dolist (elem unicode-disp-default-character-list) (let* ((char (decode-char 'ucs (nth 0 elem))) (str (nth 1 elem)) (face (nth 2 elem))) (when (and ;; table doesn't already have an entry (not (and table (aref table char))) ;; char not already displayable (not (unicode-disp--char-displayable-p char)) ;; face func returns a face (or (not face) (setq face (funcall face)))) ;; TABLE nil means `standard-display-table', to be initialized by ;; loading disp-table.el (unless table (require 'disp-table) (setq table standard-display-table)) (aset table char (vconcat (mapcar (lambda (c) (unicode-disp--make-glyph-code c face)) str))))))) ;; `window-display-table' noticed through `set-window-display-table' ;; (defadvice set-window-display-table (after unicode-disp activate) "Apply `unicode-disp' character fallbacks to `window-display-table'." ;; in emacs21 `unload-feature' doesn't call `unicode-disp-unload-function' ;; so this advice is left behind, allow for that by checking ;; 'unicode-disp-table' still exists (when (fboundp 'unicode-disp-table) (let ((table (ad-get-arg 1))) ;; args WINDOW TABLE (and table (unicode-disp--with-selected-frame (window-frame window) (unicode-disp-table table)))))) (defun unicode-disp-unload-function () "Remove advice on `set-window-display-table'. This is called by `unload-feature'." (when (ad-find-advice 'set-window-display-table 'after 'unicode-disp) (ad-remove-advice 'set-window-display-table 'after 'unicode-disp) (ad-activate 'set-window-display-table)) nil) ;; and do normal unload-feature actions too ;; `buffer-display-table' noticed under `window-configuration-change-hook' ;; this means only displayed buffers are considered, which may help if ;; there's lots of buffers, but basically there's no good way to notice a ;; plain setq to buffer-display-table anyway ;; (defun unicode-disp-winconf () "Apply `unicode-disp' character fallbacks to `buffer-display-table'. This function is used in `window-configuration-change-hook' to check any buffer display tables in the displayed buffers." ;; in emacs21 `unload-feature' doesn't remove `unicode-disp-winconf' from ;; `window-configuration-change-hook', allow for that by checking ;; 'unicode-disp-table' still exists (when (fboundp 'unicode-disp-table) ;; in case `unload-feature' (dolist (window (window-list nil t)) (when (window-live-p window) ;; dead windows don't have buffers (with-current-buffer (window-buffer window) (if buffer-display-table (unicode-disp-table buffer-display-table))))))) ;;;###autoload (defun unicode-disp () "Setup some display table fallbacks for unicode chars. The display tables are modified to show a few unicode chars as ascii near-equivalents if not otherwise displayable. For example if U+2010 HYPHEN isn't displayable then it's set to plain ascii \"-\". This only affects the screen display, the characters in the buffers are unchanged. `standard-display-table' and current and future `window-display-table' and `buffer-display-table' are acted on. A new setting for a `buffer-display-table' is only noticed on the next window configuration change, which is not really right but usually close enough. ---- The unicode-disp.el home page is URL `http://user42.tuxfamily.org/unicode-disp/index.html'" (interactive) (when (eval-when-compile (boundp 'standard-display-table)) ;; not in xemacs ;; if different frames have different char-displayable-p then might want ;; to mangle the standard table for each to make a lowest denominator, ;; but for now just do it once (can be repeated by M-x unicode-disp) (unicode-disp-table standard-display-table) (dolist (frame (frame-list)) (unicode-disp--with-selected-frame frame ;; initial `window-display-table's (dolist (window (window-list frame t)) (let ((table (window-display-table window))) (if table (unicode-disp-table table)))) ;; initial `buffer-display-table's (unicode-disp-winconf))) ;; future `buffer-display-table's (add-hook 'window-configuration-change-hook 'unicode-disp-winconf))) ;; Might have put `unicode-disp' as a customize option on `term-setup-hook' ;; or similar. But as of Emacs 23 `term-setup-hook' is just a defvar not ;; defcustom. ;; ;; ;;;###autoload ;; (custom-add-option 'term-setup-hook 'unicode-disp) ;; LocalWords: latin overline fallbacks unicode tty disp ascii undisplayable charsets cyrillic iso (provide 'unicode-disp) ;;; unicode-disp.el ends here
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iD8DBQBPKwjkLFMCIV9q3ToRAgw/AJ0T3u+q3TAEkdtGDZ+xPqpHGJwPCgCfSj+G h3Aghb/nLjrRAZ/ffH1ddD4= =r33R -----END PGP SIGNATURE-----
_______________________________________________ gnu-emacs-sources mailing list gnu-emacs-sources <at> gnu.org https://lists.gnu.org/mailman/listinfo/gnu-emacs-sources
RSS Feed