(chise-tex-encode-ucs-char-at-point): Add setting for U+0250, U+0254,
[chise/uptex-chise.git] / elisp / chise-tex.el
1 ;;; chise-tex.el --- Coding-system based chise2otf like tool
2
3 ;; Copyright (C) 2004,2005,2006,2007,2008,2009 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 ?\u0250)
157       (delete-char)
158       (insert "\\textturna{}")
159       t)
160      ((eq chr ?\u0254)
161       (delete-char)
162       (insert "\\textopeno{}")
163       t)
164      ((eq chr ?\u0264)
165       (delete-char)
166       (insert "\\textramshorns{}")
167       t)
168      ((eq chr ?\u026F)
169       (delete-char)
170       (insert "\\textturnm{}")
171       t)
172      ((eq chr ?\u0282)
173       (delete-char)
174       (insert "{\\usefont{T1}{pxr}{m}{n}\\k{s}}")
175       t)
176      ((eq chr ?\u0294)
177       (delete-char)
178       ;; (insert "\\UCSjis{0294}")
179       (insert "\\textglotstop{}")
180       t)
181      ((eq chr ?\u2022)
182       (delete-char)
183       (insert "\\textbullet{}")
184       t)
185      ((eq chr ?\u2080)
186       (delete-char)
187       (insert "$_0$")
188       t)
189      ((eq chr ?\u2081)
190       (delete-char)
191       (insert "$_1$")
192       t)
193      ((eq chr ?\u2082)
194       (delete-char)
195       (insert "$_2$")
196       t)
197      ((eq chr ?\u2083)
198       (delete-char)
199       (insert "$_3$")
200       t)
201      ((eq chr ?\u2084)
202       (delete-char)
203       (insert "$_4$")
204       t)
205      ((eq chr ?\u2085)
206       (delete-char)
207       (insert "$_5$")
208       t)
209      ((eq chr ?\u2086)
210       (delete-char)
211       (insert "$_6$")
212       t)
213      ((eq chr ?\u2087)
214       (delete-char)
215       (insert "$_7$")
216       t)
217      ((eq chr ?\u2088)
218       (delete-char)
219       (insert "$_8$")
220       t)
221      ((eq chr ?\u2089)
222       (delete-char)
223       (insert "$_9$")
224       t)
225      ((eq chr ?\u208A)
226       (delete-char)
227       (insert "$_+$")
228       t)
229      ((eq chr ?\u208B)
230       (delete-char)
231       (insert "$_-$")
232       t)
233      ((eq chr ?\u208C)
234       (delete-char)
235       (insert "$_=$")
236       t)
237      ((eq chr ?\u208D)
238       (delete-char)
239       (insert "$_($")
240       t)
241      ((eq chr ?\u208E)
242       (delete-char)
243       (insert "$_)$")
244       t)
245      ((eq chr ?\u2637)
246       (delete-char)
247       (insert "\\UCSgb{2637}")
248       t)
249      ((eq (encode-char chr '=ucs@jis) #x8DBC)
250       (delete-char)
251       (insert "\\GTpjG{4933}")
252       t)
253      ((and (encode-char chr '=ucs@jp)
254            (setq ret (char-representative-of-domain chr 'gb))
255            (setq ret (encode-char ret '=ucs@gb))
256            (<= ret #xFFFF))
257       (delete-char)
258       ;; (if (eq (char-before) ?\e$B!T\e(B)
259       ;;     (insert " "))
260       (insert (format "\\UCSgb{%04X}" ret))
261       t)
262      ((catch 'tag
263         (setq rest chise-tex-coded-charset-expression-alist)
264         (while (setq spec (car rest))
265           (if (setq ret (encode-char chr (car spec)))
266               (throw 'tag ret))
267           (setq rest (cdr rest))))
268       (delete-char)
269       ;; (if (eq (char-before) ?\e$B!T\e(B)
270       ;;     (insert " "))
271       (insert (format (format "\\%s{%%0%d%s}"
272                               (nth 1 spec)
273                               (nth 2 spec)
274                               (nth 3 spec))
275                       ret))
276       t)
277      )))
278
279 (defun chise-tex-encode-region-for-jis (start end)
280   (interactive "r")
281   (save-excursion
282     (save-restriction
283       (narrow-to-region start end)
284       (goto-char start)
285       (let (chr ret
286                 ;; rest spec
287                 modifier base modifier-1)
288         (while (and (skip-chars-forward "\x00-\x7F")
289                     (not (eobp)))
290           (setq chr (char-after))
291           (cond ((encode-char chr '=jis-x0208-1983)
292                  (forward-char))
293                 ;; ((setq ret (encode-char chr '=jis-x0208-1990))
294                 ;;  (delete-char)
295                 ;;  (insert (decode-char '=jis-x0208-1983 ret)))
296                 ((and (not (eq (char-ucs chr) #x0439))
297                       (not (eq (char-ucs chr) #x0451))
298                       (setq ret (char-feature chr '=decomposition))
299                       (setq modifier (assq (nth 1 ret)
300                                            '((?\u0300 . "`")
301                                              (?\u0301 . "'")
302                                              (?\u0302 . "^")
303                                              (?\u0303 . "~")
304                                              (?\u0304 . "=")
305                                              (?\u0306 . "u")
306                                              (?\u0307 . ".")
307                                              (?\u0308 . "\"")
308                                              (?\u0309 . "Hook")
309                                              (?\u030C . "v")
310                                              (?\u0323 . "d")
311                                              (?\u0327 . "c")
312                                              ))))
313                  (delete-char)
314                  (setq base (car ret))
315                  (if (and (setq ret (char-feature base '=decomposition))
316                           (setq modifier-1
317                                 (assq (car modifier)
318                                       (cdr
319                                        (assq (nth 1 ret)
320                                              '((?\u0302
321                                                 (?\u0300 . "CircGrave")
322                                                 (?\u0301 . "CircAcute")
323                                                 (?\u0303 . "CircTilde")
324                                                 (?\u0309 . "CircHook")
325                                                 )
326                                                (?\u031B
327                                                 (?\u0301 . "HornAcute")
328                                                 )
329                                                (?\u0323
330                                                 (?\u0302 . "Circudot")
331                                                 )))))))
332                      (insert (format "\\%s{%c}" (cdr modifier-1) (car ret)))
333                    (insert (format "\\%s{%c}" (cdr modifier) base))))
334                 ((and (or (encode-char chr '=jis-x0213-1-2000)
335                           (encode-char chr '=jis-x0213-2-2000))
336                       (setq ret (or (encode-char chr '=ucs@jis/2000)
337                                     (encode-char chr '=ucs@jis/fw)))
338                       (<= ret #xFFFF))
339                  (delete-char)
340                  ;; (if (eq (char-before) ?\e$B!T\e(B)
341                  ;;     (insert " "))
342                  (insert (format "\\UCSjis{%04X}" ret)))
343                 ((chise-tex-encode-ucs-char-at-point chr))
344                 (t
345                  (forward-char))))))))
346
347 (defun chise-tex-encode-region-for-utf-8-jis (start end)
348   (interactive "r")
349   (save-excursion
350     (save-restriction
351       (narrow-to-region start end)
352       (goto-char start)
353       (let ((font-encoding 'T1)
354             chr ret
355             ;; rest spec
356             modifier base modifier-1 pos)
357         (while (and (skip-chars-forward "\x00-\x7F")
358                     (not (eobp)))
359           (setq chr (char-after))
360           (cond
361            ((and (setq ret (encode-char chr '=ucs))
362                  (and (<= #x0400 ret)(<= ret #x04F9)))
363             (if (eq font-encoding 'T2A)
364                 (forward-char)
365               (setq pos (point))
366               ;; (unless (and (prog1
367               ;;                  (search-backward
368               ;;                   "\\fontencoding{T2A}\\selectfont{}" nil t)
369               ;;                (goto-char pos))
370               ;;              (eq pos (match-end 0)))
371               ;;   (insert "\\fontencoding{T2A}\\selectfont{}")
372               ;;   )
373               (if (search-backward "\\CyrillicScript{"
374                                    (- pos (eval-when-compile
375                                             (length "\\CyrillicScript{")))
376                                    t)
377                   (search-forward "}" nil t)
378                 (insert "\\CyrillicScript{")
379                 (forward-char)
380                 (skip-chars-forward "---\u0400-\u04F9 ")
381                 (insert "}"))
382               ;; (setq font-encoding 'T2A)
383               )
384             )
385            ((and (setq ret (encode-char chr '=ucs))
386                  (and (<= #x0374 ret)(<= ret #x03F3)))
387             (if (eq font-encoding 'LGR)
388                 (forward-char)
389               (setq pos (point))
390               ;; (unless (and (prog1
391               ;;                  (search-backward
392               ;;                   "\\fontencoding{LGR}\\selectfont{}" nil t)
393               ;;                (goto-char pos))
394               ;;              (eq pos (match-end 0)))
395               ;;   (insert "\\fontencoding{LGR}\\selectfont{}")
396               ;;   )
397               (if (search-backward "\\GreekScript{"
398                                    (- pos (eval-when-compile
399                                             (length "\\GreekScript{")))
400                                    t)
401                   (search-forward "}" nil t)
402                 (insert "\\GreekScript{")
403                 (forward-char)
404                 (skip-chars-forward "\u0374-\u03F3 ")
405                 (insert "}"))
406               ;; (setq font-encoding 'LGR)
407               )
408             ;; (unless (eq font-encoding 'T1)
409             ;;   (unless (looking-at
410             ;;            "\\\\fontencoding{T1}\\\\selectfont{}")
411             ;;     (insert "\\fontencoding{T1}\\selectfont{}")
412             ;;     )
413             ;;   (setq font-encoding 'T1))
414             )
415            (t
416             (unless (eq font-encoding 'T1)
417               (setq pos (point))
418               (unless (and (prog1
419                                (search-backward
420                                 "\\fontencoding{T1}\\selectfont{}" nil t)
421                              (goto-char pos))
422                            (eq pos (match-end 0)))
423                 (insert "\\fontencoding{T1}\\selectfont{}")
424                 )
425               (setq font-encoding 'T1))
426             (cond ((eq (char-ucs chr) #x00D7)
427                    (delete-char)
428                    (insert "\\UCSjis{00D7}"))
429                   ((encode-char chr '=jis-x0208-1983)
430                    (forward-char))
431                   ((and (setq ret (char-ucs chr))
432                         (or (eq ret #x00C5)
433                             (eq ret #x00E5)
434                             (eq ret #x1E2B)
435                             ))
436                    (forward-char))
437                   ;; ((setq ret (encode-char chr '=jis-x0208-1990))
438                   ;;  (delete-char)
439                   ;;  (insert (decode-char '=jis-x0208-1983 ret)))
440                   ((eq (char-ucs chr) #x012B)
441                    (delete-char)
442                    (insert "\\={\\i}")
443                    )
444                   ((setq ret (encode-char chr 'thai-tis620))
445                    (delete-char)
446                    (insert (format "\\ThaiTIS{%X}" (logior ret #x80)))
447                    )
448                   ((and (not (eq (char-ucs chr) #x0439))
449                         (not (eq (char-ucs chr) #x0451))
450                         (setq ret (char-feature chr '=decomposition))
451                         (setq modifier (assq (nth 1 ret)
452                                              chise-tex-accent-macro-alist)))
453                    (delete-char)
454                    (setq base (car ret))
455                    (if (and (setq ret (char-feature base '=decomposition))
456                             (setq modifier-1
457                                   (assq (car modifier)
458                                         (cdr
459                                          (assq (nth 1 ret)
460                                                '((?\u0302
461                                                   (?\u0300 . "\\CircGrave{%c}")
462                                                   (?\u0301 . "\\'{\\^%c}")
463                                                   (?\u0303 . "\\~{\\^%c}")
464                                                   (?\u0309 . "\\CircHook{%c}")
465                                                   )
466                                                  (?\u031B
467                                                   (?\u0301 . "\\HornAcute{%c}")
468                                                   (?\u0303 . "\\HornTilde{%c}")
469                                                   )
470                                                  (?\u0323
471                                                   (?\u0302 . "\\Circudot{%c}")
472                                                   )))))))
473                        (insert (format (cdr modifier-1) (car ret)))
474                      (insert (format "\\%s{%c}" (cdr modifier) base))))
475                   ((and (or (encode-char chr '=jis-x0213-1-2000)
476                             (encode-char chr '=jis-x0213-2-2000))
477                         (setq ret (or (encode-char chr '=ucs@jis/2000)
478                                       (encode-char chr '=ucs@jis/fw)))
479                         (<= ret #xFFFF))
480                    ;; (delete-char)
481                    ;; (if (eq (char-before) ?\e$B!T\e(B)
482                    ;;     (insert " "))
483                    ;; (insert (format "\\UCSjis{%04X}" ret))
484                    (forward-char))
485                   ((chise-tex-encode-ucs-char-at-point chr))
486                   (t
487                    (forward-char))))))))))
488
489 (defun chise-tex-decode-region (start end)
490   (interactive "r")
491   (save-excursion
492     (save-restriction
493       (narrow-to-region start end)
494       (goto-char start)
495       (let (macro code ret me rest spec)
496         (while (search-forward "\\={\\i}" nil t)
497           (replace-match "\e.D\eNo" t t))
498         (goto-char start)
499         (while (re-search-forward "\\\\\\(.\\){\\(.\\)}" nil t)
500           (when (and
501                  (setq macro
502                        (assq
503                         (aref (match-string 1) 0)
504                         '((?\` . ?\u0300) ; <COMBINING GRAVE ACCENT>
505                           (?\' . ?\u0301) ; <COMBINING ACUTE ACCENT>
506                           (?^  . ?\u0302) ; <COMBINING CIRCUMFLEX ACCENT>
507                           (?~  . ?\u0303) ; <COMBINING TILDE>
508                           (?=  . ?\u0304) ; <COMBINING MACRON>
509                           (?u  . ?\u0306) ; <COMBINING BREVE>
510                           (?\. . ?\u0307) ; <COMBINING DOT ABOVE>
511                           (?\" . ?\u0308) ; <COMBINING DIAERESIS>
512                           (?v  . ?\u030C) ; <COMBINING CARON>
513                           (?d  . ?\u0323) ; <COMBINING DOT BELOW>
514                           (?c  . ?\u0327) ; <COMBINING CEDILLA>
515                           )))
516                  (setq ret
517                        (cdr (assq (cdr macro)
518                                   (char-feature (aref (match-string 2) 0)
519                                                 'composition)))))
520             (delete-region (match-beginning 0)(match-end 0))
521             (insert ret)))
522         (goto-char start)
523         (while (re-search-forward "\\\\\\([a-zA-Z0-9]+\\){\\([0-9A-Fa-f]+\\)}"
524                                   nil t)
525           (setq macro (match-string 1)
526                 code (match-string 2)
527                 me (match-end 0))
528           (if (and (catch 'tag
529                      (setq rest chise-tex-coded-charset-expression-alist)
530                      (while (setq spec (car rest))
531                        (if (string= (nth 1 spec) macro)
532                            (throw 'tag spec))
533                        (setq rest (cdr rest))))
534                    (setq ret (decode-char (car spec)
535                                           (string-to-int
536                                            code
537                                            (if (eq (nth 3 spec) 'X)
538                                                16)))))
539               (progn
540                 (delete-region (match-beginning 0)(match-end 0))
541                 (insert ret))
542             (goto-char me)))))))
543
544 (make-coding-system
545  'iso-2022-jp-tex-gb 'iso2022
546  "ISO-2022-JP with TeX representation for GB fonts."
547  '(charset-g0 ascii
548    short t
549    seven t
550    ;; input-charset-conversion ((latin-jisx0201 ascii)
551    ;;                        (japanese-jisx0208-1978 japanese-jisx0208))
552    pre-write-conversion chise-tex-encode-region-for-gb
553    post-read-conversion chise-tex-decode-region
554    mnemonic "pTeX(GB)/7bit"
555    ))
556
557 (make-coding-system
558  'iso-2022-jp-tex-jis 'iso2022
559  "ISO-2022-JP with TeX representation for JIS fonts."
560  '(charset-g0 ascii
561    short t
562    seven t
563    ccs-priority-list (ascii
564                       =jis-x0208@1983 =jis-x0208@1978
565                       latin-jisx0201)
566    ;; output-charset-conversion ((=jis-x0208@1990 =jis-x0208@1983))
567    pre-write-conversion chise-tex-encode-region-for-jis
568    post-read-conversion chise-tex-decode-region
569    mnemonic "pTeX(JIS)/7bit"
570    ))
571
572 (make-coding-system
573  'utf-8-jp-tex 'utf-8
574  "Coding-system of UTF-8 for common glyphs used in Japan."
575  '(pre-write-conversion chise-tex-encode-region-for-utf-8-jis
576    post-read-conversion chise-tex-decode-region
577    charset-g0 =ucs@jp
578    charset-g1 =>ucs-jis
579    charset-g2 =>ucs
580    mnemonic "upTeX(JP)/UTF8"))
581
582
583 ;;; @ End.
584 ;;;
585
586 (provide 'chise-tex)
587
588 ;;; chise-tex.el ends here