update.
[chise/omega.git] / chise2otf / elisp / chise-tex.el
1 ;;; chise-tex.el --- Coding-system based chise2otf like tool
2
3 ;; Copyright (C) 2004,2005,2006,2007,2008 MORIOKA Tomohiko
4
5 ;; Author: MORIOKA Tomohiko <tomo@kanji.zinbun.kyoto-u.ac.jp>
6 ;; Keywords: OTF package, pTeX, CHISE, Multiscript, Multilingual
7
8 ;; This file is a part of Omega/CHISE.
9
10 ;; This program is free software; you can redistribute it and/or
11 ;; modify it under the terms of the GNU General Public License as
12 ;; published by the Free Software Foundation; either version 2, or (at
13 ;; your option) any later version.
14
15 ;; This program is distributed in the hope that it will be useful, but
16 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 ;; General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with this program; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
24
25 ;;; Code:
26
27 (defvar chise-tex-coded-charset-expression-alist
28   '((=ucs-bmp@gb        "UCSgb"         4 X)
29     (=ucs-bmp@jis       "UCSjis"        4 X)
30     (=ucs-bmp@ks        "UCSks"         4 X)
31     (=gt-pj-1           "GTpjA"         4 X)
32     (=gt-pj-2           "GTpjB"         4 X)
33     (=gt-pj-3           "GTpjC"         4 X)
34     (=gt-pj-4           "GTpjD"         4 X)
35     (=gt-pj-5           "GTpjE"         4 X)
36     (=gt-pj-6           "GTpjF"         4 X)
37     (=gt-pj-7           "GTpjG"         4 X)
38     (=gt-pj-8           "GTpjH"         4 X)
39     (=gt-pj-9           "GTpjI"         4 X)
40     (=gt-pj-10          "GTpjJ"         4 X)
41     (=gt-pj-11          "GTpjK"         4 X)
42     (=ruimoku-v6        "Ruimoku"       4 X)
43     (=hanziku-1         "HanzikuA"      4 X)
44     (=hanziku-2         "HanzikuB"      4 X)
45     (=hanziku-3         "HanzikuC"      4 X)
46     (=hanziku-4         "HanzikuD"      4 X)
47     (=hanziku-5         "HanzikuE"      4 X)
48     (=hanziku-6         "HanzikuF"      4 X)
49     (=hanziku-7         "HanzikuG"      4 X)
50     (=hanziku-8         "HanzikuH"      4 X)
51     (=hanziku-9         "HanzikuI"      4 X)
52     (=hanziku-10        "HanzikuJ"      4 X)
53     (=hanziku-11        "HanzikuK"      4 X)
54     (=hanziku-12        "HanzikuL"      4 X)
55     (=ucs-bmp@cns       "UCScns"        4 X)
56     (thai-tis620        "ThaiTIS"       2 X)
57     ))
58
59 (defvar chise-tex-accent-macro-alist
60   '((?\u0300 . "`") ; <COMBINING GRAVE ACCENT>
61     (?\u0301 . "'") ; <COMBINING ACUTE ACCENT>
62     (?\u0302 . "^") ; <COMBINING CIRCUMFLEX ACCENT>
63     (?\u0303 . "~") ; <COMBINING TILDE>
64     (?\u0304 . "=") ; <COMBINING MACRON>
65     (?\u0306 . "u") ; <COMBINING BREVE>
66     (?\u0307 . ".") ; <COMBINING DOT ABOVE>
67     (?\u0308 . "\"") ; <COMBINING DIAERESIS>
68     (?\u0309 . "Hook")
69     (?\u030C . "v") ; <COMBINING CARON>
70     (?\u0323 . "d") ; <COMBINING DOT BELOW>
71     (?\u0327 . "c") ; <COMBINING CEDILLA>
72     (?\u032E . "ubreve")
73     (?\u0331 . "umacron")
74     ))
75
76 (defun chise-tex-encode-region-for-gb (start end)
77   (interactive "r")
78   (save-excursion
79     (save-restriction
80       (narrow-to-region start end)
81       (goto-char start)
82       (let (chr ret rest spec)
83         (while (and (skip-chars-forward "\x00-\xFF")
84                     (not (eobp)))
85           (setq chr (char-after))
86           (cond ((memq chr '(?\e$(O#@\e(B))
87                  (delete-char)
88                  (insert (format "\\UCSjis{%04X}"
89                                  (encode-char chr '=ucs@jis)))
90                  )
91                 ((and (setq ret (encode-char chr '=jis-x0208-1983))
92                       (< ret #x3021))
93                  (forward-char))
94                 ;; ((setq ret (encode-char chr '=jis-x0208-1990))
95                 ;;  (delete-char)
96                 ;;  (insert (decode-char '=jis-x0208-1983 ret)))
97                 ((and (encode-char chr '=ks-x1001)
98                       (setq ret (or (encode-char chr '=ucs@ks)
99                                     (char-ucs chr))))
100                  (delete-char)
101                  ;; (if (eq (char-before) ?\e$B!T\e(B)
102                  ;;     (insert " "))
103                  (insert (format "\\UCSks{%04X}" ret)))
104                 ((catch 'tag
105                    (setq rest chise-tex-coded-charset-expression-alist)
106                    (while (setq spec (car rest))
107                      (if (setq ret (encode-char chr (car spec)))
108                          (throw 'tag ret))
109                      (setq rest (cdr rest))))
110                  (delete-char)
111                  ;; (if (eq (char-before) ?\e$B!T\e(B)
112                  ;;     (insert " "))
113                  (insert (format (format "\\%s{%%0%d%s}"
114                                          (nth 1 spec)
115                                          (nth 2 spec)
116                                          (nth 3 spec))
117                                  ret)))
118                 (t
119                  (forward-char))))))))
120
121 (defun chise-tex-encode-ucs-char-at-point (&optional chr)
122   (unless chr
123     (setq chr (char-after)))
124   (let (ret rest spec)
125     (cond
126      ((and (encode-char chr '=ks-x1001)
127            (setq ret (or (encode-char chr '=ucs@ks)
128                          (char-ucs chr))))
129       (delete-char)
130       ;; (if (eq (char-before) ?\e$B!T\e(B)
131       ;;     (insert " "))
132       (insert (format "\\UCSks{%04X}" ret))
133       t)
134      ((setq ret (encode-char chr '=ucs-hangul))
135       (delete-char)
136       ;; (if (eq (char-before) ?\e$B!T\e(B)
137       ;;     (insert " "))
138       (insert (format "\\UCSks{%04X}" ret))
139       t)
140      ((eq chr ?\u00B2)
141       (delete-char)
142       (insert "$^2$")
143       t)
144      ((eq chr ?\u00B3)
145       (delete-char)
146       (insert "$^3$")
147       t)
148      ((eq chr ?\u0111)
149       (delete-char)
150       (insert "{\\usefont{T1}{pxr}{m}{n}\\dj}")
151       t)
152      ((eq chr ?\u014B)
153       (delete-char)
154       (insert "{\\usefont{T1}{pxr}{m}{n}\\ng}")
155       t)
156      ((eq chr ?\u0282)
157       (delete-char)
158       (insert "{\\usefont{T1}{pxr}{m}{n}\\k{s}}")
159       t)
160      ((eq chr ?\u0294)
161       (delete-char)
162       (insert "\\UCSjis{0294}")
163       t)
164      ((eq chr ?\u2022)
165       (delete-char)
166       (insert "\\textbullet{}")
167       t)
168      ((eq chr ?\u2080)
169       (delete-char)
170       (insert "$_0$")
171       t)
172      ((eq chr ?\u2081)
173       (delete-char)
174       (insert "$_1$")
175       t)
176      ((eq chr ?\u2082)
177       (delete-char)
178       (insert "$_2$")
179       t)
180      ((eq chr ?\u2083)
181       (delete-char)
182       (insert "$_3$")
183       t)
184      ((eq chr ?\u2084)
185       (delete-char)
186       (insert "$_4$")
187       t)
188      ((eq chr ?\u2085)
189       (delete-char)
190       (insert "$_5$")
191       t)
192      ((eq chr ?\u2086)
193       (delete-char)
194       (insert "$_6$")
195       t)
196      ((eq chr ?\u2087)
197       (delete-char)
198       (insert "$_7$")
199       t)
200      ((eq chr ?\u2088)
201       (delete-char)
202       (insert "$_8$")
203       t)
204      ((eq chr ?\u2089)
205       (delete-char)
206       (insert "$_9$")
207       t)
208      ((eq chr ?\u208A)
209       (delete-char)
210       (insert "$_+$")
211       t)
212      ((eq chr ?\u208B)
213       (delete-char)
214       (insert "$_-$")
215       t)
216      ((eq chr ?\u208C)
217       (delete-char)
218       (insert "$_=$")
219       t)
220      ((eq chr ?\u208D)
221       (delete-char)
222       (insert "$_($")
223       t)
224      ((eq chr ?\u208E)
225       (delete-char)
226       (insert "$_)$")
227       t)
228      ((eq chr ?\u2637)
229       (delete-char)
230       (insert "\\UCSgb{2637}")
231       t)
232      ((eq (encode-char chr '=ucs@jis) #x8DBC)
233       (delete-char)
234       (insert "\\GTpjG{4933}")
235       t)
236      ((and (encode-char chr '=ucs@jp)
237            (setq ret (char-representative-of-domain chr 'gb))
238            (setq ret (encode-char ret '=ucs@gb))
239            (<= ret #xFFFF))
240       (delete-char)
241       ;; (if (eq (char-before) ?\e$B!T\e(B)
242       ;;     (insert " "))
243       (insert (format "\\UCSgb{%04X}" ret))
244       t)
245      ((catch 'tag
246         (setq rest chise-tex-coded-charset-expression-alist)
247         (while (setq spec (car rest))
248           (if (setq ret (encode-char chr (car spec)))
249               (throw 'tag ret))
250           (setq rest (cdr rest))))
251       (delete-char)
252       ;; (if (eq (char-before) ?\e$B!T\e(B)
253       ;;     (insert " "))
254       (insert (format (format "\\%s{%%0%d%s}"
255                               (nth 1 spec)
256                               (nth 2 spec)
257                               (nth 3 spec))
258                       ret))
259       t)
260      )))
261
262 (defun chise-tex-encode-region-for-jis (start end)
263   (interactive "r")
264   (save-excursion
265     (save-restriction
266       (narrow-to-region start end)
267       (goto-char start)
268       (let (chr ret
269                 ;; rest spec
270                 modifier base modifier-1)
271         (while (and (skip-chars-forward "\x00-\x7F")
272                     (not (eobp)))
273           (setq chr (char-after))
274           (cond ((encode-char chr '=jis-x0208-1983)
275                  (forward-char))
276                 ;; ((setq ret (encode-char chr '=jis-x0208-1990))
277                 ;;  (delete-char)
278                 ;;  (insert (decode-char '=jis-x0208-1983 ret)))
279                 ((and (not (eq (char-ucs chr) #x0439))
280                       (not (eq (char-ucs chr) #x0451))
281                       (setq ret (char-feature chr '=decomposition))
282                       (setq modifier (assq (nth 1 ret)
283                                            '((?\u0300 . "`")
284                                              (?\u0301 . "'")
285                                              (?\u0302 . "^")
286                                              (?\u0303 . "~")
287                                              (?\u0304 . "=")
288                                              (?\u0306 . "u")
289                                              (?\u0307 . ".")
290                                              (?\u0308 . "\"")
291                                              (?\u0309 . "Hook")
292                                              (?\u030C . "v")
293                                              (?\u0323 . "d")
294                                              (?\u0327 . "c")
295                                              ))))
296                  (delete-char)
297                  (setq base (car ret))
298                  (if (and (setq ret (char-feature base '=decomposition))
299                           (setq modifier-1
300                                 (assq (car modifier)
301                                       (cdr
302                                        (assq (nth 1 ret)
303                                              '((?\u0302
304                                                 (?\u0300 . "CircGrave")
305                                                 (?\u0301 . "CircAcute")
306                                                 (?\u0303 . "CircTilde")
307                                                 (?\u0309 . "CircHook")
308                                                 )
309                                                (?\u031B
310                                                 (?\u0301 . "HornAcute")
311                                                 )
312                                                (?\u0323
313                                                 (?\u0302 . "Circudot")
314                                                 )))))))
315                      (insert (format "\\%s{%c}" (cdr modifier-1) (car ret)))
316                    (insert (format "\\%s{%c}" (cdr modifier) base))))
317                 ((and (or (encode-char chr '=jis-x0213-1-2000)
318                           (encode-char chr '=jis-x0213-2-2000))
319                       (setq ret (or (encode-char chr '=ucs@jis/2000)
320                                     (encode-char chr '=ucs@jis/fw)))
321                       (<= ret #xFFFF))
322                  (delete-char)
323                  ;; (if (eq (char-before) ?\e$B!T\e(B)
324                  ;;     (insert " "))
325                  (insert (format "\\UCSjis{%04X}" ret)))
326                 ((chise-tex-encode-ucs-char-at-point chr))
327                 (t
328                  (forward-char))))))))
329
330 (defun chise-tex-encode-region-for-utf-8-jis (start end)
331   (interactive "r")
332   (save-excursion
333     (save-restriction
334       (narrow-to-region start end)
335       (goto-char start)
336       (let ((font-encoding 'T1)
337             chr ret
338             ;; rest spec
339             modifier base modifier-1 pos)
340         (while (and (skip-chars-forward "\x00-\x7F")
341                     (not (eobp)))
342           (setq chr (char-after))
343           (cond
344            ((and (setq ret (encode-char chr '=ucs))
345                  (and (<= #x0400 ret)(<= ret #x04F9)))
346             (if (eq font-encoding 'T2A)
347                 (forward-char)
348               (setq pos (point))
349               (unless (and (prog1
350                                (search-backward
351                                 "\\fontencoding{T2A}\\selectfont{}" nil t)
352                              (goto-char pos))
353                            (eq pos (match-end 0)))
354                 (insert "\\fontencoding{T2A}\\selectfont{}")
355                 )
356               (forward-char)
357               (setq font-encoding 'T2A))
358             )
359            ((and (setq ret (encode-char chr '=ucs))
360                  (and (<= #x0374 ret)(<= ret #x03F3)))
361             (if (eq font-encoding 'LGR)
362                 (forward-char)
363               (setq pos (point))
364               (unless (and (prog1
365                                (search-backward
366                                 "\\fontencoding{LGR}\\selectfont{}" nil t)
367                              (goto-char pos))
368                            (eq pos (match-end 0)))
369                 (insert "\\fontencoding{LGR}\\selectfont{}")
370                 )
371               (forward-char)
372               (setq font-encoding 'LGR))
373             (skip-chars-forward "\u0374-\u03F3")
374             (unless (eq font-encoding 'T1)
375               (unless (looking-at
376                        "\\\\fontencoding{T1}\\\\selectfont{}")
377                 (insert "\\fontencoding{T1}\\selectfont{}")
378                 )
379               (setq font-encoding 'T1))
380             )
381            (t
382             (unless (eq font-encoding 'T1)
383               (setq pos (point))
384               (unless (and (prog1
385                                (search-backward
386                                 "\\fontencoding{T1}\\selectfont{}" nil t)
387                              (goto-char pos))
388                            (eq pos (match-end 0)))
389                 (insert "\\fontencoding{T1}\\selectfont{}")
390                 )
391               (setq font-encoding 'T1))
392             (cond ((eq (char-ucs chr) #x00D7)
393                    (delete-char)
394                    (insert "\\UCSjis{00D7}"))
395                   ((encode-char chr '=jis-x0208-1983)
396                    (forward-char))
397                   ((and (setq ret (char-ucs chr))
398                         (or (eq ret #x00C5)
399                             (eq ret #x00E5)
400                             (eq ret #x1E2B)
401                             ))
402                    (forward-char))
403                   ;; ((setq ret (encode-char chr '=jis-x0208-1990))
404                   ;;  (delete-char)
405                   ;;  (insert (decode-char '=jis-x0208-1983 ret)))
406                   ((eq (char-ucs chr) #x012B)
407                    (delete-char)
408                    (insert "\\={\\i}")
409                    )
410                   ((setq ret (encode-char chr 'thai-tis620))
411                    (delete-char)
412                    (insert (format "\\ThaiTIS{%X}" (logior ret #x80)))
413                    )
414                   ((and (not (eq (char-ucs chr) #x0439))
415                         (not (eq (char-ucs chr) #x0451))
416                         (setq ret (char-feature chr '=decomposition))
417                         (setq modifier (assq (nth 1 ret)
418                                              chise-tex-accent-macro-alist)))
419                    (delete-char)
420                    (setq base (car ret))
421                    (if (and (setq ret (char-feature base '=decomposition))
422                             (setq modifier-1
423                                   (assq (car modifier)
424                                         (cdr
425                                          (assq (nth 1 ret)
426                                                '((?\u0302
427                                                   (?\u0300 . "\\CircGrave{%c}")
428                                                   (?\u0301 . "\\'{\\^%c}")
429                                                   (?\u0303 . "\\~{\\^%c}")
430                                                   (?\u0309 . "\\CircHook{%c}")
431                                                   )
432                                                  (?\u031B
433                                                   (?\u0301 . "\\HornAcute{%c}")
434                                                   (?\u0303 . "\\HornTilde{%c}")
435                                                   )
436                                                  (?\u0323
437                                                   (?\u0302 . "\\Circudot{%c}")
438                                                   )))))))
439                        (insert (format (cdr modifier-1) (car ret)))
440                      (insert (format "\\%s{%c}" (cdr modifier) base))))
441                   ((and (or (encode-char chr '=jis-x0213-1-2000)
442                             (encode-char chr '=jis-x0213-2-2000))
443                         (setq ret (or (encode-char chr '=ucs@jis/2000)
444                                       (encode-char chr '=ucs@jis/fw)))
445                         (<= ret #xFFFF))
446                    ;; (delete-char)
447                    ;; (if (eq (char-before) ?\e$B!T\e(B)
448                    ;;     (insert " "))
449                    ;; (insert (format "\\UCSjis{%04X}" ret))
450                    (forward-char))
451                   ((chise-tex-encode-ucs-char-at-point chr))
452                   (t
453                    (forward-char))))))))))
454
455 (defun chise-tex-decode-region (start end)
456   (interactive "r")
457   (save-excursion
458     (save-restriction
459       (narrow-to-region start end)
460       (goto-char start)
461       (let (macro code ret me rest spec)
462         (while (search-forward "\\={\\i}" nil t)
463           (replace-match "\e.D\eNo" t t))
464         (goto-char start)
465         (while (re-search-forward "\\\\\\(.\\){\\(.\\)}" nil t)
466           (when (and
467                  (setq macro
468                        (assq
469                         (aref (match-string 1) 0)
470                         '((?\` . ?\u0300) ; <COMBINING GRAVE ACCENT>
471                           (?\' . ?\u0301) ; <COMBINING ACUTE ACCENT>
472                           (?^  . ?\u0302) ; <COMBINING CIRCUMFLEX ACCENT>
473                           (?~  . ?\u0303) ; <COMBINING TILDE>
474                           (?=  . ?\u0304) ; <COMBINING MACRON>
475                           (?u  . ?\u0306) ; <COMBINING BREVE>
476                           (?\. . ?\u0307) ; <COMBINING DOT ABOVE>
477                           (?\" . ?\u0308) ; <COMBINING DIAERESIS>
478                           (?v  . ?\u030C) ; <COMBINING CARON>
479                           (?d  . ?\u0323) ; <COMBINING DOT BELOW>
480                           (?c  . ?\u0327) ; <COMBINING CEDILLA>
481                           )))
482                  (setq ret
483                        (cdr (assq (cdr macro)
484                                   (char-feature (aref (match-string 2) 0)
485                                                 'composition)))))
486             (delete-region (match-beginning 0)(match-end 0))
487             (insert ret)))
488         (goto-char start)
489         (while (re-search-forward "\\\\\\([a-zA-Z0-9]+\\){\\([0-9A-Fa-f]+\\)}"
490                                   nil t)
491           (setq macro (match-string 1)
492                 code (match-string 2)
493                 me (match-end 0))
494           (if (and (catch 'tag
495                      (setq rest chise-tex-coded-charset-expression-alist)
496                      (while (setq spec (car rest))
497                        (if (string= (nth 1 spec) macro)
498                            (throw 'tag spec))
499                        (setq rest (cdr rest))))
500                    (setq ret (decode-char (car spec)
501                                           (string-to-int
502                                            code
503                                            (if (eq (nth 3 spec) 'X)
504                                                16)))))
505               (progn
506                 (delete-region (match-beginning 0)(match-end 0))
507                 (insert ret))
508             (goto-char me)))))))
509
510 (make-coding-system
511  'iso-2022-jp-tex-gb 'iso2022
512  "ISO-2022-JP with TeX representation for GB fonts."
513  '(charset-g0 ascii
514    short t
515    seven t
516    ;; input-charset-conversion ((latin-jisx0201 ascii)
517    ;;                        (japanese-jisx0208-1978 japanese-jisx0208))
518    pre-write-conversion chise-tex-encode-region-for-gb
519    post-read-conversion chise-tex-decode-region
520    mnemonic "pTeX(GB)/7bit"
521    ))
522
523 (make-coding-system
524  'iso-2022-jp-tex-jis 'iso2022
525  "ISO-2022-JP with TeX representation for JIS fonts."
526  '(charset-g0 ascii
527    short t
528    seven t
529    ccs-priority-list (ascii
530                       =jis-x0208@1983 =jis-x0208@1978
531                       latin-jisx0201)
532    ;; output-charset-conversion ((=jis-x0208@1990 =jis-x0208@1983))
533    pre-write-conversion chise-tex-encode-region-for-jis
534    post-read-conversion chise-tex-decode-region
535    mnemonic "pTeX(JIS)/7bit"
536    ))
537
538 (make-coding-system
539  'utf-8-jp-tex 'utf-8
540  "Coding-system of UTF-8 for common glyphs used in Japan."
541  '(pre-write-conversion chise-tex-encode-region-for-utf-8-jis
542    post-read-conversion chise-tex-decode-region
543    charset-g0 =ucs@jp
544    charset-g1 =>ucs-jis
545    charset-g2 =>ucs
546    mnemonic "upTeX(JP)/UTF8"))
547
548
549 ;;; @ End.
550 ;;;
551
552 (provide 'chise-tex)
553
554 ;;; chise-tex.el ends here