An electric test is now passing
[emacs.git] / lisp / international / characters.el
blob012827ba1c65ccbbd3586702731a121e10ac6f86
1 ;;; characters.el --- set syntax and category for multibyte characters
3 ;; Copyright (C) 1997, 2000-2019 Free Software Foundation, Inc.
4 ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
5 ;; 2005, 2006, 2007, 2008, 2009, 2010, 2011
6 ;; National Institute of Advanced Industrial Science and Technology (AIST)
7 ;; Registration Number H14PRO021
8 ;; Copyright (C) 2003
9 ;; National Institute of Advanced Industrial Science and Technology (AIST)
10 ;; Registration Number H13PRO009
12 ;; Keywords: multibyte character, character set, syntax, category
14 ;; This file is part of GNU Emacs.
16 ;; GNU Emacs is free software: you can redistribute it and/or modify
17 ;; it under the terms of the GNU General Public License as published by
18 ;; the Free Software Foundation, either version 3 of the License, or
19 ;; (at your option) any later version.
21 ;; GNU Emacs is distributed in the hope that it will be useful,
22 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
23 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 ;; GNU General Public License for more details.
26 ;; You should have received a copy of the GNU General Public License
27 ;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
29 ;;; Commentary:
31 ;;; Code:
33 ;;; Predefined categories.
35 ;; For each character set.
37 (define-category ?a "ASCII
38 ASCII graphic characters 32-126 (ISO646 IRV:1983[4/0])")
39 (define-category ?l "Latin")
40 (define-category ?t "Thai")
41 (define-category ?g "Greek")
42 (define-category ?b "Arabic")
43 (define-category ?w "Hebrew")
44 (define-category ?y "Cyrillic")
45 (define-category ?k "Katakana
46 Japanese katakana")
47 (define-category ?r "Roman
48 Japanese roman")
49 (define-category ?c "Chinese")
50 (define-category ?j "Japanese")
51 (define-category ?h "Korean")
52 (define-category ?e "Ethiopic
53 Ethiopic (Ge'ez)")
54 (define-category ?v "Viet
55 Vietnamese")
56 (define-category ?i "Indian")
57 (define-category ?o "Lao")
58 (define-category ?q "Tibetan")
60 ;; For each group (row) of 2-byte character sets.
62 (define-category ?A "2-byte alnum
63 Alpha-numeric characters of 2-byte character sets")
64 (define-category ?C "2-byte han
65 Chinese (Han) characters of 2-byte character sets")
66 (define-category ?G "2-byte Greek
67 Greek characters of 2-byte character sets")
68 (define-category ?H "2-byte Hiragana
69 Japanese Hiragana characters of 2-byte character sets")
70 (define-category ?K "2-byte Katakana
71 Japanese Katakana characters of 2-byte character sets")
72 (define-category ?N "2-byte Korean
73 Korean Hangul characters of 2-byte character sets")
74 (define-category ?Y "2-byte Cyrillic
75 Cyrillic characters of 2-byte character sets")
76 (define-category ?I "Indian Glyphs")
78 ;; For phonetic classifications.
80 (define-category ?0 "consonant")
81 (define-category ?1 "base vowel
82 Base (independent) vowel")
83 (define-category ?2 "upper diacritic
84 Upper diacritical mark (including upper vowel)")
85 (define-category ?3 "lower diacritic
86 Lower diacritical mark (including lower vowel)")
87 (define-category ?4 "combining tone
88 Combining tone mark")
89 (define-category ?5 "symbol")
90 (define-category ?6 "digit")
91 (define-category ?7 "vowel diacritic
92 Vowel-modifying diacritical mark")
93 (define-category ?8 "vowel-signs")
94 (define-category ?9 "semivowel lower")
96 ;; For filling.
97 (define-category ?| "line breakable
98 While filling, we can break a line at this character.")
100 ;; For indentation calculation.
101 (define-category ?\s
102 "space for indent
103 This character counts as a space for indentation purposes.")
105 ;; Keep the following for `kinsoku' processing. See comments in
106 ;; kinsoku.el.
107 (define-category ?> "Not at bol
108 A character which can't be placed at beginning of line.")
109 (define-category ?< "Not at eol
110 A character which can't be placed at end of line.")
112 ;; Base and Combining
113 (define-category ?. "Base
114 Base characters (Unicode General Category L,N,P,S,Zs)")
115 (define-category ?^ "Combining
116 Combining diacritic or mark (Unicode General Category M)")
118 ;; bidi types
119 (define-category ?R "Right-to-left (strong)
120 Characters with \"strong\" right-to-left directionality, i.e.
121 with R, AL, RLE, or RLO Unicode bidi character type.")
123 (define-category ?L "Left-to-right (strong)
124 Characters with \"strong\" left-to-right directionality, i.e.
125 with L, LRE, or LRO Unicode bidi character type.")
128 ;;; Setting syntax and category.
130 ;; ASCII
132 ;; All ASCII characters have the category `a' (ASCII) and `l' (Latin).
133 (modify-category-entry '(32 . 127) ?a)
134 (modify-category-entry '(32 . 127) ?l)
136 ;; Deal with the CJK charsets first. Since the syntax of blocks is
137 ;; defined per charset, and the charsets may contain e.g. Latin
138 ;; characters, we end up with the wrong syntax definitions if we're
139 ;; not careful.
141 ;; Chinese characters (Unicode)
142 (modify-category-entry '(#x2E80 . #x312F) ?|)
143 (modify-category-entry '(#x3190 . #x33FF) ?|)
144 (modify-category-entry '(#x3400 . #x4DB5) ?C)
145 (modify-category-entry '(#x4E00 . #x9FD5) ?C)
146 (modify-category-entry '(#x3400 . #x9FD5) ?c)
147 (modify-category-entry '(#x3400 . #x9FD5) ?|)
148 (modify-category-entry '(#xF900 . #xFAFF) ?C)
149 (modify-category-entry '(#xF900 . #xFAFF) ?c)
150 (modify-category-entry '(#xF900 . #xFAFF) ?|)
151 (modify-category-entry '(#x1B170 . #x1B2FF) ?c)
152 (modify-category-entry '(#x20000 . #x2FFFF) ?|)
153 (modify-category-entry '(#x20000 . #x2FFFF) ?C)
154 (modify-category-entry '(#x20000 . #x2FFFF) ?c)
157 ;; Chinese character set (GB2312)
159 (map-charset-chars #'modify-syntax-entry 'chinese-gb2312 "_" #x2121 #x217E)
160 (map-charset-chars #'modify-syntax-entry 'chinese-gb2312 "_" #x2221 #x227E)
161 (map-charset-chars #'modify-syntax-entry 'chinese-gb2312 "_" #x2921 #x297E)
163 (map-charset-chars #'modify-category-entry 'chinese-gb2312 ?c)
164 (map-charset-chars #'modify-category-entry 'chinese-gb2312 ?A #x2330 #x2339)
165 (map-charset-chars #'modify-category-entry 'chinese-gb2312 ?A #x2341 #x235A)
166 (map-charset-chars #'modify-category-entry 'chinese-gb2312 ?A #x2361 #x237A)
167 (map-charset-chars #'modify-category-entry 'chinese-gb2312 ?H #x2421 #x247E)
168 (map-charset-chars #'modify-category-entry 'chinese-gb2312 ?K #x2521 #x257E)
169 (map-charset-chars #'modify-category-entry 'chinese-gb2312 ?G #x2621 #x267E)
170 (map-charset-chars #'modify-category-entry 'chinese-gb2312 ?Y #x2721 #x277E)
171 (map-charset-chars #'modify-category-entry 'chinese-gb2312 ?C #x3021 #x7E7E)
173 ;; Chinese character set (BIG5)
175 (map-charset-chars #'modify-category-entry 'big5 ?c)
176 (map-charset-chars #'modify-category-entry 'big5 ?C #xA259 #xA261)
177 (map-charset-chars #'modify-category-entry 'big5 ?C #xA440 #xC67E)
178 (map-charset-chars #'modify-category-entry 'big5 ?C #xC940 #xF9DC)
180 ;; Chinese character set (CNS11643)
182 (dolist (c '(chinese-cns11643-1 chinese-cns11643-2 chinese-cns11643-3
183 chinese-cns11643-4 chinese-cns11643-5 chinese-cns11643-6
184 chinese-cns11643-7))
185 (map-charset-chars #'modify-category-entry c ?c)
186 (if (eq c 'chinese-cns11643-1)
187 (map-charset-chars #'modify-category-entry c ?C #x4421 #x7E7E)
188 (map-charset-chars #'modify-category-entry c ?C)))
190 ;; Japanese character set (JISX0201, JISX0208, JISX0212, JISX0213)
192 (map-charset-chars #'modify-category-entry 'katakana-jisx0201 ?k)
194 (map-charset-chars #'modify-category-entry 'latin-jisx0201 ?r)
196 (dolist (l '(katakana-jisx0201 japanese-jisx0208 japanese-jisx0212
197 japanese-jisx0213-1 japanese-jisx0213-2
198 japanese-jisx0213.2004-1
199 cp932-2-byte))
200 (map-charset-chars #'modify-category-entry l ?j))
202 ;; Fullwidth characters
203 (modify-category-entry '(#xff01 . #xff60) ?\|)
205 ;; Unicode equivalents of JISX0201-kana
206 (let ((range '(#xff61 . #xff9f)))
207 (modify-category-entry range ?k)
208 (modify-category-entry range ?j)
209 (modify-category-entry range ?\|))
211 ;; Katakana block
212 (modify-category-entry '(#x3099 . #x309C) ?K)
213 (modify-category-entry '(#x30A0 . #x30FF) ?K)
214 (modify-category-entry '(#x31F0 . #x31FF) ?K)
215 (modify-category-entry '(#x30A0 . #x30FA) ?\|)
216 (modify-category-entry #x30FF ?\|)
218 ;; Hiragana block
219 (modify-category-entry '(#x3040 . #x309F) ?H)
220 (modify-category-entry '(#x3040 . #x3096) ?\|)
221 (modify-category-entry #x309F ?\|)
222 (modify-category-entry #x30A0 ?H)
223 (modify-category-entry #x30FC ?H)
225 (modify-category-entry '(#x1B000 . #x1B1FF) ?j)
228 ;; JISX0208
229 (map-charset-chars #'modify-syntax-entry 'japanese-jisx0208 "_" #x2121 #x227E)
230 (map-charset-chars #'modify-syntax-entry 'japanese-jisx0208 "_" #x2821 #x287E)
231 (let ((chars '(?ー ?゛ ?゜ ?ヽ ?ヾ ?ゝ ?ゞ ?〃 ?仝 ?々 ?〆 ?〇)))
232 (dolist (elt chars)
233 (modify-syntax-entry elt "w")))
235 (map-charset-chars #'modify-category-entry 'japanese-jisx0208 ?A #x2321 #x237E)
236 (map-charset-chars #'modify-category-entry 'japanese-jisx0208 ?H #x2421 #x247E)
237 (map-charset-chars #'modify-category-entry 'japanese-jisx0208 ?K #x2521 #x257E)
238 (map-charset-chars #'modify-category-entry 'japanese-jisx0208 ?G #x2621 #x267E)
239 (map-charset-chars #'modify-category-entry 'japanese-jisx0208 ?Y #x2721 #x277E)
240 (map-charset-chars #'modify-category-entry 'japanese-jisx0208 ?C #x3021 #x7E7E)
241 (let ((chars '(?仝 ?々 ?〆 ?〇)))
242 (while chars
243 (modify-category-entry (car chars) ?C)
244 (setq chars (cdr chars))))
246 ;; JISX0212
248 (map-charset-chars #'modify-syntax-entry 'japanese-jisx0212 "_" #x2121 #x237E)
250 ;; JISX0201-Kana
252 (let ((chars '(?。 ?、 ?・)))
253 (while chars
254 (modify-syntax-entry (car chars) ".")
255 (setq chars (cdr chars))))
257 (modify-syntax-entry ?\「 "(」")
258 (modify-syntax-entry ?\」 "(「")
260 ;; Korean character set (KSC5601)
262 (map-charset-chars #'modify-category-entry 'korean-ksc5601 ?h)
264 (map-charset-chars #'modify-syntax-entry 'korean-ksc5601 "_" #x2121 #x227E)
265 (map-charset-chars #'modify-syntax-entry 'korean-ksc5601 "_" #x2621 #x277E)
266 (map-charset-chars #'modify-syntax-entry 'korean-ksc5601 "_" #x2830 #x287E)
267 (map-charset-chars #'modify-syntax-entry 'korean-ksc5601 "_" #x2930 #x297E)
268 (map-charset-chars #'modify-category-entry 'korean-ksc5601 ?A #x2330 #x2339)
269 (map-charset-chars #'modify-category-entry 'korean-ksc5601 ?A #x2341 #x235A)
270 (map-charset-chars #'modify-category-entry 'korean-ksc5601 ?A #x2361 #x237A)
271 (map-charset-chars #'modify-category-entry 'korean-ksc5601 ?G #x2521 #x257E)
272 (map-charset-chars #'modify-category-entry 'korean-ksc5601 ?H #x2A21 #x2A7E)
273 (map-charset-chars #'modify-category-entry 'korean-ksc5601 ?K #x2B21 #x2B7E)
274 (map-charset-chars #'modify-category-entry 'korean-ksc5601 ?Y #x2C21 #x2C7E)
276 ;; These are in more than one charset.
277 (let ((parens (concat "〈〉《》「」『』【】〔〕〖〗〘〙〚〛"
278 "︵︶︷︸︹︺︻︼︽︾︿﹀﹁﹂﹃﹄"
279 "()[]{}"))
280 open close)
281 (dotimes (i (/ (length parens) 2))
282 (setq open (aref parens (* i 2))
283 close (aref parens (1+ (* i 2))))
284 (modify-syntax-entry open (format "(%c" close))
285 (modify-syntax-entry close (format ")%c" open))))
287 ;; Arabic character set
289 (let ((charsets '(arabic-iso8859-6
290 arabic-digit
291 arabic-1-column
292 arabic-2-column)))
293 (while charsets
294 (map-charset-chars #'modify-category-entry (car charsets) ?b)
295 (setq charsets (cdr charsets))))
296 (modify-category-entry '(#x600 . #x6ff) ?b)
297 (modify-category-entry '(#x8a0 . #x8ff) ?b)
298 (modify-category-entry '(#xfb50 . #xfdff) ?b)
299 (modify-category-entry '(#xfe70 . #xfefe) ?b)
301 ;; Cyrillic character set (ISO-8859-5)
303 (modify-syntax-entry ?№ ".")
305 ;; Ethiopic character set
307 (modify-category-entry '(#x1200 . #x1399) ?e)
308 (modify-category-entry '(#x2d80 . #x2dde) ?e)
309 (let ((chars '(?፡ ?። ?፣ ?፤ ?፥ ?፦ ?፧ ?፨)))
310 (while chars
311 (modify-syntax-entry (car chars) ".")
312 (setq chars (cdr chars))))
313 (map-charset-chars #'modify-category-entry 'ethiopic ?e)
315 ;; Hebrew character set (ISO-8859-8)
317 (modify-syntax-entry #x5be ".") ; MAQAF
318 (modify-syntax-entry #x5c0 ".") ; PASEQ
319 (modify-syntax-entry #x5c3 ".") ; SOF PASUQ
320 (modify-syntax-entry #x5f3 ".") ; GERESH
321 (modify-syntax-entry #x5f4 ".") ; GERSHAYIM
323 ;; Indian character set (IS 13194 and other Emacs original Indian charsets)
325 (modify-category-entry '(#x901 . #x970) ?i)
326 (map-charset-chars #'modify-category-entry 'indian-is13194 ?i)
327 (map-charset-chars #'modify-category-entry 'indian-2-column ?i)
329 ;; Lao character set
331 (modify-category-entry '(#xe80 . #xeff) ?o)
332 (map-charset-chars #'modify-category-entry 'lao ?o)
334 (let ((deflist '(("ກ-ຮ" "w" ?0) ; consonant
335 ("ະາຳຽເ-ໄ" "w" ?1) ; vowel base
336 ("ັິ-ືົໍ" "w" ?2) ; vowel upper
337 ("ຸູ" "w" ?3) ; vowel lower
338 ("່-໋" "w" ?4) ; tone mark
339 ("ຼຽ" "w" ?9) ; semivowel lower
340 ("໐-໙" "w" ?6) ; digit
341 ("ຯໆ" "_" ?5) ; symbol
343 elm chars len syntax category to ch i)
344 (while deflist
345 (setq elm (car deflist))
346 (setq chars (car elm)
347 len (length chars)
348 syntax (nth 1 elm)
349 category (nth 2 elm)
350 i 0)
351 (while (< i len)
352 (if (= (aref chars i) ?-)
353 (setq i (1+ i)
354 to (aref chars i))
355 (setq ch (aref chars i)
356 to ch))
357 (while (<= ch to)
358 (unless (string-equal syntax "w")
359 (modify-syntax-entry ch syntax))
360 (modify-category-entry ch category)
361 (setq ch (1+ ch)))
362 (setq i (1+ i)))
363 (setq deflist (cdr deflist))))
365 ;; Thai character set (TIS620)
367 (modify-category-entry '(#xe00 . #xe7f) ?t)
368 (map-charset-chars #'modify-category-entry 'thai-tis620 ?t)
370 (let ((deflist '(;; chars syntax category
371 ("ก-รลว-ฮ" "w" ?0) ; consonant
372 ("ฤฦะาำเ-ๅ" "w" ?1) ; vowel base
373 ("ัิ-ื็๎" "w" ?2) ; vowel upper
374 ("ุ-ฺ" "w" ?3) ; vowel lower
375 ("่-ํ" "w" ?4) ; tone mark
376 ("๐-๙" "w" ?6) ; digit
377 ("ฯๆ฿๏๚๛" "_" ?5) ; symbol
379 elm chars len syntax category to ch i)
380 (while deflist
381 (setq elm (car deflist))
382 (setq chars (car elm)
383 len (length chars)
384 syntax (nth 1 elm)
385 category (nth 2 elm)
386 i 0)
387 (while (< i len)
388 (if (= (aref chars i) ?-)
389 (setq i (1+ i)
390 to (aref chars i))
391 (setq ch (aref chars i)
392 to ch))
393 (while (<= ch to)
394 (unless (string-equal syntax "w")
395 (modify-syntax-entry ch syntax))
396 (modify-category-entry ch category)
397 (setq ch (1+ ch)))
398 (setq i (1+ i)))
399 (setq deflist (cdr deflist))))
401 ;; Tibetan character set
403 (modify-category-entry '(#xf00 . #xfff) ?q)
404 (map-charset-chars #'modify-category-entry 'tibetan ?q)
405 (map-charset-chars #'modify-category-entry 'tibetan-1-column ?q)
407 (let ((deflist '(;; chars syntax category
408 ("ཀ-ཀྵཪ" "w" ?0) ; consonant
409 ("ྐ-ྐྵྺྻྼ" "w" ?0) ;
410 ("ིེཻོཽྀ" "w" ?2) ; upper vowel
411 ("ཾྂྃ྆྇ྈྉྊྋ" "w" ?2) ; upper modifier
412 ("྄ཱུ༙༵༷" "w" ?3) ; lower vowel/modifier
413 ("཰" "w" ?3) ; invisible vowel a
414 ("༠-༩༪-༳" "w" ?6) ; digit
415 ("་།-༒༔ཿ" "." ?|) ; line-break char
416 ("་།༏༐༑༔ཿ" "." ?|) ;
417 ("༈་།-༒༔ཿ༽༴" "." ?>) ; prohibition
418 ("་།༏༐༑༔ཿ" "." ?>) ;
419 ("ༀ-༊༼࿁࿂྅" "." ?<) ; prohibition
420 ("༓༕-༘༚-༟༶༸-༻༾༿྾྿-࿏" "." ?q) ; others
422 elm chars len syntax category to ch i)
423 (while deflist
424 (setq elm (car deflist))
425 (setq chars (car elm)
426 len (length chars)
427 syntax (nth 1 elm)
428 category (nth 2 elm)
429 i 0)
430 (while (< i len)
431 (if (= (aref chars i) ?-)
432 (setq i (1+ i)
433 to (aref chars i))
434 (setq ch (aref chars i)
435 to ch))
436 (while (<= ch to)
437 (unless (string-equal syntax "w")
438 (modify-syntax-entry ch syntax))
439 (modify-category-entry ch category)
440 (setq ch (1+ ch)))
441 (setq i (1+ i)))
442 (setq deflist (cdr deflist))))
444 ;; Vietnamese character set
446 ;; To make a word with Latin characters
447 (map-charset-chars #'modify-category-entry 'vietnamese-viscii-lower ?l)
448 (map-charset-chars #'modify-category-entry 'vietnamese-viscii-lower ?v)
450 (map-charset-chars #'modify-category-entry 'vietnamese-viscii-upper ?l)
451 (map-charset-chars #'modify-category-entry 'vietnamese-viscii-upper ?v)
453 (let ((tbl (standard-case-table))
454 (i 32))
455 (while (< i 128)
456 (let* ((char (decode-char 'vietnamese-viscii-upper i))
457 (charl (decode-char 'vietnamese-viscii-lower i))
458 (uc (encode-char char 'ucs))
459 (lc (encode-char charl 'ucs)))
460 (set-case-syntax-pair char (decode-char 'vietnamese-viscii-lower i)
461 tbl)
462 (if uc (modify-category-entry uc ?v))
463 (if lc (modify-category-entry lc ?v)))
464 (setq i (1+ i))))
466 ;; Tai Viet
467 (let ((deflist '(;; chars syntax category
468 ((?ꪀ. ?ꪯ) "w" ?0) ; consonant
469 ("ꪱꪵꪶ" "w" ?1) ; vowel base
470 ((?ꪹ . ?ꪽ) "w" ?1) ; vowel base
471 ("ꪰꪲꪳꪷꪸꪾ" "w" ?2) ; vowel upper
472 ("ꪴ" "w" ?3) ; vowel lower
473 ("ꫀꫂ" "w" ?1) ; non-combining tone-mark
474 ("꪿꫁" "w" ?4) ; combining tone-mark
475 ((?ꫛ . ?꫟) "_" ?5) ; symbol
477 (dolist (elm deflist)
478 (let ((chars (car elm))
479 (syntax (nth 1 elm))
480 (category (nth 2 elm)))
481 (if (consp chars)
482 (progn
483 (modify-syntax-entry chars syntax)
484 (modify-category-entry chars category))
485 (mapc #'(lambda (x)
486 (modify-syntax-entry x syntax)
487 (modify-category-entry x category))
488 chars)))))
490 ;; Bidi categories
492 ;; If bootstrapping without generated uni-*.el files, table not defined.
493 (let ((table (unicode-property-table-internal 'bidi-class)))
494 (when table
495 (map-char-table (lambda (key val)
496 (cond
497 ((memq val '(R AL RLO RLE))
498 (modify-category-entry key ?R))
499 ((memq val '(L LRE LRO))
500 (modify-category-entry key ?L))))
501 table)))
503 ;; Load uni-mirrored.el and uni-brackets.el if available, so that they
504 ;; get dumped into Emacs. This allows starting Emacs with
505 ;; force-load-messages in ~/.emacs, and avoid infinite recursion in
506 ;; bidi_initialize, which needs to load uni-mirrored.el and
507 ;; uni-brackets.el in order to display the "Loading" messages.
508 (unicode-property-table-internal 'mirroring)
509 (unicode-property-table-internal 'bracket-type)
511 ;; Latin
513 (modify-category-entry '(#x80 . #x024F) ?l)
515 (let ((tbl (standard-case-table)) c)
517 ;; Latin-1
519 ;; Fixme: Some of the non-word syntaxes here perhaps should be
520 ;; reviewed. (Note that the following all implicitly have word
521 ;; syntax: ¢£¤¥¨ª¯²³´¶¸¹º.) There should be a well-defined way of
522 ;; relating Unicode categories to Emacs syntax codes.
524 ;; NBSP isn't semantically interchangeable with other whitespace chars,
525 ;; so it's more like punctuation.
526 (set-case-syntax"." tbl)
527 (set-case-syntax"." tbl)
528 (set-case-syntax"_" tbl)
529 (set-case-syntax"." tbl)
530 (set-case-syntax"_" tbl)
531 ;; French wants
532 ;; (set-case-syntax-delims ?« ?» tbl)
533 ;; And German wants
534 ;; (set-case-syntax-delims ?» ?« tbl)
535 ;; So let's stay neutral and let users set these up if/when they want to.
536 (set-case-syntax"." tbl)
537 (set-case-syntax"." tbl)
538 (set-case-syntax"_" tbl)
539 (set-case-syntax"_" tbl)
540 (set-case-syntax"_" tbl)
541 (set-case-syntax"_" tbl)
542 (set-case-syntax"_" tbl)
543 (set-case-syntax"_" tbl)
544 (set-case-syntax"_" tbl)
545 (set-case-syntax"_" tbl)
546 (set-case-syntax"_" tbl)
547 (set-case-syntax"_" tbl)
548 (set-case-syntax ?¿ "." tbl)
549 (set-case-syntax"_" tbl)
550 (set-case-syntax"w" tbl)
551 (set-case-syntax"_" tbl)
552 ;; See below for ÿ.
554 ;; Latin Extended-A, Latin Extended-B
555 (setq c #x0100)
556 (while (<= c #x02B8)
557 (modify-category-entry c ?l)
558 (setq c (1+ c)))
560 ;; Latin Extended Additional
561 (modify-category-entry '(#x1e00 . #x1ef9) ?l)
563 ;; Latin Extended-C
564 (setq c #x2C60)
565 (while (<= c #x2C7F)
566 (modify-category-entry c ?l)
567 (setq c (1+ c)))
569 ;; Latin Extended-D
570 (setq c #xA720)
571 (while (<= c #xA7FF)
572 (modify-category-entry c ?l)
573 (setq c (1+ c)))
575 ;; Latin Extended-E
576 (setq c #xAB30)
577 (while (<= c #xAB64)
578 (modify-category-entry c ?l)
579 (setq c (1+ c)))
581 ;; Greek
582 (modify-category-entry '(#x0370 . #x03ff) ?g)
584 ;; Armenian
585 (setq c #x531)
587 ;; Greek Extended
588 (modify-category-entry '(#x1f00 . #x1fff) ?g)
590 ;; cyrillic
591 (modify-category-entry '(#x0400 . #x04FF) ?y)
592 (modify-category-entry '(#xA640 . #xA69F) ?y)
594 ;; Georgian
595 (setq c #x10A0)
597 ;; Cyrillic Extended-C
598 (modify-category-entry '(#x1C80 . #x1C8F) ?y)
600 ;; general punctuation
601 (setq c #x2000)
602 (while (<= c #x200b)
603 (set-case-syntax c " " tbl)
604 (setq c (1+ c)))
605 (while (<= c #x200F)
606 (set-case-syntax c "." tbl)
607 (setq c (1+ c)))
608 ;; Fixme: These aren't all right:
609 (setq c #x2010)
610 (while (<= c #x2016)
611 (set-case-syntax c "_" tbl)
612 (setq c (1+ c)))
613 ;; Punctuation syntax for quotation marks (like `)
614 (while (<= c #x201f)
615 (set-case-syntax c "." tbl)
616 (setq c (1+ c)))
617 ;; Fixme: These aren't all right:
618 (while (<= c #x2027)
619 (set-case-syntax c "_" tbl)
620 (setq c (1+ c)))
621 (while (<= c #x206F)
622 (set-case-syntax c "." tbl)
623 (setq c (1+ c)))
625 ;; Fixme: The following blocks might be better as symbol rather than
626 ;; punctuation.
627 ;; Arrows
628 (setq c #x2190)
629 (while (<= c #x21FF)
630 (set-case-syntax c "." tbl)
631 (setq c (1+ c)))
632 ;; Mathematical Operators
633 (while (<= c #x22FF)
634 (set-case-syntax c "." tbl)
635 (setq c (1+ c)))
636 ;; Miscellaneous Technical
637 (while (<= c #x23FF)
638 (set-case-syntax c "." tbl)
639 (setq c (1+ c)))
640 ;; Control Pictures
641 (while (<= c #x243F)
642 (set-case-syntax c "_" tbl)
643 (setq c (1+ c)))
645 ;; Circled Latin
646 (setq c #x24B6)
647 (while (<= c #x24CF)
648 (modify-category-entry c ?l)
649 (modify-category-entry (+ c 26) ?l)
650 (setq c (1+ c)))
652 ;; Supplemental Mathematical Operators
653 (setq c #x2A00)
654 (while (<= c #x2AFF)
655 (set-case-syntax c "." tbl)
656 (setq c (1+ c)))
658 ;; Miscellaneous Symbols and Arrows
659 (setq c #x2B00)
660 (while (<= c #x2BFF)
661 (set-case-syntax c "." tbl)
662 (setq c (1+ c)))
664 ;; Coptic
665 ;; There's no Coptic category. However, Coptic letters that are
666 ;; part of the Greek block above get the Greek category, and those
667 ;; in this block are derived from Greek letters, so let's be
668 ;; consistent about their category.
669 (modify-category-entry '(#x2C80 . #x2CFF) ?g)
671 ;; Supplemental Punctuation
672 (setq c #x2E00)
673 (while (<= c #x2E7F)
674 (set-case-syntax c "." tbl)
675 (setq c (1+ c)))
677 ;; Fullwidth Latin
678 (setq c #xff21)
679 (while (<= c #xff3a)
680 (modify-category-entry c ?l)
681 (modify-category-entry (+ c #x20) ?l)
682 (setq c (1+ c)))
684 ;; Combining diacritics
685 (modify-category-entry '(#x300 . #x362) ?^)
686 ;; Combining marks
687 (modify-category-entry '(#x20d0 . #x20ff) ?^)
689 (let ((gc (unicode-property-table-internal 'general-category))
690 (syn-table (standard-syntax-table)))
691 ;; In early bootstrapping Unicode tables are not available so we need to
692 ;; skip this step in those cases.
693 (when gc
694 ;; Set all Letter, uppercase; Letter, lowercase and Letter,
695 ;; titlecase syntax to word.
696 (map-char-table
697 (lambda (ch cat)
698 (when (memq cat '(Lu Ll Lt))
699 (modify-syntax-entry ch "w " syn-table)))
701 ;; Ⅰ through Ⅻ had word syntax in the past so set it here as well.
702 ;; The general category of those characters is Number, Letter.
703 (modify-syntax-entry '(#x2160 . #x216b) "w " syn-table)
705 ;; ⓐ through ⓩ are symbols, other according to Unicode but Emacs set
706 ;; their syntax to word in the past so keep backwards compatibility.
707 (modify-syntax-entry '(#x24D0 . #x24E9) "w " syn-table)
709 ;; Set downcase and upcase from Unicode properties
711 ;; In some languages, such as Turkish, U+0049 LATIN CAPITAL LETTER I and
712 ;; U+0131 LATIN SMALL LETTER DOTLESS I make a case pair, and so do U+0130
713 ;; LATIN CAPITAL LETTER I WITH DOT ABOVE and U+0069 LATIN SMALL LETTER I.
715 ;; We used to set up half of those correspondence unconditionally, but
716 ;; that makes searches slow. So now we don't set up either half of these
717 ;; correspondences by default.
719 ;; (set-downcase-syntax ?İ ?i tbl)
720 ;; (set-upcase-syntax ?I ?ı tbl)
722 (let ((map-unicode-property
723 (lambda (property func)
724 (map-char-table
725 (lambda (ch cased)
726 ;; ASCII characters skipped due to reasons outlined above. As
727 ;; of Unicode 9.0, this exception affects the following:
728 ;; lc(U+0130 İ) = i
729 ;; uc(U+0131 ı) = I
730 ;; uc(U+017F ſ) = S
731 ;; uc(U+212A K) = k
732 (when (> cased 127)
733 (let ((end (if (consp ch) (cdr ch) ch)))
734 (setq ch (max 128 (if (consp ch) (car ch) ch)))
735 (while (<= ch end)
736 (funcall func ch cased)
737 (setq ch (1+ ch))))))
738 (unicode-property-table-internal property))))
739 (down tbl)
740 (up (case-table-get-table tbl 'up)))
742 ;; This works on an assumption that if toUpper(x) != x then toLower(x)
743 ;; == x (and the opposite for toLower/toUpper). This doesn’t hold for
744 ;; title case characters but those incorrect mappings will be
745 ;; overwritten later.
746 (funcall map-unicode-property 'uppercase
747 (lambda (lc uc) (aset down lc lc) (aset up uc uc)))
748 (funcall map-unicode-property 'lowercase
749 (lambda (uc lc) (aset down lc lc) (aset up uc uc)))
751 ;; Now deal with the actual mapping. This will correctly assign casing
752 ;; for title-case characters.
753 (funcall map-unicode-property 'uppercase
754 (lambda (lc uc) (aset up lc uc) (aset up uc uc)))
755 (funcall map-unicode-property 'lowercase
756 (lambda (uc lc) (aset down uc lc) (aset down lc lc))))))
758 ;; Clear out the extra slots so that they will be recomputed from the main
759 ;; (downcase) table and upcase table. Since we’re side-stepping the usual
760 ;; set-case-syntax-* functions, we need to do it explicitly.
761 (set-char-table-extra-slot tbl 1 nil)
762 (set-char-table-extra-slot tbl 2 nil)
764 ;; Fixme: syntax for symbols &c
767 (let ((pairs
768 '("⁅⁆" ; U+2045 U+2046
769 "⁽⁾" ; U+207D U+207E
770 "₍₎" ; U+208D U+208E
771 "〈〉" ; U+2329 U+232A
772 "⎴⎵" ; U+23B4 U+23B5
773 "❨❩" ; U+2768 U+2769
774 "❪❫" ; U+276A U+276B
775 "❬❭" ; U+276C U+276D
776 "❰❱" ; U+2770 U+2771
777 "❲❳" ; U+2772 U+2773
778 "❴❵" ; U+2774 U+2775
779 "⟦⟧" ; U+27E6 U+27E7
780 "⟨⟩" ; U+27E8 U+27E9
781 "⟪⟫" ; U+27EA U+27EB
782 "⦃⦄" ; U+2983 U+2984
783 "⦅⦆" ; U+2985 U+2986
784 "⦇⦈" ; U+2987 U+2988
785 "⦉⦊" ; U+2989 U+298A
786 "⦋⦌" ; U+298B U+298C
787 "⦍⦎" ; U+298D U+298E
788 "⦏⦐" ; U+298F U+2990
789 "⦑⦒" ; U+2991 U+2992
790 "⦓⦔" ; U+2993 U+2994
791 "⦕⦖" ; U+2995 U+2996
792 "⦗⦘" ; U+2997 U+2998
793 "⧼⧽" ; U+29FC U+29FD
794 "〈〉" ; U+3008 U+3009
795 "《》" ; U+300A U+300B
796 "「」" ; U+300C U+300D
797 "『』" ; U+300E U+300F
798 "【】" ; U+3010 U+3011
799 "〔〕" ; U+3014 U+3015
800 "〖〗" ; U+3016 U+3017
801 "〘〙" ; U+3018 U+3019
802 "〚〛" ; U+301A U+301B
803 "﴾﴿" ; U+FD3E U+FD3F
804 "︵︶" ; U+FE35 U+FE36
805 "︷︸" ; U+FE37 U+FE38
806 "︹︺" ; U+FE39 U+FE3A
807 "︻︼" ; U+FE3B U+FE3C
808 "︽︾" ; U+FE3D U+FE3E
809 "︿﹀" ; U+FE3F U+FE40
810 "﹁﹂" ; U+FE41 U+FE42
811 "﹃﹄" ; U+FE43 U+FE44
812 "﹙﹚" ; U+FE59 U+FE5A
813 "﹛﹜" ; U+FE5B U+FE5C
814 "﹝﹞" ; U+FE5D U+FE5E
815 "()" ; U+FF08 U+FF09
816 "[]" ; U+FF3B U+FF3D
817 "{}" ; U+FF5B U+FF5D
818 "⦅⦆" ; U+FF5F U+FF60
819 "「」" ; U+FF62 U+FF63
821 (dolist (elt pairs)
822 (modify-syntax-entry (aref elt 0) (string ?\( (aref elt 1)))
823 (modify-syntax-entry (aref elt 1) (string ?\) (aref elt 0)))))
826 ;; For each character set, put the information of the most proper
827 ;; coding system to encode it by `preferred-coding-system' property.
829 ;; Fixme: should this be junked?
830 (let ((l '((latin-iso8859-1 . iso-latin-1)
831 (latin-iso8859-2 . iso-latin-2)
832 (latin-iso8859-3 . iso-latin-3)
833 (latin-iso8859-4 . iso-latin-4)
834 (thai-tis620 . thai-tis620)
835 (greek-iso8859-7 . greek-iso-8bit)
836 (arabic-iso8859-6 . iso-2022-7bit)
837 (hebrew-iso8859-8 . hebrew-iso-8bit)
838 (katakana-jisx0201 . japanese-shift-jis)
839 (latin-jisx0201 . japanese-shift-jis)
840 (cyrillic-iso8859-5 . cyrillic-iso-8bit)
841 (latin-iso8859-9 . iso-latin-5)
842 (japanese-jisx0208-1978 . iso-2022-jp)
843 (chinese-gb2312 . chinese-iso-8bit)
844 (chinese-gbk . chinese-gbk)
845 (gb18030-2-byte . chinese-gb18030)
846 (gb18030-4-byte-bmp . chinese-gb18030)
847 (gb18030-4-byte-smp . chinese-gb18030)
848 (gb18030-4-byte-ext-1 . chinese-gb18030)
849 (gb18030-4-byte-ext-2 . chinese-gb18030)
850 (japanese-jisx0208 . iso-2022-jp)
851 (korean-ksc5601 . iso-2022-kr)
852 (japanese-jisx0212 . iso-2022-jp)
853 (chinese-big5-1 . chinese-big5)
854 (chinese-big5-2 . chinese-big5)
855 (chinese-sisheng . iso-2022-7bit)
856 (ipa . iso-2022-7bit)
857 (vietnamese-viscii-lower . vietnamese-viscii)
858 (vietnamese-viscii-upper . vietnamese-viscii)
859 (arabic-digit . iso-2022-7bit)
860 (arabic-1-column . iso-2022-7bit)
861 (lao . lao)
862 (arabic-2-column . iso-2022-7bit)
863 (indian-is13194 . devanagari)
864 (indian-glyph . devanagari)
865 (tibetan-1-column . tibetan)
866 (ethiopic . iso-2022-7bit)
867 (chinese-cns11643-1 . iso-2022-cn)
868 (chinese-cns11643-2 . iso-2022-cn)
869 (chinese-cns11643-3 . iso-2022-cn)
870 (chinese-cns11643-4 . iso-2022-cn)
871 (chinese-cns11643-5 . iso-2022-cn)
872 (chinese-cns11643-6 . iso-2022-cn)
873 (chinese-cns11643-7 . iso-2022-cn)
874 (indian-2-column . devanagari)
875 (tibetan . tibetan)
876 (latin-iso8859-14 . iso-latin-8)
877 (latin-iso8859-15 . iso-latin-9))))
878 (while l
879 (put-charset-property (car (car l)) 'preferred-coding-system (cdr (car l)))
880 (setq l (cdr l))))
883 ;; Setup auto-fill-chars for charsets that should invoke auto-filling.
884 ;; SPACE and NEWLINE are already set.
886 (set-char-table-range auto-fill-chars '(#x3041 . #x30FF) t)
887 (set-char-table-range auto-fill-chars '(#x3400 . #x4DB5) t)
888 (set-char-table-range auto-fill-chars '(#x4e00 . #x9fbb) t)
889 (set-char-table-range auto-fill-chars '(#xF900 . #xFAFF) t)
890 (set-char-table-range auto-fill-chars '(#xFF00 . #xFF9F) t)
891 (set-char-table-range auto-fill-chars '(#x20000 . #x2FFFF) t)
894 ;;; Setting char-width-table. The default is 1.
896 ;; 0: non-spacing, enclosing combining, formatting, Hangul Jamo medial
897 ;; and final characters.
898 (let ((l '((#x0300 . #x036F)
899 (#x0483 . #x0489)
900 (#x0591 . #x05BD)
901 (#x05BF . #x05BF)
902 (#x05C1 . #x05C2)
903 (#x05C4 . #x05C5)
904 (#x05C7 . #x05C7)
905 (#x0600 . #x0605)
906 (#x0610 . #x061C)
907 (#x064B . #x065F)
908 (#x0670 . #x0670)
909 (#x06D6 . #x06E4)
910 (#x06E7 . #x06E8)
911 (#x06EA . #x06ED)
912 (#x070F . #x070F)
913 (#x0711 . #x0711)
914 (#x0730 . #x074A)
915 (#x07A6 . #x07B0)
916 (#x07EB . #x07F3)
917 (#x0816 . #x0823)
918 (#x0825 . #x082D)
919 (#x0859 . #x085B)
920 (#x08D4 . #x0902)
921 (#x093A . #x093A)
922 (#x093C . #x093C)
923 (#x0941 . #x0948)
924 (#x094D . #x094D)
925 (#x0951 . #x0957)
926 (#x0962 . #x0963)
927 (#x0981 . #x0981)
928 (#x09BC . #x09BC)
929 (#x09C1 . #x09C4)
930 (#x09CD . #x09CD)
931 (#x09E2 . #x09E3)
932 (#x0A01 . #x0A02)
933 (#x0A3C . #x0A3C)
934 (#x0A41 . #x0A4D)
935 (#x0A41 . #x0A42)
936 (#x0A47 . #x0A48)
937 (#x0A4B . #x0A4D)
938 (#x0A51 . #x0A51)
939 (#x0A70 . #x0A71)
940 (#x0A75 . #x0A75)
941 (#x0A81 . #x0A82)
942 (#x0ABC . #x0ABC)
943 (#x0AC1 . #x0AC8)
944 (#x0ACD . #x0ACD)
945 (#x0AE2 . #x0AE3)
946 (#x0B01 . #x0B01)
947 (#x0B3C . #x0B3C)
948 (#x0B3F . #x0B3F)
949 (#x0B41 . #x0B44)
950 (#x0B4D . #x0B56)
951 (#x0B62 . #x0B63)
952 (#x0B82 . #x0B82)
953 (#x0BC0 . #x0BC0)
954 (#x0BCD . #x0BCD)
955 (#x0C00 . #x0C00)
956 (#x0C3E . #x0C40)
957 (#x0C46 . #x0C56)
958 (#x0C62 . #x0C63)
959 (#x0C81 . #x0C81)
960 (#x0CBC . #x0CBC)
961 (#x0CCC . #x0CCD)
962 (#x0CE2 . #x0CE3)
963 (#x0D01 . #x0D01)
964 (#x0D41 . #x0D44)
965 (#x0D4D . #x0D4D)
966 (#x0D62 . #x0D63)
967 (#x0DCA . #x0DCA)
968 (#x0DD2 . #x0DD6)
969 (#x0E31 . #x0E31)
970 (#x0E34 . #x0E3A)
971 (#x0E47 . #x0E4E)
972 (#x0EB1 . #x0EB1)
973 (#x0EB4 . #x0EBC)
974 (#x0EC8 . #x0ECD)
975 (#x0F18 . #x0F19)
976 (#x0F35 . #x0F35)
977 (#x0F37 . #x0F37)
978 (#x0F39 . #x0F39)
979 (#x0F71 . #x0F7E)
980 (#x0F80 . #x0F84)
981 (#x0F86 . #x0F87)
982 (#x0F8D . #x0FBC)
983 (#x0FC6 . #x0FC6)
984 (#x102D . #x1030)
985 (#x1032 . #x1037)
986 (#x1039 . #x103A)
987 (#x103D . #x103E)
988 (#x1058 . #x1059)
989 (#x105E . #x1160)
990 (#x1071 . #x1074)
991 (#x1082 . #x1082)
992 (#x1085 . #x1086)
993 (#x108D . #x108D)
994 (#x109D . #x109D)
995 (#x1160 . #x11FF)
996 (#x135D . #x135F)
997 (#x1712 . #x1714)
998 (#x1732 . #x1734)
999 (#x1752 . #x1753)
1000 (#x1772 . #x1773)
1001 (#x17B4 . #x17B5)
1002 (#x17B7 . #x17BD)
1003 (#x17C6 . #x17C6)
1004 (#x17C9 . #x17D3)
1005 (#x17DD . #x17DD)
1006 (#x180B . #x180E)
1007 (#x18A9 . #x18A9)
1008 (#x1885 . #x1886)
1009 (#x18A9 . #x18A9)
1010 (#x1920 . #x1922)
1011 (#x1927 . #x1928)
1012 (#x1932 . #x1932)
1013 (#x1939 . #x193B)
1014 (#x1A17 . #x1A18)
1015 (#x1A1B . #x1A1B)
1016 (#x1A56 . #x1A56)
1017 (#x1A58 . #x1A5E)
1018 (#x1A60 . #x1A60)
1019 (#x1A62 . #x1A62)
1020 (#x1A65 . #x1A6C)
1021 (#x1A73 . #x1A7C)
1022 (#x1A7F . #x1A7F)
1023 (#x1AB0 . #x1ABE)
1024 (#x1B00 . #x1B03)
1025 (#x1B34 . #x1B34)
1026 (#x1B36 . #x1B3A)
1027 (#x1B3C . #x1B3C)
1028 (#x1B42 . #x1B42)
1029 (#x1B6B . #x1B73)
1030 (#x1B80 . #x1B81)
1031 (#x1BA2 . #x1BA5)
1032 (#x1BA8 . #x1BA9)
1033 (#x1BAB . #x1BAD)
1034 (#x1BE6 . #x1BE6)
1035 (#x1BE8 . #x1BE9)
1036 (#x1BED . #x1BED)
1037 (#x1BEF . #x1BF1)
1038 (#x1C2C . #x1C33)
1039 (#x1C36 . #x1C37)
1040 (#x1CD0 . #x1CD2)
1041 (#x1CD4 . #x1CE0)
1042 (#x1CE2 . #x1CE8)
1043 (#x1CED . #x1CED)
1044 (#x1CF4 . #x1CF4)
1045 (#x1CF8 . #x1CF9)
1046 (#x1DC0 . #x1DFF)
1047 (#x200B . #x200F)
1048 (#x202A . #x202E)
1049 (#x2060 . #x206F)
1050 (#x20D0 . #x20F0)
1051 (#x2CEF . #x2CF1)
1052 (#x2D7F . #x2D7F)
1053 (#x2DE0 . #x2DFF)
1054 (#xA66F . #xA672)
1055 (#xA674 . #xA69F)
1056 (#xA6F0 . #xA6F1)
1057 (#xA802 . #xA802)
1058 (#xA806 . #xA806)
1059 (#xA80B . #xA80B)
1060 (#xA825 . #xA826)
1061 (#xA8C4 . #xA8C5)
1062 (#xA8E0 . #xA8F1)
1063 (#xA926 . #xA92D)
1064 (#xA947 . #xA951)
1065 (#xA980 . #xA9B3)
1066 (#xA9B6 . #xA9B9)
1067 (#xA9BC . #xA9BC)
1068 (#xA9E5 . #xA9E5)
1069 (#xAA29 . #xAA2E)
1070 (#xAA31 . #xAA32)
1071 (#xAA35 . #xAA36)
1072 (#xAA43 . #xAA43)
1073 (#xAA4C . #xAA4C)
1074 (#xAA7C . #xAA7C)
1075 (#xAAB0 . #xAAB0)
1076 (#xAAB2 . #xAAB4)
1077 (#xAAB7 . #xAAB8)
1078 (#xAABE . #xAABF)
1079 (#xAAC1 . #xAAC1)
1080 (#xAAEC . #xAAED)
1081 (#xAAF6 . #xAAF6)
1082 (#xABE5 . #xABE5)
1083 (#xABE8 . #xABE8)
1084 (#xABED . #xABED)
1085 (#xD7B0 . #xD7FB)
1086 (#xFB1E . #xFB1E)
1087 (#xFE00 . #xFE0F)
1088 (#xFE20 . #xFE2F)
1089 (#xFEFF . #xFEFF)
1090 (#xFFF9 . #xFFFB)
1091 (#x101FD . #x101FD)
1092 (#x102E0 . #x102E0)
1093 (#x10376 . #x1037A)
1094 (#x10A01 . #x10A0F)
1095 (#x10A38 . #x10A3F)
1096 (#x10AE5 . #x10AE6)
1097 (#x11001 . #x11001)
1098 (#x11038 . #x11046)
1099 (#x1107F . #x11081)
1100 (#x110B3 . #x110B6)
1101 (#x110B9 . #x110BA)
1102 (#x110BD . #x110BD)
1103 (#x11100 . #x11102)
1104 (#x11127 . #x1112B)
1105 (#x1112D . #x11134)
1106 (#x11173 . #x11173)
1107 (#x11180 . #x11181)
1108 (#x111B6 . #x111BE)
1109 (#x111CA . #x111CC)
1110 (#x1122F . #x11231)
1111 (#x11234 . #x11234)
1112 (#x11236 . #x11237)
1113 (#x1123E . #x1123E)
1114 (#x112DF . #x112DF)
1115 (#x112E3 . #x112EA)
1116 (#x11300 . #x11301)
1117 (#x1133C . #x1133C)
1118 (#x11340 . #x11340)
1119 (#x11366 . #x1136C)
1120 (#x11370 . #x11374)
1121 (#x11438 . #x1143F)
1122 (#x11442 . #x11444)
1123 (#x11446 . #x11446)
1124 (#x114B3 . #x114B8)
1125 (#x114BA . #x114C0)
1126 (#x114C2 . #x114C3)
1127 (#x115B2 . #x115B5)
1128 (#x115BC . #x115BD)
1129 (#x115BF . #x115C0)
1130 (#x115DC . #x115DD)
1131 (#x11633 . #x1163A)
1132 (#x1163D . #x1163D)
1133 (#x1163F . #x11640)
1134 (#x116AB . #x116AB)
1135 (#x116AD . #x116AD)
1136 (#x116B0 . #x116B5)
1137 (#x116B7 . #x116B7)
1138 (#x1171D . #x1171F)
1139 (#x11722 . #x11725)
1140 (#x11727 . #x1172B)
1141 (#x11C30 . #x11C36)
1142 (#x11C38 . #x11C3D)
1143 (#x11C92 . #x11CA7)
1144 (#x11CAA . #x11CB0)
1145 (#x11CB2 . #x11CB3)
1146 (#x11CB5 . #x11CB6)
1147 (#x16AF0 . #x16AF4)
1148 (#x16B30 . #x16B36)
1149 (#x16F8F . #x16F92)
1150 (#x1BC9D . #x1BC9E)
1151 (#x1BCA0 . #x1BCA3)
1152 (#x1D167 . #x1D169)
1153 (#x1D173 . #x1D182)
1154 (#x1D185 . #x1D18B)
1155 (#x1D1AA . #x1D1AD)
1156 (#x1D242 . #x1D244)
1157 (#x1DA00 . #x1DA36)
1158 (#x1DA3B . #x1DA6C)
1159 (#x1DA75 . #x1DA75)
1160 (#x1DA84 . #x1DA84)
1161 (#x1DA9B . #x1DA9F)
1162 (#x1DAA1 . #x1DAAF)
1163 (#x1E000 . #x1E006)
1164 (#x1E008 . #x1E018)
1165 (#x1E01B . #x1E021)
1166 (#x1E023 . #x1E024)
1167 (#x1E026 . #x1E02A)
1168 (#x1E8D0 . #x1E8D6)
1169 (#x1E944 . #x1E94A)
1170 (#xE0001 . #xE01EF))))
1171 (dolist (elt l)
1172 (set-char-table-range char-width-table elt 0)))
1174 ;; 2: East Asian Wide and Full-width characters.
1175 (let ((l '((#x1100 . #x115F)
1176 (#x231A . #x231B)
1177 (#x2329 . #x232A)
1178 (#x23E9 . #x23EC)
1179 (#x23F0 . #x23F0)
1180 (#x23F3 . #x23F3)
1181 (#x25FD . #x25FE)
1182 (#x2614 . #x2615)
1183 (#x2648 . #x2653)
1184 (#x267F . #x267F)
1185 (#x2693 . #x2693)
1186 (#x26A1 . #x26A1)
1187 (#x26AA . #x26AB)
1188 (#x26BD . #x26BE)
1189 (#x26C4 . #x26C5)
1190 (#x26CE . #x26CE)
1191 (#x26D4 . #x26D4)
1192 (#x26EA . #x26EA)
1193 (#x26F2 . #x26F3)
1194 (#x26F5 . #x26F5)
1195 (#x26FA . #x26FA)
1196 (#x26FD . #x26FD)
1197 (#x2705 . #x2705)
1198 (#x270A . #x270B)
1199 (#x2728 . #x2728)
1200 (#x274C . #x274C)
1201 (#x274E . #x274E)
1202 (#x2753 . #x2755)
1203 (#x2757 . #x2757)
1204 (#x2795 . #x2797)
1205 (#x27B0 . #x27B0)
1206 (#x27BF . #x27BF)
1207 (#x2B1B . #x2B1C)
1208 (#x2B50 . #x2B50)
1209 (#x2B55 . #x2B55)
1210 (#x2E80 . #x303E)
1211 (#x3040 . #x3247)
1212 (#x3250 . #x4DBF)
1213 (#x4E00 . #xA4CF)
1214 (#xA490 . #xA4C6)
1215 (#xA960 . #xA97F)
1216 (#xAC00 . #xD7A3)
1217 (#xF900 . #xFAFF)
1218 (#xFE10 . #xFE19)
1219 (#xFE30 . #xFE6F)
1220 (#xFF01 . #xFF60)
1221 (#xFFE0 . #xFFE6)
1222 (#x16FE0 . #x16FE3)
1223 (#x17000 . #x187F7)
1224 (#x18800 . #x18AF2)
1225 (#x1B000 . #x1B152)
1226 (#x1B164 . #x1B167)
1227 (#x1B170 . #x1B2FB)
1228 (#x1F004 . #x1F004)
1229 (#x1F0CF . #x1F0CF)
1230 (#x1F18E . #x1F18E)
1231 (#x1F191 . #x1F19A)
1232 (#x1F200 . #x1F320)
1233 (#x1F32D . #x1F335)
1234 (#x1F337 . #x1F37C)
1235 (#x1F37E . #x1F393)
1236 (#x1F3A0 . #x1F3CA)
1237 (#x1F3CF . #x1F3D3)
1238 (#x1F3E0 . #x1F3F0)
1239 (#x1F3F4 . #x1F3F4)
1240 (#x1F3F8 . #x1F3FA)
1241 (#x1F3FB . #x1F3FF)
1242 (#x1F400 . #x1F43E)
1243 (#x1F440 . #x1F440)
1244 (#x1F442 . #x1F4FC)
1245 (#x1F4FF . #x1F53D)
1246 (#x1F54B . #x1F54E)
1247 (#x1F550 . #x1F567)
1248 (#x1F57A . #x1F57A)
1249 (#x1F595 . #x1F596)
1250 (#x1F5A4 . #x1F5A4)
1251 (#x1F5FB . #x1F5FF)
1252 (#x1F600 . #x1F64F)
1253 (#x1F680 . #x1F6C5)
1254 (#x1F6CC . #x1F6CC)
1255 (#x1F6D0 . #x1F6D2)
1256 (#x1F6D5 . #x1F6D5)
1257 (#x1F6EB . #x1F6EC)
1258 (#x1F6F4 . #x1F6FA)
1259 (#x1F7E0 . #x1F7EB)
1260 (#x1F90D . #x1F971)
1261 (#x1F973 . #x1F976)
1262 (#x1F97A . #x1F9A2)
1263 (#x1F9A5 . #x1F9AA)
1264 (#x1F9AE . #x1F9CA)
1265 (#x1F9CD . #x1F9FF)
1266 (#x1FA00 . #x1FA53)
1267 (#x1FA60 . #x1FA6D)
1268 (#x1FA70 . #x1FA73)
1269 (#x1FA78 . #x1FA7A)
1270 (#x1FA80 . #x1FA82)
1271 (#x1FA90 . #x1FA95)
1272 (#x20000 . #x2FFFF)
1273 (#x30000 . #x3FFFF))))
1274 (dolist (elt l)
1275 (set-char-table-range char-width-table elt 2)))
1277 ;; Other double width
1278 ;;(map-charset-chars
1279 ;; (lambda (range ignore) (set-char-table-range char-width-table range 2))
1280 ;; 'ethiopic)
1281 ;; (map-charset-chars
1282 ;; (lambda (range ignore) (set-char-table-range char-width-table range 2))
1283 ;; 'tibetan)
1284 (map-charset-chars
1285 (lambda (range _ignore) (set-char-table-range char-width-table range 2))
1286 'indian-2-column)
1287 (map-charset-chars
1288 (lambda (range _ignore) (set-char-table-range char-width-table range 2))
1289 'arabic-2-column)
1291 ;; Internal use only.
1292 ;; Alist of locale symbol vs charsets. In a language environment
1293 ;; corresponding to the locale, width of characters in the charsets is
1294 ;; set to 2. Each element has the form:
1295 ;; (LOCALE TABLE (CHARSET (FROM-CODE . TO-CODE) ...) ...)
1296 ;; LOCALE: locale symbol
1297 ;; TABLE: char-table used for char-width-table, initially nil.
1298 ;; CHARSET: character set
1299 ;; FROM-CODE, TO-CODE: range of code-points in CHARSET
1301 (defvar cjk-char-width-table-list
1302 '((ja_JP nil (japanese-jisx0208 (#x2121 . #x287E))
1303 (cp932-2-byte (#x8140 . #x879F)))
1304 (zh_CN nil (chinese-gb2312 (#x2121 . #x297E)))
1305 (zh_HK nil (big5-hkscs (#xA140 . #xA3FE) (#xC6A0 . #xC8FE)))
1306 (zh_TW nil (big5 (#xA140 . #xA3FE))
1307 (chinese-cns11643-1 (#x2121 . #x427E)))
1308 (ko_KR nil (korean-ksc5601 (#x2121 . #x2C7E)))))
1310 ;; Internal use only.
1311 ;; Setup char-width-table appropriate for a language environment
1312 ;; corresponding to LOCALE-NAME (symbol).
1314 (defun use-cjk-char-width-table (locale-name)
1315 (while (char-table-parent char-width-table)
1316 (setq char-width-table (char-table-parent char-width-table)))
1317 (let ((slot (assq locale-name cjk-char-width-table-list)))
1318 (or slot (error "Unknown locale for CJK language environment: %s"
1319 locale-name))
1320 (unless (nth 1 slot)
1321 (let ((table (make-char-table nil)))
1322 (dolist (charset-info (nthcdr 2 slot))
1323 (let ((charset (car charset-info)))
1324 (dolist (code-range (cdr charset-info))
1325 (map-charset-chars #'(lambda (range _arg)
1326 (set-char-table-range table range 2))
1327 charset nil
1328 (car code-range) (cdr code-range)))))
1329 (optimize-char-table table)
1330 (set-char-table-parent table char-width-table)
1331 (setcar (cdr slot) table)))
1332 (setq char-width-table (nth 1 slot))))
1334 (defun use-default-char-width-table ()
1335 "Internal use only.
1336 Setup char-width-table appropriate for non-CJK language environment."
1337 (while (char-table-parent char-width-table)
1338 (setq char-width-table (char-table-parent char-width-table))))
1340 (optimize-char-table (standard-case-table))
1341 (optimize-char-table (standard-syntax-table))
1344 ;; Setting char-script-table.
1345 (if dump-mode
1346 ;; While dumping, we can't use require, and international is not
1347 ;; in load-path.
1348 (load "international/charscript")
1349 (require 'charscript))
1351 (map-charset-chars
1352 #'(lambda (range _ignore)
1353 (set-char-table-range char-script-table range 'tibetan))
1354 'tibetan)
1357 ;;; Setting unicode-category-table.
1359 (when (setq unicode-category-table
1360 (unicode-property-table-internal 'general-category))
1361 (map-char-table #'(lambda (key val)
1362 (if val
1363 (cond ((or (and (/= (aref (symbol-name val) 0) ?M)
1364 (/= (aref (symbol-name val) 0) ?C))
1365 (eq val 'Zs))
1366 (modify-category-entry key ?.))
1367 ((eq val 'Mn)
1368 (modify-category-entry key ?^)))))
1369 unicode-category-table))
1371 (optimize-char-table (standard-category-table))
1374 ;; Display of glyphless characters.
1376 (defvar char-acronym-table
1377 (make-char-table 'char-acronym-table nil)
1378 "Char table of acronyms for non-graphic characters.")
1380 (let ((c0-acronyms '("NUL" "SOH" "STX" "ETX" "EOT" "ENQ" "ACK" "BEL"
1381 "BS" nil nil "VT" "FF" "CR" "SO" "SI"
1382 "DLE" "DC1" "DC2" "DC3" "DC4" "NAK" "SYN" "ETB"
1383 "CAN" "EM" "SUB" "ESC" "FC" "GS" "RS" "US")))
1384 (dotimes (i 32)
1385 (aset char-acronym-table i (car c0-acronyms))
1386 (setq c0-acronyms (cdr c0-acronyms))))
1388 (let ((c1-acronyms '("PAD" "HOP" "BPH" "NBH" "IND" "NEL" "SSA" "ESA"
1389 "HTS" "HTJ" "VTS" "PLD" "PLU" "R1" "SS2" "SS1"
1390 "DCS" "PU1" "PU2" "STS" "CCH" "MW" "SPA" "EPA"
1391 "SOS" "SGCI" "SC1" "CSI" "ST" "OSC" "PM" "APC")))
1392 (dotimes (i 32)
1393 (aset char-acronym-table (+ #x0080 i) (car c1-acronyms))
1394 (setq c1-acronyms (cdr c1-acronyms))))
1396 (aset char-acronym-table #x17B4 "KIVAQ") ; KHMER VOWEL INHERENT AQ
1397 (aset char-acronym-table #x17B5 "KIVAA") ; KHMER VOWEL INHERENT AA
1398 (aset char-acronym-table #x200B "ZWSP") ; ZERO WIDTH SPACE
1399 (aset char-acronym-table #x200C "ZWNJ") ; ZERO WIDTH NON-JOINER
1400 (aset char-acronym-table #x200D "ZWJ") ; ZERO WIDTH JOINER
1401 (aset char-acronym-table #x200E "LRM") ; LEFT-TO-RIGHT MARK
1402 (aset char-acronym-table #x200F "RLM") ; RIGHT-TO-LEFT MARK
1403 (aset char-acronym-table #x202A "LRE") ; LEFT-TO-RIGHT EMBEDDING
1404 (aset char-acronym-table #x202B "RLE") ; RIGHT-TO-LEFT EMBEDDING
1405 (aset char-acronym-table #x202C "PDF") ; POP DIRECTIONAL FORMATTING
1406 (aset char-acronym-table #x202D "LRO") ; LEFT-TO-RIGHT OVERRIDE
1407 (aset char-acronym-table #x202E "RLO") ; RIGHT-TO-LEFT OVERRIDE
1408 (aset char-acronym-table #x2060 "WJ") ; WORD JOINER
1409 (aset char-acronym-table #x206A "ISS") ; INHIBIT SYMMETRIC SWAPPING
1410 (aset char-acronym-table #x206B "ASS") ; ACTIVATE SYMMETRIC SWAPPING
1411 (aset char-acronym-table #x206C "IAFS") ; INHIBIT ARABIC FORM SHAPING
1412 (aset char-acronym-table #x206D "AAFS") ; ACTIVATE ARABIC FORM SHAPING
1413 (aset char-acronym-table #x206E "NADS") ; NATIONAL DIGIT SHAPES
1414 (aset char-acronym-table #x206F "NODS") ; NOMINAL DIGIT SHAPES
1415 (aset char-acronym-table #xFEFF "ZWNBSP") ; ZERO WIDTH NO-BREAK SPACE
1416 (aset char-acronym-table #xFFF9 "IAA") ; INTERLINEAR ANNOTATION ANCHOR
1417 (aset char-acronym-table #xFFFA "IAS") ; INTERLINEAR ANNOTATION SEPARATOR
1418 (aset char-acronym-table #xFFFB "IAT") ; INTERLINEAR ANNOTATION TERMINATOR
1419 (aset char-acronym-table #x1D173 "BEGBM") ; MUSICAL SYMBOL BEGIN BEAM
1420 (aset char-acronym-table #x1D174 "ENDBM") ; MUSICAL SYMBOL END BEAM
1421 (aset char-acronym-table #x1D175 "BEGTIE") ; MUSICAL SYMBOL BEGIN TIE
1422 (aset char-acronym-table #x1D176 "END") ; MUSICAL SYMBOL END TIE
1423 (aset char-acronym-table #x1D177 "BEGSLR") ; MUSICAL SYMBOL BEGIN SLUR
1424 (aset char-acronym-table #x1D178 "ENDSLR") ; MUSICAL SYMBOL END SLUR
1425 (aset char-acronym-table #x1D179 "BEGPHR") ; MUSICAL SYMBOL BEGIN PHRASE
1426 (aset char-acronym-table #x1D17A "ENDPHR") ; MUSICAL SYMBOL END PHRASE
1427 (aset char-acronym-table #xE0001 "|->TAG") ; LANGUAGE TAG
1428 (aset char-acronym-table #xE0020 "SP TAG") ; TAG SPACE
1429 (dotimes (i 94)
1430 (aset char-acronym-table (+ #xE0021 i) (format " %c TAG" (+ 33 i))))
1431 (aset char-acronym-table #xE007F "->|TAG") ; CANCEL TAG
1433 (defun update-glyphless-char-display (&optional variable value)
1434 "Make the setting of `glyphless-char-display-control' take effect.
1435 This function updates the char-table `glyphless-char-display',
1436 and is intended to be used in the `:set' attribute of the
1437 option `glyphless-char-display'."
1438 (when value
1439 (set-default variable value))
1440 (dolist (elt value)
1441 (let ((target (car elt))
1442 (method (cdr elt)))
1443 (or (memq method '(zero-width thin-space empty-box acronym hex-code))
1444 (error "Invalid glyphless character display method: %s" method))
1445 (cond ((eq target 'c0-control)
1446 (glyphless-set-char-table-range glyphless-char-display
1447 #x00 #x1F method)
1448 ;; Users will not expect their newlines and TABs be
1449 ;; displayed as anything but themselves, so exempt those
1450 ;; two characters from c0-control.
1451 (set-char-table-range glyphless-char-display #x9 nil)
1452 (set-char-table-range glyphless-char-display #xa nil))
1453 ((eq target 'c1-control)
1454 (glyphless-set-char-table-range glyphless-char-display
1455 #x80 #x9F method))
1456 ((eq target 'format-control)
1457 (when unicode-category-table
1458 (map-char-table
1459 #'(lambda (char category)
1460 (if (eq category 'Cf)
1461 (let ((this-method method)
1462 from to)
1463 (if (consp char)
1464 (setq from (car char) to (cdr char))
1465 (setq from char to char))
1466 (while (<= from to)
1467 (when (/= from #xAD)
1468 (if (eq method 'acronym)
1469 (setq this-method
1470 (aref char-acronym-table from)))
1471 (set-char-table-range glyphless-char-display
1472 from this-method))
1473 (setq from (1+ from))))))
1474 unicode-category-table)))
1475 ((eq target 'no-font)
1476 (set-char-table-extra-slot glyphless-char-display 0 method))
1478 (error "Invalid glyphless character group: %s" target))))))
1480 (defun glyphless-set-char-table-range (chartable from to method)
1481 (if (eq method 'acronym)
1482 (let ((i from))
1483 (while (<= i to)
1484 (set-char-table-range chartable i (aref char-acronym-table i))
1485 (setq i (1+ i))))
1486 (set-char-table-range chartable (cons from to) method)))
1488 ;;; Control of displaying glyphless characters.
1489 (defcustom glyphless-char-display-control
1490 '((format-control . thin-space)
1491 (no-font . hex-code))
1492 "List of directives to control display of glyphless characters.
1494 Each element has the form (GROUP . METHOD), where GROUP is a
1495 symbol specifying the character group, and METHOD is a symbol
1496 specifying the method of displaying characters belonging to that
1497 group.
1499 GROUP must be one of these symbols:
1500 `c0-control': U+0000..U+001F, but excluding newline and TAB.
1501 `c1-control': U+0080..U+009F.
1502 `format-control': Characters of Unicode General Category `Cf',
1503 such as U+200C (ZWNJ), U+200E (LRM), but
1504 excluding characters that have graphic images,
1505 such as U+00AD (SHY).
1506 `no-font': characters for which no suitable font is found.
1507 For character terminals, characters that cannot
1508 be encoded by `terminal-coding-system'.
1510 METHOD must be one of these symbols:
1511 `zero-width': don't display.
1512 `thin-space': display a thin (1-pixel width) space. On character
1513 terminals, display as 1-character space.
1514 `empty-box': display an empty box.
1515 `acronym': display an acronym of the character in a box. The
1516 acronym is taken from `char-acronym-table', which see.
1517 `hex-code': display the hexadecimal character code in a box.
1519 Do not set its value directly from Lisp; the value takes effect
1520 only via a custom `:set'
1521 function (`update-glyphless-char-display'), which updates
1522 `glyphless-char-display'."
1523 :version "24.1"
1524 :type '(alist :key-type (symbol :tag "Character Group")
1525 :value-type (symbol :tag "Display Method"))
1526 :options '((c0-control
1527 (choice (const :tag "Don't display" zero-width)
1528 (const :tag "Display as thin space" thin-space)
1529 (const :tag "Display as empty box" empty-box)
1530 (const :tag "Display acronym" acronym)
1531 (const :tag "Display hex code in a box" hex-code)))
1532 (c1-control
1533 (choice (const :tag "Don't display" zero-width)
1534 (const :tag "Display as thin space" thin-space)
1535 (const :tag "Display as empty box" empty-box)
1536 (const :tag "Display acronym" acronym)
1537 (const :tag "Display hex code in a box" hex-code)))
1538 (format-control
1539 (choice (const :tag "Don't display" zero-width)
1540 (const :tag "Display as thin space" thin-space)
1541 (const :tag "Display as empty box" empty-box)
1542 (const :tag "Display acronym" acronym)
1543 (const :tag "Display hex code in a box" hex-code)))
1544 (no-font
1545 (choice (const :tag "Don't display" zero-width)
1546 (const :tag "Display as thin space" thin-space)
1547 (const :tag "Display as empty box" empty-box)
1548 (const :tag "Display acronym" acronym)
1549 (const :tag "Display hex code in a box" hex-code))))
1550 :set 'update-glyphless-char-display
1551 :group 'display)
1554 ;;; Setting word boundary.
1556 (setq word-combining-categories
1557 '((nil . ?^)
1558 (?^ . nil)
1559 (?C . ?H)
1560 (?C . ?K)))
1562 (setq word-separating-categories ; (2-byte character sets)
1563 '((?H . ?K) ; Hiragana - Katakana
1566 ;; Local Variables:
1567 ;; coding: utf-8
1568 ;; End:
1570 ;;; characters.el ends here