Xref: utzoo comp.emacs:8081 gnu.emacs:2631 Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!sdd.hp.com!decwrl!shelby!neon!Neon.Stanford.EDU!yossi From: yossi@Neon.Stanford.EDU (Joseph Friedman) Newsgroups: comp.emacs,gnu.emacs Subject: Hebrew support for GNU Emacs/Epoch under X11 (part 01 of 02) Keywords: Semitic languages, Emacs, X Windows Message-ID: <1990Apr8.181956.25064@Neon.Stanford.EDU> Date: 8 Apr 90 18:19:56 GMT Sender: yossi@Neon.Stanford.EDU (Joseph Friedman) Organization: Computer Science Department, Stanford University Lines: 704 Looks like Emacs is going International. I heard of a Japanese Emacs, and recently there have been some postings about a Swedish Emacs. Well, I'd like to contribute my stuff: Hebrew Emacs (and I hope that somehow all these foreign dialects will make it to version 19). The basic problem with Hebrew is that, like other Semitic languages, you write it from right to left. The other problem is that Hebrew fonts share nothing with Roman fonts, so I had to use a 256-character font. I enclose a sample Hebrew X11 screen font, as well as patches to both GNU Emacs 18.55 and Epoch 3.1. Enjoy! Oh, and please report any problems to me. -yossi -----------------8<-----------------------8<----------------- #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'README' <<'END_OF_FILE' XThis directory contains the patches necessary to edit text in Semitic Xlanguages using GNU Emacs 18.55 under X11, or Epoch 3.1. This Xdirectory contains: X X1) A simple, fixed, Hebrew X screen font, modified from misc/6x13. X Also, I included the accompanying line in the fonts.alias file. X X2) Patches for the source code and lisp code for GNU Emacs 18.55 and X Epoch 3.1 that do right-to-left display and editing, as well X as my own version of 256-character fonts support. X X3) A new lisp package, hebrew.el, which selectively maps the X workstation keyboard into a standard Hebrew keyboard. This mapping X is done both in insertion and in searching (sorry, I haven't X implemented replacing yet, but it'll come soon.) X XThe basic idea: X-------------- XTo summarize the changes to the C code, I created two new buffer-local Xvariables, display-literal and display-reversed. When display-literal Xis non-nil, nonprintable characters in the buffer are NOT mapped into Xctl-arrow or backslash-and-three-octals; instead, whatever is in the Xfont entry is displayed as is (don't do this at home! On a non-X Xdisplay, this can really mess up the screen). When display-reversed Xis non-nil, all the windows showing the current buffer are flipped Xlaterally, so the beginning of the line appears on the right and the Xlines are wrapped (or truncated) on the left; all the editing command Xcontinue to behave as they were before. The default value for both Xthese variables is nil, so Emacs and Epoch behave exactly like the Xnon-semitic version unless you specifically request otherwise. X XInstallation: X------------ X1) Start with the font. Unpack the font using: X X uudecode thefont X uncompress heb6x13.bdf.Z X X then run bdftosnf on heb6x13.bdf and install heb6x13.snf wherever X you keep your local fonts. Run mkfontdir in that directory, and X then append the enclosed fonts.alias to your fonts.alias file. X You're all set. Just to be sure, try: X X xfd -fn heb6x13 X X2) Now apply the patches. The Emacs patches are in Emacs-18.55. X Apply patch-src in the source directory and patch-lisp in the lisp X directory. For Epoch, apply Epoch-3.1/patch-src in the source X directory and Epoch-3.1/patch-lisp in the epoch-lisp-files (not the X lisp) directory. NOTE: A couple of days ago, Simon M. Kaplan X posted a new version of motion.el; I enclose patches for both the X old motion.el and this new-and-improved motion.el. When patching X the lisp files, don't forget to delete the corresponding X .elc files, since they have precedence over .el files. X X3) Next, copy hebrew.el to your local lisp directory. X X4) You're almost ready to use the package. Now comes the REALLY HARD X part---making little labels with the hebrew characters on them and X taping these labels on the front of the keys on the keyboard :-( X XHave fun! And please report any problems/bugs/suggestions to me. X X-yossi END_OF_FILE if test 2899 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test ! -d 'emacs-18.55' ; then echo shar: Creating directory \"'emacs-18.55'\" mkdir 'emacs-18.55' fi if test -f 'emacs-18.55/patch-lisp' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'emacs-18.55/patch-lisp'\" else echo shar: Extracting \"'emacs-18.55/patch-lisp'\" \(1950 characters\) sed "s/^X//" >'emacs-18.55/patch-lisp' <<'END_OF_FILE' X*** x-mouse.el.orig Thu Mar 24 01:04:41 1988 X--- x-mouse.el Sun Apr 8 05:58:23 1990 X*************** X*** 106,129 **** X (funcall x-process-mouse-hook x-mouse-pos x-mouse-item)))) X X (define-key global-map "\C-c\C-m" 'x-flush-mouse-queue) X (define-key global-map "\C-x\C-@" 'x-flush-mouse-queue) X X (defun x-mouse-select (arg) X "Select Emacs window the mouse is on." X (let ((start-w (selected-window)) X (done nil) X (w (selected-window)) X! (rel-coordinate nil)) X (while (and (not done) X (null (setq rel-coordinate X (coordinates-in-window-p arg w)))) X (setq w (next-window w)) X (if (eq w start-w) X (setq done t))) X (select-window w) X! rel-coordinate)) X X (defun x-mouse-keep-one-window (arg) X "Select Emacs window mouse is on, then kill all other Emacs windows." X (if (x-mouse-select arg) X (delete-other-windows))) X--- 106,136 ---- X (funcall x-process-mouse-hook x-mouse-pos x-mouse-item)))) X X (define-key global-map "\C-c\C-m" 'x-flush-mouse-queue) X (define-key global-map "\C-x\C-@" 'x-flush-mouse-queue) X X+ ; yossi-- modified x-mouse-select to support reverse displays. X (defun x-mouse-select (arg) X "Select Emacs window the mouse is on." X (let ((start-w (selected-window)) X (done nil) X (w (selected-window)) X! (rel-coordinate nil) X! (cur-buf (current-buffer))) X (while (and (not done) X (null (setq rel-coordinate X (coordinates-in-window-p arg w)))) X (setq w (next-window w)) X (if (eq w start-w) X (setq done t))) X (select-window w) X! (set-buffer (window-buffer w)) X! (and rel-coordinate X! (if (null display-reversed) X! rel-coordinate X! (cons (- (window-width) (car rel-coordinate) 1) X! (cdr rel-coordinate)))))) X X (defun x-mouse-keep-one-window (arg) X "Select Emacs window mouse is on, then kill all other Emacs windows." X (if (x-mouse-select arg) X (delete-other-windows))) END_OF_FILE if test 1950 -ne `wc -c <'emacs-18.55/patch-lisp'`; then echo shar: \"'emacs-18.55/patch-lisp'\" unpacked with wrong size! fi # end of 'emacs-18.55/patch-lisp' fi if test ! -d 'epoch-3.1' ; then echo shar: Creating directory \"'epoch-3.1'\" mkdir 'epoch-3.1' fi if test -f 'epoch-3.1/patch-lisp' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'epoch-3.1/patch-lisp'\" else echo shar: Extracting \"'epoch-3.1/patch-lisp'\" \(4826 characters\) sed "s/^X//" >'epoch-3.1/patch-lisp' <<'END_OF_FILE' X*** smk-x-mouse.el.orig Tue Jan 30 19:50:55 1990 X--- smk-x-mouse.el Sun Apr 8 05:59:33 1990 X*************** X*** 106,129 **** X (funcall x-process-mouse-hook x-mouse-pos x-mouse-item)))) X X (define-key global-map "\C-c\C-m" 'x-flush-mouse-queue) X (define-key global-map "\C-x\C-@" 'x-flush-mouse-queue) X X (defun x-mouse-select (arg) X "Select Emacs window the mouse is on." X (let ((start-w (selected-window)) X (done nil) X (w (selected-window)) X! (rel-coordinate nil)) X (while (and (not done) X (null (setq rel-coordinate X (coordinates-in-window-p arg w)))) X (setq w (next-window w)) X (if (eq w start-w) X (setq done t))) X (select-window w) X! rel-coordinate)) X X (defun x-mouse-keep-one-window (arg) X "Select Emacs window mouse is on, then kill all other Emacs windows." X (if (x-mouse-select arg) X (delete-other-windows))) X--- 106,137 ---- X (funcall x-process-mouse-hook x-mouse-pos x-mouse-item)))) X X (define-key global-map "\C-c\C-m" 'x-flush-mouse-queue) X (define-key global-map "\C-x\C-@" 'x-flush-mouse-queue) X X+ X+ ; yossi-- modified x-mouse-select to support reverse displays. X (defun x-mouse-select (arg) X "Select Emacs window the mouse is on." X (let ((start-w (selected-window)) X (done nil) X (w (selected-window)) X! (rel-coordinate nil) X! (cur-buf (current-buffer))) X (while (and (not done) X (null (setq rel-coordinate X (coordinates-in-window-p arg w)))) X (setq w (next-window w)) X (if (eq w start-w) X (setq done t))) X (select-window w) X! (set-buffer (window-buffer w)) X! (and rel-coordinate X! (if (null display-reversed) X! rel-coordinate X! (cons (- (window-width) (car rel-coordinate) 1) X! (cdr rel-coordinate)))))) X X (defun x-mouse-keep-one-window (arg) X "Select Emacs window mouse is on, then kill all other Emacs windows." X (if (x-mouse-select arg) X (delete-other-windows))) X*** old-motion.el.orig Wed Jan 31 09:11:37 1990 X--- old-motion.el Sun Apr 8 06:23:46 1990 X*************** X*** 48,67 **** X ) X X (setq-default drag-button nil) X (setq-default already-moused nil) X X (defun mouse-sweep-update() X (let (x y pos) X (if (not drag-button) X (progn X (setq drag-button X (epoch::add-button (marker-position mouse-down-marker) (point) 1 nil)) X (setq drag-m1 (aref drag-button 0)) X (setq drag-m2 (aref drag-button 1)))) X (setq pos (epoch::query-pointer)) X- (setq foo pos) X (setq y (car (cdr pos))) X (if (< y 0) X (progn (scroll-down 1) X (setq y 0) X (epoch::send-client-message (current-screen) xa-motion)) X--- 48,67 ---- X ) X X (setq-default drag-button nil) X (setq-default already-moused nil) X X+ ; yossi-- changed mouse-sweep-update to handle reversed screens. X (defun mouse-sweep-update() X (let (x y pos) X (if (not drag-button) X (progn X (setq drag-button X (epoch::add-button (marker-position mouse-down-marker) (point) 1 nil)) X (setq drag-m1 (aref drag-button 0)) X (setq drag-m2 (aref drag-button 1)))) X (setq pos (epoch::query-pointer)) X (setq y (car (cdr pos))) X (if (< y 0) X (progn (scroll-down 1) X (setq y 0) X (epoch::send-client-message (current-screen) xa-motion)) X*************** X*** 69,79 **** X (if (>= y (window-height)) X (progn (scroll-up 1) (setq y (- (window-height) 1)) X (epoch::send-client-message (current-screen) xa-motion)) X ) X (move-to-window-line (- y (car (cdr (window-edges))))) X! (move-to-column (+ (current-column) (car pos))) X (setq p (point)) X (if (> mouse-down-marker (point)) X (progn X (set-marker drag-m1 (point)) (set-marker drag-m2 mouse-down-marker) X ) X--- 69,83 ---- X (if (>= y (window-height)) X (progn (scroll-up 1) (setq y (- (window-height) 1)) X (epoch::send-client-message (current-screen) xa-motion)) X ) X (move-to-window-line (- y (car (cdr (window-edges))))) X! (move-to-column (+ (current-column) X! (let ((x (car pos))) X! (if (null display-reversed) X! x X! (- (window-width) x 1))))) X (setq p (point)) X (if (> mouse-down-marker (point)) X (progn X (set-marker drag-m1 (point)) (set-marker drag-m2 mouse-down-marker) X ) X*** motion.el.orig Sun Apr 8 08:31:34 1990 X--- motion.el Sun Apr 8 08:24:44 1990 X*************** X*** 67,76 **** X--- 67,78 ---- X (/= 0 (logand mouse-any (elt pos 2))) X ;;(/= 0 (logand mouse-any (cdr (cdr pos)))) ;if error on previous line X ) X ;;convert to window relative co-ordinates X (setq x (- (car pos) left)) X+ (if (not (null display-reversed)) X+ (setq x (- (window-width) x 1))) X (setq y (- (elt pos 1) top)) X (setq out-of-bounds X (not (and (<= 0 y) (<= y bottom) (<= 0 x) (<= x right))) X ) X END_OF_FILE if test 4826 -ne `wc -c <'epoch-3.1/patch-lisp'`; then echo shar: \"'epoch-3.1/patch-lisp'\" unpacked with wrong size! fi # end of 'epoch-3.1/patch-lisp' fi if test -f 'fonts.alias' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'fonts.alias'\" else echo shar: Extracting \"'fonts.alias'\" \(143 characters\) sed "s/^X//" >'fonts.alias' <<'END_OF_FILE' Xheb6x13 -yossi-fixed-medium-r-semicondensed-hebrew-13-120-75-75-c-60-- Xheb8x13 -yossi-fixed-bold-r-normal-hebrew-13-120-75-75-c-80-- END_OF_FILE if test 143 -ne `wc -c <'fonts.alias'`; then echo shar: \"'fonts.alias'\" unpacked with wrong size! fi # end of 'fonts.alias' fi if test -f 'hebrew.el' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'hebrew.el'\" else echo shar: Extracting \"'hebrew.el'\" \(5702 characters\) sed "s/^X//" >'hebrew.el' <<'END_OF_FILE' X;;; X;;; hebrew.el -- Hebrew editing mode. X;;; For more information, see documentation of `hebrew-mode'. X;;; X;;; Copyright (c) Yossi Friedman, April 1990 X;;; X X(defvar running-epoch nil "*Non-nil means Epoch is running.") X X(defvar hebrew-mode-hook () "*Called when entering hebrew-mode") X X(defvar hebrew-mode nil "*Non nil when Hebrew mode is turned on.") X(make-variable-buffer-local 'hebrew-mode) X X(or (assoc 'hebrew-mode minor-mode-alist) X (setq minor-mode-alist X (cons '(hebrew-mode " Hebrew") minor-mode-alist))) X X(defun hebrew-mode () X"\ XToggles hebrew-mode on/off. Hebrew-mode is a minor mode which allows Xreversing the editor display and changing the keyboard in order to Xenter and edit text in a semitic language, such as Hebrew. X XBy default, hebrew-mode stays in \"normal\" state. The \"reversed\" Xstate is activated with \"\\[hebrew-toggle-reversed]\". (In Epoch, this Xis also bound to \"F3\".) In the \"reversed\" state, hebrew-mode emulates Xa Hebrew keyboard both during direct insertion and during searches. X XHebrew-mode calls hebrew-mode-hook upon entering." X X X (interactive) X (if (null hebrew-mode) X (let (char) X X ; signal hebrew minor mode in the mode-line X (setq hebrew-mode t) X X ; activate the hebrew insertion function X (setq char ? ) X (while (<= char ?~) X (local-set-key (format "%c" char) 'hebrew-insert) X (setq char (1+ char))) X X ; display-literal, display-reversed X (setq display-literal t) X (local-set-key "\C-cR" 'hebrew-toggle-reversed) X X ; syntax table stuff X (setq char ?\340) ; aleph X (while (<= char ?\372) ; taf X (modify-syntax-entry char "w") X (setq char (1+ char))) X X ; search stuff X (local-set-key "\C-s" 'hebrew-ctrl-s) X (local-set-key "\C-r" 'hebrew-ctrl-r) X X ; hooks X (run-hooks 'hebrew-mode-hook)) X X (let (char) X X ; turn off hebrew minor mode in the mode-line X (setq hebrew-mode nil) X X ; deactivate the hebrew insertion function X (setq char ? ) X (while (<= char ?~) X (local-unset-key (format "%c" char)) X (setq char (1+ char))) X X ; deactivate display-literal and display-reversed X (setq display-literal nil) X (local-unset-key "\C-cR") X X ; search stuff X (local-unset-key "\C-s") X (local-unset-key "\C-r") X X ; restore syntax-table X (setq char ?\340) ; aleph X (while (<= char ?\372) ; taf X (modify-syntax-entry char " ") X (setq char (1+ char)))))) X X(if running-epoch X (epoch::rebind-key "F3" 0 "\C-cR")) X(defun hebrew-toggle-reversed () X "Toggle whether or not the display is laterally reversed." X (interactive) X (setq display-reversed (null display-reversed)) X (if running-epoch X (epoch::redisplay-screen) X (x-smart-redisplay))) X X(defun hebrew-insert (&optional arg) X "\ XIf display-reversed is nil, behaves like self-insert-command. XIf display-reversed is t, simulates a Hebrew typewriter keyboard." X X (interactive) X (or (numberp arg) (setq arg 1)) X (let ((char (if display-reversed X (aref hebrew-keyboard last-command-char) X (format "%c" last-command-char)))) X (while (> arg 0) X (insert char) X (setq arg (1- arg))))) X X(defun hebrew-ctrl-s () "The Hebrew-mode version of \C-s" X (interactive) X (let ((old-read-char (symbol-function 'read-char)) X (old-text-char-description (symbol-function 'text-char-description)) X (search-exit-option nil) X res) X (fset 'read-char (symbol-function 'hebrew-read-char)) X (fset 'text-char-description X (symbol-function 'hebrew-text-char-description)) X (setq res (funcall (global-key-binding "\C-s"))) X (fset 'read-char old-read-char) X (fset 'text-char-description old-text-char-description) X res)) X X(defun hebrew-ctrl-r () "The Hebrew-mode version of \C-r" X (interactive) X (let ((old-read-char (symbol-function 'read-char)) X (old-text-char-description (symbol-function 'text-char-description)) X (search-exit-option nil) X res) X (fset 'read-char (symbol-function 'hebrew-read-char)) X (fset 'text-char-description X (symbol-function 'hebrew-text-char-description)) X (setq res (funcall (global-key-binding "\C-r"))) X (fset 'read-char old-read-char) X (fset 'text-char-description old-text-char-description) X res)) X X(defun hebrew-read-char () X "The hebrew-mode version of read-char." X (let ((char (funcall old-read-char))) X (if (and display-reversed (>= char ? ) (<= char ?~)) X (string-to-char (aref hebrew-keyboard char)) X char))) X X(defun hebrew-text-char-description (char) X "The hebrew-mode version of text-char-description." X (if display-reversed X (char-to-string char) X (funcall old-text-char-description char))) X X; for the search function to work, we can't use a byte-compiled version of X; isearch.el, so load it back: X(load-library "isearch.el") X X(setq hebrew-keyboard X [ X "" "" "" "" "" "" "" "" X "" "" "" "" "" "" "" "" X "" "" "" "" "" "" "" "" X "" "" "" "" "" "" "" "" X " " "!" "\"" "#" "$" "%" "&" "'" X "(" ")" "*" "+" "\372" "-" "\365" "." X "0" "1" "2" "3" "4" "5" "6" "7" X "8" "9" ":" "\363" "<" "=" ">" "?" X "@" "A" "B" "C" "D" "E" "F" "G" X "H" "I" "J" "K" "L" "M" "N" "O" X "P" "Q" "R" "S" "T" "U" "V" "W" X "X" "Y" "Z" "[" "\\" "]" "^" "_" X ";" "\371" "\360" "\341" "\342" "\367" "\353" "\362" X "\351" "\357" "\347" "\354" "\352" "\366" "\356" "\355" X "\364" "\\" "\370" "\343" "\340" "\345" "\344" "," X "\361" "\350" "\346" "{" "|" "}" "~" ""]) END_OF_FILE if test 5702 -ne `wc -c <'hebrew.el'`; then echo shar: \"'hebrew.el'\" unpacked with wrong size! fi # end of 'hebrew.el' fi if test -f 'thefont' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'thefont'\" else echo shar: Extracting \"'thefont'\" \(8166 characters\) sed "s/^X//" >'thefont' <<'END_OF_FILE' Xbegin 644 heb6x13.bdf.Z XM'YV04Z@$D4+%R!,G5$#(&,&1!@0<]J$8<,&!)(R8N24N0-SC,XR;D"8>>.&C@N'$"52)%-& XM3AH[9<@(E?.F#0@;>&+,<"&&C!D%!BFVR/)FSIPT+8RDP1.U19.H:>JT:2&E XMQ90R;=(,(*$2!(G1T1CN8IY!@@8(%K,F"R0(!0I3Z 4(9BDR!3,.3XC=!)$ XMXAET1W10)(%%$4Q(6-EE6BD Q1.GM4>999@=I@!R4SS!1!54)''0 XM%ZLI]J)O,M)HHQ-?.*?C%% $,<1I1SPW1'1!6+%;$$=8^%^ 2%P%@T-(##1% XM?\ XM$'GNB=F5#T&1A13JL:@00<(*(R1 @C7G06"$4Y%)9,;+ "7 PS1343$;;GM5J-O8TKQFPPUV$#; XM0%3(.9"DE*8!P[,*F/D$FDE>.<64 H) @PTQU$D$ME7:4*<00JPF;F:PR:: XM$$E0T4004"@ K1%7T@M6O?C>JZ^]]D+K[Y6Z*BO%L00)S&RESS8D+;6830:N XMMMQZ^["X5Y)K;FNOQ38;N^["*^^5_WXLLHLW7&F&9R4KX&+(T 8\)\')SGFP XMLS#($*T39R*ID,, 9KMMMU=^VW.XXY;+&KH:K]ONN_&R#/*587A6 ]124ZW XMU I$+7++I0D,L\&:-OOL; OK/-NU0T,,M )"4\E:Q4:?ZUJZ&R_ML=,BAP'U XME67LG?65*;LH.,!=OQP0LF!O2C,--^><)N-HN_VSQ&E3O&[<&-.M=,=-/[TU XMWU?B<.48H9M\):8*0*8 ZJB[/-#7,H>-, PU-#ZMSK5'[G/$04]<],5(J\LQ XMTY\7G[+H"B"? XMM%1W*P4T4'5X"YGK!E:]^]$I?S"( >$&YP" XM3J:R*ZW,9)Z18.%>5\'$B2T&"L/9[=(4G _R+H3B&V$!-7>^!.(-!YX9@V>T XME@//('%UIXNB^SPS0=CA#WLQL-GVDJ1!GDGNAVW+U@ Q%[RZG3""H7-BU5HH XM,A:JT$55K.'U;D@V'3(,AU[&UU(2#:ZJ&\H+%X<[6=# XMA,6 <5ML41Z_!T817HZ$@-P<\="82$0.TI#SHQXCY^C(VD6R1#[<)DUM)DL_2F+>E'PUQ>$'NVY"!FNF?-2@91 XMF\4TX2;3!TYFVI-KY,3E,W6),!GD4)W2!.8U5TG&$@82??8TPRPYB3=G6H^? XMSI*!%GN9IAAXL)VJ?"=[3TC/&%Z4"/2=*;%"RD^2?I0D_;3E#U5 XM2$. *DR7^I&HFO28. OIHF5N=:3U*ZE.98:$,\YE8GM*P^"9:I?FKXPD0%>UAS@D)(R\,]L-J,JB,6KX(Z2 XM6*27#26&;VA3>=+7FO$@=WO H,HB! XM#4-.TJ6,C$W[;E/)Q4OO\TILSQ33R0UR$0.DTG &-V09!/#E,D'O:^,E0TO, XM*UPC"_'<4"B+E0QOH$D8Y/#F&(:P5Z.9U&+9V#>DIF39@8! XMBW7B!C:4P0R=CB3J9!SJM>Z:U-!*-1OE!T5:_A:[QI;9MH%"*F:+V\/TA;:N XMR8MNZ1:RBP"?*^K8N^/$/%TS XM# #EUX\ XM1U?:Z?K,\!R / [V:=(EN=4#TUYP\)O?75] XM9WW$2W81UIY(>#4F;XT9!WMQB>)B<3N[[T??-^"[#C^_??6Z(LLV'>Z@]TAB XMC=P/E_;-/7<\P[M=[J7+<]U=G6$ZH.$G;ZX!OHVN=A'7^;QO5X"Z4^9VMS^1 XM]_ NN,R&4@=">[[A:0]]TGF=[K@K<\Q7NU(#61CPU<=[669X2N.C6@.1)Y_D XM$!]]&_^;O"N)870Q3/_A(VU]X:MX+;&7.>V5/^JMLY_PJ9]PX=N'^;D7N^-X(06((&XW)L XM0!2QQW<8B'5K-WFHW/M XMQG,Z*#/>9A9OICJ@]X++UV\+2%VIUUO.9X-*J%T@4 88,1-A.'L&2'_G9G]X XM@WG0HH?%YGYT<@8Z$08'%X;(YX(AAH#B!RW(HX:Z!S)PMVZI1X+%A1%E, =T XM('4#&%4VX'V&2&,V%X-7*()G2$N-UH<1B#\5J$XV(']U2(;U=V,SZ!G!IC5: XM('!!(Q4R&@@ XM=3J>\6"49HVK$URFV(7+,@1AV(*M>(B?R'RAB'^W2'?K@X/^QWHY101A"(3/ XM>(#C:(83AHWV6(WXN$+;6%Q%$(91&(]VR'9+=HRI9UT%F7_$MH[71R=&\&8I XM,X;BN('DJ'KH:#KG>)"YR(UT<@0.28>_*(\2:88SB)'!1H/[Z(9(X)"%&(Z> XM&)+VAXR&=XR&MW_*&&5)X)"(295E&9H]>9DP26% F9#9-C"=N9)R^9JO.) AN'\3!FR_ XMR9:*YX93L)HYN9N@V9O&\YNIQWOJ!X)/Z894L)I%Z9K+:94#V5\^Z4U?F5-5 XML)I3*9D:2)E729JR:7B969Q19@6K.9:T-9FPN62S^41XAC4J])T&LW\3VITG&65:\&8-])D JIVX=WIK:&WMMI;3&64Y$09K4 9TX&W@9J*M XM29X=JJ(A\S[MYH!2A#KK25<:"0)BD!)K,'::8G:1E .Z^9\/ZJ$B0W?L-EV- XM:(/$::3%-:,;8:/UEHJ?E0/)*:4]2I<_NH9,F:755Z39EC^4(@=C(!IT\ XM*GG".#(5NJ4XEVUUH""RYG(Z8:+CR:%X*HU-EU"V^7\R@VR/@J-BRC Y )\9 XM>*9(*3(&]EM\RG5O:J+^>:?!B*B9D3 XMEJ#+,DM/NJ&L&JJN:EXC>8[JJ)E11G51I4'6,G*\Z:/IHWYN5X/UB3*GRJC+ XMHH*?I4$[:JBZFHB\&H($R7\C*E9?<4HU(V=S>:G0XF#5*$7U.*0[=Z$&J+"KFK&("(JI(Z*"-;'L:#!"!JZX:K/SB([,3B3?,BIXUV'OJEVW&-ZR_U+6MFK8T5;4" XMBSRT2B<@=THQ4*BY"K X:[$3H&:('FV%WL+5!6[M# XMVW:K:WA(NT:5BP?O^E/&FIT.:T_V.5>#][H+"0)YD+S5BKJV2[01*HJMBZ_L XMEVUZD+QF.[?!:V(M\R*5NZ*5E *G)*[?86[[%8U&"M96?9+^5FZ1] XM"U RX*_SRY.!I[/>*;/+XKYAFKR,*[0"7#SX.U?V^TE;6;GYA<._N\/T&S(_+,1.',,Q3,/-O,5I',1@G :'T5U6/+X!;)Y+ XMIL8PO,9.W,:'$5]6++\,3,?%8\>"S,9$G#^'06!D#,!_#*%,',10/,.% XM7,,P4,)DO,# V\"-_,1X_,B2#+L0Y4\W[$N&9L8IVKS0,LB<',E##,J*Y4]' XM3,JGN\A4FLJ.W,EXK,=9]*XSH,,@"\IH3,S0#,VZS,=W1 /72\M3:\NK_,Q6H\N([$L,9\I2 XMB\JXK,VY+,UA'%#5[,>9#,S./,SF_,7R[,;I-*TTH,CWW,QYH\\&'](PS<\);E3$TL/:XN;=6([=%,Z]9&S=4U[=A+G=.JK,>M,ZQB"-1* XMW=>:3=05#<[ORBU>G<):/-I-S=D7[4LV,-4D/=>0O=:#-MQS=8+=IJG=BE7=E<9 .$ XM+==5[=P(_=%3C#6GY+K#S<'V!]Y8+=YAC-3E?=D-*]2L+=;032RO75$/"=I? XMO=K7O=D5W=6G= /A/-O?/=]_S=YN7 / [4N>+=_] XM3=KU72SO>@-F?>&/K=YVC>#$HMV8,23ZK=K%'>''7=^J$^#4'=\ASN+/3>*H XM'>#=S=Q@3>/A/=DU'-L=WM@RGMD9WMH5O8D=#M]G/.-%3M\VON 5Y9DI3MSI XMS>/K[>-3; ,4SD6LZ>!+'-&1K>$VGLY1+MN[3=LBKM,V;N(69>$ZSM]A;N3U XMG3*GA ,?_N8KWN0'CN5A+.#OB@/+7=W-;>4CSN=NW.!U'N-+3N1Q[N2&CE>X XM'>4Y+N@[KN<2/N=0SN5"ONC6W>A[GK6&K"-UKN38S.2>?NDD?@-DSD4G.N7H XMW<.$KN:/?@-LG@,#?N8%;NDMCN",-#M%I?>J[;NB,M=6L[N:4#N=T XM_>E'FC^,==^L?N?+GN?$7N/&[EKOF@.!/N2=WNRHGNV9#AR*7NJ,#N[%#NJ* XMPUA;#AR3[NV#KNO8KN[-PEBK#AR;;N[?7MOA3N^<4LG;3NI!;>KH/N_/ONY= XM%$DV'.QH?=@%W^/^;BEXI/ 9Q/"&_?".'O$=)NT*$:Y8_.H0+N\0?_#UCLQZ XMI>T?_^"!'.N2K?'4?/+4#N^5?NTC7US0OKAOML<6S]LLW\J\GKDY#P/E/O#G XMSN_I3O*<0L\G_^Z<'N\T?^4:_\\,XAK5=[^I.PRS^Q& XM;_ VK_;W[D\QW_0S'_PS_<+O?H-;_NF/_CUOMAZ=5;$?_&_?_3(SRF=DO-[U?P\+_+'[_GK XMWMEFI=+63]NX>YB>8=ZV&&R&2<';O_42U>V(K[I)!;)LRG3H7^_KK/ ]_?U5 XMC3<1"_\YG(V[F_;T+]+YE!/F]B0?)T%?\2\!SC].$="H7]73?.X/LR@KJ_7_ XM<%]#HWZS3\5IKY#QL1)@]5F ED*Z*;PK5@!9GWE).1X+_G4L8/74Z)^)0RFW XM[N[1JSR4C^Z1_P.!\,77^12RAO^R&=Z817D).$DO8^?>]$J1Z8&/K<' /Z22 XM]6K V-LR2/"FT4 M107U5NYI@@)0(<29*#@#S]<$7$"E"0&Q@]\I8!4RSPI?#ULK*7_VA*5LI'^T<,#$&- XMQX+(8 :DUO]M%4_37%UQ6@_#TW3A(& /QW 8$ XM*340O3@E' CD%-XZBX,1T'/00:D1!N_@S# T6?!_^;U)^ D5D VT@E;0$=*] XM!H@**>$GIQ5B+4W(]RY@+ZR%B@@]!1O]@Y$<8>&3;LG<#8B%2BX8A[^F]ONAG*3Q< XMSG."?!##*43@QQ [!=_K:@AQY6&_A:C]"&+A&X,9$>X]O\JG\6C=0V1__1#P X)Y3WBHBO\A ( X Xend END_OF_FILE if test 8166 -ne `wc -c <'thefont'`; then echo shar: \"'thefont'\" unpacked with wrong size! fi # end of 'thefont' fi echo shar: End of archive 1 \(of 2\). cp /dev/null ark1isdone MISSING="" for I in 1 2 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked both archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0