|
Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
;; -*- lexical-binding: nil; -*-
;;; eev-math-glyphs.el -- mathematical glyphs for editing TeX texts in X
;; Copyright (C) 2005,2006,2007,2008 Free Software Foundation, Inc.
;;
;; This file is part of GNU eev.
;;
;; GNU eev 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.
;;
;; GNU eev 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 GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;
;; Author: Eduardo Ochs <eduardoochs@gmail.com>
;; Maintainer: Eduardo Ochs <eduardoochs@gmail.com>
;; Version: 2008jul03
;; Keywords: e-scripts, display, TeX, glyphs.
;;; Commentary:
;; This is immature code, and it is being included in the eev package
;; as an example ONLY! This is only for the addicts to the
;; unibyte/raw-text "encodings", like me. I have tons of TeX'able
;; notes using glyphs like those, and _I KNOW_ that unibyte and glyphs
;; is not the modern way to do things, that this glyphs trick is
;; non-standard as hell, etc etc, you don't need to tell me, _thanks_!
;;
;; By the way: I used to use glyphs like those in (VGA) text mode,
;; using hacked console fonts - I only adapted this thing to X in the
;; beginning of May, 2005. Which means: I haven't even played with it
;; for long enough!
;;
;; See: (find-eev "eev-glyphs.el")
;; (find-eev "eev-compose.el")
;; (find-angg "vtutil4/mathchars.lua")
;; To reload: (load-file "eev-math-glyphs.el")
;; «.faces» (to "faces")
(require 'eev-glyphs)
(require 'eev-compose)
(if (not window-system)
(error "eev-math-glyphs.el is for X only"))
;;; _ _ _ _ _
;;; __| (_)___ _ __ | |_ __ _| |__ | | ___ ___
;;; / _` | / __| '_ \ | __/ _` | '_ \| |/ _ \/ __|
;;; | (_| | \__ \ |_) | | || (_| | |_) | | __/\__ \
;;; \__,_|_|___/ .__/ \__\__,_|_.__/|_|\___||___/
;;; |_|
;;
;; We want to make adding new glyphs a reversible operation, so...
(defvar eev-math-glyphs-standard-display-table-backup nil
"A backup of standard-display-table (before adding user-defined glyphs)")
;; Save a backup of `standard-disply-table' now.
(if (not eev-math-glyphs-standard-display-table-backup)
(setq eev-math-glyphs-standard-display-table-backup
(copy-sequence standard-display-table)))
(defun eev-math-glyphs-reset ()
"Restore the standard-display-table and empties eev-composes-localmath."
(interactive)
(setq standard-display-table
(copy-sequence eev-math-glyphs-standard-display-table-backup))
(setq eev-composes-localmath nil)
(eev-composes-update))
;;; __
;;; / _| __ _ ___ ___ ___
;;; | |_ / _` |/ __/ _ \/ __|
;;; | _| (_| | (_| __/\__ \
;;; |_| \__,_|\___\___||___/
;;;
;; «faces» (to ".faces")
;; Define several faces for glyphs in a few lines of code.
;; This is too rigid, but whatever.
;; (find-ecolors)
;;
(defun eev-glyphs-set-face (face fg bg)
(make-face face)
(set-face-foreground face fg)
(set-face-background face bg))
(eev-glyphs-set-face 'eev-glyph-face-Greek "orange" "gray20")
(eev-glyphs-set-face 'eev-glyph-face-greek "coral" "gray20")
(eev-glyphs-set-face 'eev-glyph-face-logical "SteelBlue1" "gray20")
(eev-glyphs-set-face 'eev-glyph-face-math "RoyalBlue2" "gray20")
(eev-glyphs-set-face 'eev-glyph-face-linear "PaleVioletRed" "gray20")
(eev-glyphs-set-face 'eev-glyph-face-graphic "red" "gray20")
(eev-glyphs-set-face 'eev-glyph-face-font "gold" "DarkOrange4")
;; Now defining glyphs can be as simple as this:
;; (eev-set-glyph ?Þ 332664 'eev-glyph-face-Greek)
;; but having many lines like that is not very convenient -
;; it is too verbose and it does not handle compose pairs...
;; See: (find-eev "eev-glyphs.el" "eev-set-glyph")
;;; __ _
;;; _ __ __ _ _ __ ___ ___ \ \ ___| |__ __ _ _ __
;;; | '_ \ / _` | '_ ` _ \ / _ \_____\ \/ __| '_ \ / _` | '__|
;;; | | | | (_| | | | | | | __/_____/ / (__| | | | (_| | |
;;; |_| |_|\__,_|_| |_| |_|\___| /_/ \___|_| |_|\__,_|_|
;;;
;; Old Emacs: (find-echarsetchars 'mule-unicode-0100-24ff)
;; (find-echarsetchars 'mule-unicode-2500-33ff)
;; New Emacs: (find-einsert '((128 14000)))
;; (find-eleimfile "quail/sgml-input.el")
;; (find-eleimfile "quail/latin-ltx.el")
;; A high-level way to set glyphs and compose pairs.
(defvar eev-math-glyphs-name-to-char
'(("Theta" . 332664)
("Pi" . 332704)
("Sigma" . 332707)
("Omega" . 332713)
;;
("delta" . 332724)
("epsilon" . 332725)
("theta" . 332728)
("lambda" . 343339)
("nu" . 332733)
("pi" . 332736)
("rho" . 332737)
("sigma" . 332739)
("tau" . 332740)
("omega" . 343541)
;;
("top" . 343268)
("bot" . 343269)
("land" . 343111)
("lor" . 343112)
("supset" . 343235)
("forall" . 343072)
("exists" . 343075)
("box" . 299376)
("thin:" . 343126)
("in" . 343082)
("circ" . 343096)
("cap" . 343113)
("cup" . 343114)
("Int" . 343115)
("nabla" . 8711) ;; was 343079
("infty" . 343102)
("ge" . 343205)
("^1" . 185)
("sqcap" . 343251)
("sqcup" . 343252)
("ud&" . 342827)
("oplus" . 343253)
("otimes" . 343259)
("to" . 342898)
("dotli" . 343375)
("nat" . 299502)
("seblock" . 299223)
("neblock" . 299229)
("b" . ?b)
("r" . ?r)
("t" . ?t)
("s" . ?s))
"An alist that translates char names\
(for mathematical glyphs) to char codes.")
;; 2008feb22: This is an emergency hack to make my math glyphs
;; work in CVS Emacs after the merge of the unicode-2 branch...
;; This - or the previous table - will disappear soon, I hope...
;;
(when (fboundp 'make-glyph-code)
(setq eev-math-glyphs-name-to-char
'(("Theta" . 920)
("Pi" . 928)
("Sigma" . 931)
("Omega" . 937)
;;
("delta" . 948)
("epsilon" . 949)
("theta" . 952)
("lambda" . 955)
("nu" . 957)
("pi" . 960)
("rho" . 961)
("sigma" . 963)
("tau" . 964)
("omega" . 969)
;;
("top" . 8868)
("bot" . 8869)
("land" . 8743)
("lor" . 8744)
("supset" . 8835)
("forall" . 8704)
("exists" . 8707)
;; ("box" . 9633)
("box" . 9744)
("thin:" . 8758)
("in" . 8712)
("circ" . 9675)
("cap" . 8745)
("cup" . 8746)
("Int" . 8747)
("nabla" . 8711)
("infty" . 8734)
("ge" . 8805)
("^1" . 185)
("sqcap" . 8851)
("sqcup" . 8852)
("ud&" . 8523)
("oplus" . 8853)
("otimes" . 8855)
("to" . 8594)
("lolli" . 8888)
("dotli" . 9480)
("nat" . 9838)
("seblock" . 9623)
("neblock" . 9629)
("b" . ?b)
("r" . ?r)
("t" . ?t)
("s" . ?s)
;;
("ulcorn" . 8988)
("urcorn" . 8989))
)
)
;; To inspect eev-math-glyphs-name-to-char:
' (progn (find-estring "")
(mapc (lambda (p) (insert (format "%c %s\n" (cdr p) (car p))))
eev-math-glyphs-name-to-char))
;;; _
;;; __ _ _ __ __ _ _ _ _ __ ___ ___ _ __ | |_ ___
;;; / _` | '__/ _` | | | | '_ ` _ \ / _ \ '_ \| __/ __|
;;; | (_| | | | (_| | |_| | | | | | | __/ | | | |_\__ \
;;; \__,_|_| \__, |\__,_|_| |_| |_|\___|_| |_|\__|___/
;;; |___/
;;
;; Functions to split packed argument lists
(defun ee-map-split (seq)
"Split with `ee-split' the strings in SEQ.
The original SEQ is not modified; this function returns a new list.
Example: (ee-map-split '(foo \"ab cd\" \"00 11\"))
==> (foo (\"ab\" \"cd\") (\"00\" \"11\"))"
(mapcar (lambda (x) (if (stringp x) (ee-split x) x)) seq))
(defun ee-map-nth (n seq)
"Substitute each list in SEQ by its N-th element.
The original SEQ is not modified; this function returns a new list.
(ee-map-nth 0 '(foo (a b c) (1 2) bar))
==> (foo a 1 bar)
(ee-map-nth 1 '(foo (a b c) (1 2) bar))
==> (foo b 2 bar)
(ee-map-nth 2 '(foo (a b c) (1 2) bar))
==> (foo c nil bar)"
(mapcar (lambda (x) (if (consp x) (nth n x) x)) seq))
(defun ee-chop1 (n bigseq)
"Return BIGSEQ split in N-element chunks.
Example: (ee-chop1 4 (number-sequence 1 10))
==> ((1 2 3 4) (5 6 7 8) (9 10))"
(setq bigseq (copy-sequence bigseq))
(let ((rest nil) (result nil))
(while bigseq
(setq rest (nthcdr n bigseq))
(if (nthcdr (- n 1) bigseq)
(setcdr (nthcdr (- n 1) bigseq) nil))
(setq result (cons bigseq result))
(setq bigseq rest))
(reverse result)))
(defun ee-chop2 (ref seq)
"Use `ee-map-nth' to return (length (nth REF SEQ)) \"sections\" of SEQ.
Examples:
(ee-chop2 1 '(foo (a b c) (1 2) bar))
==> ((foo a 1 bar) (foo b 2 bar) (foo c nil bar))
(ee-chop2 2 '(foo (a b c) (1 2) bar))
==> ((foo a 1 bar) (foo b 2 bar))"
(let ((ns (number-sequence 0 (- (length (nth ref seq)) 1))))
(mapcar (lambda (n) (ee-map-nth n seq)) ns)))
(defun ee-chop3 (n ref bigseq)
"Combine `ee-map-split', `ee-chop1', and `ee-chop2'.
Example:
(ee-chop3 4 1 '(Greek \"Pi Sigma Theta\" \"Pi Si Th\" (P S T)
greek \"delta epsilon\" \"dd ee\" (d e)))
==> ((Greek \"Pi\" \"Pi\" P)
(Greek \"Sigma\" \"Si\" S)
(Greek \"Theta\" \"Th\" T)
(greek \"delta\" \"dd\" d)
(greek \"epsilon\" \"ee\" e))"
(let* ((seqs (ee-chop1 n (ee-map-split bigseq)))
(columns (mapcar (lambda (seq) (ee-chop2 ref seq)) seqs)))
(apply 'append columns)))
;;; _ _ _ _
;;; _ __ ___ __ _| |_| |__ __ _| |_ _ _ __ | |__ ___
;;; | '_ ` _ \ / _` | __| '_ \ / _` | | | | | '_ \| '_ \/ __|
;;; | | | | | | (_| | |_| | | | | (_| | | |_| | |_) | | | \__ \
;;; |_| |_| |_|\__,_|\__|_| |_| \__, |_|\__, | .__/|_| |_|___/
;;; |___/ |___/|_|
(defun eev-math-glyphs-set (face names pairs chars &rest rest)
"This is hard to explain, but there's an example at:...
(find-efunction 'eev-math-glyphs-edrx)"
(setq names (split-string names " +"))
(setq pairs (split-string pairs " +"))
(setq chars (split-string chars " +"))
(while names
(let ((n (car names)) (p (car pairs)) (c (car chars)))
(if (= 1 (length c))
(let ((c (string-to-char c)))
(eev-set-glyph c (ee-aref eev-math-glyphs-name-to-char n) face)
(setq eev-composes-localmath
(lax-plist-put eev-composes-localmath p c)))))
(setq names (cdr names) pairs (cdr pairs) chars (cdr chars)))
(if rest (apply 'eev-math-glyphs-set rest)
(eev-composes-update)))
;; A demo: this function sets up the glyphs that I (Edrx)
;; use for most of my TeXed notes.
(defun eev-math-glyphs-edrx ()
"Sets up a certain set of mathematical glyphs for TeX, with compose pairs."
(interactive)
(eev-math-glyphs-set
'eev-glyph-face-Greek
"Theta Pi Sigma Omega"
"Th Pi Si Om "
"Þ å Æ Ø "
'eev-glyph-face-greek
"delta epsilon theta lambda nu pi rho sigma tau omega"
"dd ee te ll nu pi ro si tt ww "
" ð Û Ï "
'eev-glyph-face-logical
"top bot land lor supset forall exists box thin: in circ"
"TT bt la lo im fa ex bo :: in oo "
"§ ® ∧ ∨ ⊃ ý Î ñ ¨ Ý ¢ "
'eev-glyph-face-math
"cap cup Int nabla infty ge ^1"
"ca cu In na 88 >= -1"
"Ì þ Å ¿ ‚ © ³ "
'eev-glyph-face-linear
"sqcap sqcup ud& oplus otimes lolli"
"ka ku && o+ ox -o"
" ÷ Ñ ¥ ¤ ¸ "
'eev-glyph-face-graphic
"dotli nat seblock neblock"
".. bq bl ^^ "
"(÷) î £ "
'eev-glyph-face-font
"b r t s "
"bf rm tx ss"
"¦ ¯ Ë Ð "))
;; Þ寨ðÛÏ
;; §®∧∨⊃ýÎñ¨Ý¢ÌþÅ¿‚©
;; ÷Ñ¥¤¸î£¦¯ËÐ
;; To set up a certain set of TeX glyphs:
;; (require 'eev-math-glyphs)
;; (eev-math-glyphs-edrx)
;; To undo (i.e., to remove all local math glyphs):
;; (eev-math-glyphs-reset)
;; An example of TeX code using glyphs:
"
%*
% (ee-once (eelatex-bounded))
\catcode`¦=13 \def¦{\mathbf}
A natural transformation from $F:¦A \to ¦B$ to $G:¦A \to ¦B$ is...
%*
"
;; See: (find-texbookpage 'appendixI)
;; (find-texbookpage (+ 11 39))
;; 2007nov09: note: this is very far from obvious, but
;; `eev-math-glyphs-set' can also be used to change individual glyphs.
;; It is convenient to add a name for the character that they use to
;; `eev-math-glyphs-name-to-char'. Here's an example:
;; (add-to-alist 'eev-math-glyphs-name-to-char '("Delta" . 332660))
;; (eev-math-glyphs-set 'eev-glyph-face-math "nabla" "na" "¿")
;; (eev-math-glyphs-set 'eev-glyph-face-math "Delta" "DD" "¿")
;; (find-glyphashtml-links "na")
;; (find-glyphashtml-links "DD")
;; That example has some problems that I will try to fix later...
;; (1) `add-to-alist' is not standard. Links:
;; (find-angg ".emacs" "add-to-alist")
;; http://angg.twu.net/.emacs.html#add-to-alist
;; http://lists.gnu.org/archive/html/bug-gnu-emacs/2001-02/msg00066.html
;; (2) `find-glyphashtml-links' is even less standard... it's
;; currently only at:
;; (find-angg ".emacs" "find-glyphashtml-links")
;; http://angg.twu.net/.emacs.html#find-glyphashtml-links
;; and I created it (in a hurry) because I wanted a quick way to
;; htmlize a glyph, for:
;; (find-angg "blogme3/anggdefs.lua")
;; (find-angg "blogme3/anggdefs.lua" "eev_math_glyphs_edrx")
(provide 'eev-math-glyphs)
;; Local Variables:
;; coding: raw-text-unix
;; ee-anchor-format: "«%s»"
;; End: