/ Hex Artifact Content
Login

Artifact a981bd6466d12dd17967515801c3ff23f74a281be1a03cf1e6f52a6959fc77eb:


0000: 0a 23 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  .#--------------
0010: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0020: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0030: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0040: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 20 50  ------------.# P
0050: 61 72 61 6d 65 74 65 72 20 24 7a 4e 61 6d 65 20  arameter $zName 
0060: 6d 75 73 74 20 62 65 20 61 20 70 61 74 68 20 74  must be a path t
0070: 6f 20 74 68 65 20 66 69 6c 65 20 55 6e 69 63 6f  o the file Unico
0080: 64 65 44 61 74 61 2e 74 78 74 2e 20 54 68 69 73  deData.txt. This
0090: 20 63 6f 6d 6d 61 6e 64 0a 23 20 72 65 61 64 73   command.# reads
00a0: 20 74 68 65 20 66 69 6c 65 20 61 6e 64 20 72 65   the file and re
00b0: 74 75 72 6e 73 20 61 20 6c 69 73 74 20 6f 66 20  turns a list of 
00c0: 6d 61 70 70 69 6e 67 73 20 72 65 71 75 69 72 65  mappings require
00d0: 64 20 74 6f 20 72 65 6d 6f 76 65 20 61 6c 6c 0a  d to remove all.
00e0: 23 20 64 69 61 63 72 69 74 69 63 61 6c 20 6d 61  # diacritical ma
00f0: 72 6b 73 20 66 72 6f 6d 20 61 20 75 6e 69 63 6f  rks from a unico
0100: 64 65 20 73 74 72 69 6e 67 2e 20 45 61 63 68 20  de string. Each 
0110: 6d 61 70 70 69 6e 67 20 69 73 20 69 74 73 65 6c  mapping is itsel
0120: 66 20 61 20 6c 69 73 74 0a 23 20 63 6f 6e 73 69  f a list.# consi
0130: 73 74 69 6e 67 20 6f 66 20 74 77 6f 20 65 6c 65  sting of two ele
0140: 6d 65 6e 74 73 20 2d 20 74 68 65 20 75 6e 69 63  ments - the unic
0150: 6f 64 65 20 63 6f 64 65 70 6f 69 6e 74 20 61 6e  ode codepoint an
0160: 64 20 74 68 65 20 73 69 6e 67 6c 65 20 41 53 43  d the single ASC
0170: 49 49 0a 23 20 63 68 61 72 61 63 74 65 72 20 74  II.# character t
0180: 68 61 74 20 69 74 20 73 68 6f 75 6c 64 20 62 65  hat it should be
0190: 20 72 65 70 6c 61 63 65 64 20 77 69 74 68 2c 20   replaced with, 
01a0: 6f 72 20 61 6e 20 65 6d 70 74 79 20 73 74 72 69  or an empty stri
01b0: 6e 67 20 69 66 20 74 68 65 20 0a 23 20 63 6f 64  ng if the .# cod
01c0: 65 70 6f 69 6e 74 20 73 68 6f 75 6c 64 20 73 69  epoint should si
01d0: 6d 70 6c 79 20 62 65 20 72 65 6d 6f 76 65 64 20  mply be removed 
01e0: 66 72 6f 6d 20 74 68 65 20 69 6e 70 75 74 2e 20  from the input. 
01f0: 45 78 61 6d 70 6c 65 73 3a 0a 23 0a 23 20 20 20  Examples:.#.#   
0200: 7b 20 32 32 34 20 61 20 20 30 20 7d 20 20 20 20  { 224 a  0 }    
0210: 20 28 72 65 70 6c 61 63 65 20 63 6f 64 65 70 6f   (replace codepo
0220: 69 6e 74 20 32 32 34 20 74 6f 20 22 61 22 29 0a  int 224 to "a").
0230: 23 20 20 20 7b 20 37 36 39 20 22 22 20 30 20 7d  #   { 769 "" 0 }
0240: 20 20 20 20 20 28 72 65 6d 6f 76 65 20 63 6f 64       (remove cod
0250: 65 70 6f 69 6e 74 20 37 36 39 20 66 72 6f 6d 20  epoint 769 from 
0260: 69 6e 70 75 74 29 0a 23 0a 23 20 4d 61 70 70 69  input).#.# Mappi
0270: 6e 67 73 20 61 72 65 20 6f 6e 6c 79 20 72 65 74  ngs are only ret
0280: 75 72 6e 65 64 20 66 6f 72 20 6e 6f 6e 2d 75 70  urned for non-up
0290: 70 65 72 20 63 61 73 65 20 63 6f 64 65 70 6f 69  per case codepoi
02a0: 6e 74 73 2e 20 49 74 20 69 73 20 61 73 73 75 6d  nts. It is assum
02b0: 65 64 0a 23 20 74 68 61 74 20 74 68 65 20 69 6e  ed.# that the in
02c0: 70 75 74 20 68 61 73 20 61 6c 72 65 61 64 79 20  put has already 
02d0: 62 65 65 6e 20 66 6f 6c 64 65 64 20 74 6f 20 6c  been folded to l
02e0: 6f 77 65 72 20 63 61 73 65 2e 0a 23 0a 23 20 54  ower case..#.# T
02f0: 68 65 20 74 68 69 72 64 20 76 61 6c 75 65 20 69  he third value i
0300: 6e 20 74 68 65 20 6c 69 73 74 20 69 73 20 61 6c  n the list is al
0310: 77 61 79 73 20 65 69 74 68 65 72 20 30 20 6f 72  ways either 0 or
0320: 20 31 2e 20 30 20 69 66 20 74 68 65 20 0a 23 20   1. 0 if the .# 
0330: 55 6e 69 63 6f 64 65 44 61 74 61 2e 74 78 74 20  UnicodeData.txt 
0340: 66 69 6c 65 20 6d 61 70 73 20 74 68 65 20 63 6f  file maps the co
0350: 64 65 70 6f 69 6e 74 20 74 6f 20 61 20 73 69 6e  depoint to a sin
0360: 67 6c 65 20 41 53 43 49 49 20 63 68 61 72 61 63  gle ASCII charac
0370: 74 65 72 20 61 6e 64 0a 23 20 61 20 64 69 61 63  ter and.# a diac
0380: 72 69 74 69 63 2c 20 6f 72 20 31 20 69 66 20 74  ritic, or 1 if t
0390: 68 65 20 6d 61 70 70 69 6e 67 20 69 73 20 69 6e  he mapping is in
03a0: 64 69 72 65 63 74 2e 20 46 6f 72 20 65 78 61 6d  direct. For exam
03b0: 70 6c 65 2c 20 63 6f 6e 73 69 64 65 72 20 74 68  ple, consider th
03c0: 65 20 0a 23 20 74 77 6f 20 65 6e 74 72 69 65 73  e .# two entries
03d0: 3a 0a 23 0a 23 20 31 45 43 44 3b 4c 41 54 49 4e  :.#.# 1ECD;LATIN
03e0: 20 53 4d 41 4c 4c 20 4c 45 54 54 45 52 20 4f 20   SMALL LETTER O 
03f0: 57 49 54 48 20 44 4f 54 20 42 45 4c 4f 57 3b 4c  WITH DOT BELOW;L
0400: 6c 3b 30 3b 4c 3b 30 30 36 46 20 30 33 32 33 3b  l;0;L;006F 0323;
0410: 3b 3b 3b 4e 3b 3b 3b 31 45 43 43 3b 3b 31 45 43  ;;;N;;;1ECC;;1EC
0420: 43 0a 23 20 31 45 44 39 3b 4c 41 54 49 4e 20 53  C.# 1ED9;LATIN S
0430: 4d 41 4c 4c 20 4c 45 54 54 45 52 20 4f 20 57 49  MALL LETTER O WI
0440: 54 48 20 43 49 52 43 55 4d 46 4c 45 58 20 41 4e  TH CIRCUMFLEX AN
0450: 44 20 44 4f 54 20 42 45 4c 4f 57 3b 4c 6c 3b 30  D DOT BELOW;Ll;0
0460: 3b 4c 3b 31 45 43 44 20 30 33 30 32 3b 3b 3b 3b  ;L;1ECD 0302;;;;
0470: 4e 3b 3b 3b 31 45 44 38 3b 3b 31 45 44 38 0a 23  N;;;1ED8;;1ED8.#
0480: 0a 23 20 54 68 65 20 66 69 72 73 74 20 63 6f 64  .# The first cod
0490: 65 70 6f 69 6e 74 20 69 73 20 61 20 64 69 72 65  epoint is a dire
04a0: 63 74 20 6d 61 70 70 69 6e 67 20 28 61 73 20 30  ct mapping (as 0
04b0: 30 36 46 20 69 73 20 41 53 43 49 49 20 61 6e 64  06F is ASCII and
04c0: 20 30 33 32 33 20 69 73 20 61 20 0a 23 20 64 69   0323 is a .# di
04d0: 61 63 72 69 74 69 63 29 2e 20 54 68 65 20 73 65  acritic). The se
04e0: 63 6f 6e 64 20 69 73 20 61 6e 20 69 6e 64 69 72  cond is an indir
04f0: 65 63 74 20 6d 61 70 70 69 6e 67 2c 20 61 73 20  ect mapping, as 
0500: 69 74 20 6d 61 70 73 20 74 6f 20 74 68 65 0a 23  it maps to the.#
0510: 20 66 69 72 73 74 20 63 6f 64 65 70 6f 69 6e 74   first codepoint
0520: 20 70 6c 75 73 20 30 33 30 32 20 28 61 20 64 69   plus 0302 (a di
0530: 61 63 72 69 74 69 63 29 2e 0a 23 0a 70 72 6f 63  acritic)..#.proc
0540: 20 72 64 5f 6c 6f 61 64 5f 75 6e 69 63 6f 64 65   rd_load_unicode
0550: 64 61 74 61 5f 74 65 78 74 20 7b 7a 4e 61 6d 65  data_text {zName
0560: 7d 20 7b 0a 20 20 67 6c 6f 62 61 6c 20 74 6c 5f  } {.  global tl_
0570: 6c 6f 6f 6b 75 70 5f 74 61 62 6c 65 0a 0a 20 20  lookup_table..  
0580: 73 65 74 20 66 64 20 5b 6f 70 65 6e 20 24 7a 4e  set fd [open $zN
0590: 61 6d 65 5d 0a 20 20 73 65 74 20 6c 46 69 65 6c  ame].  set lFiel
05a0: 64 20 7b 0a 20 20 20 20 63 6f 64 65 0a 20 20 20  d {.    code.   
05b0: 20 63 68 61 72 61 63 74 65 72 5f 6e 61 6d 65 0a   character_name.
05c0: 20 20 20 20 67 65 6e 65 72 61 6c 5f 63 61 74 65      general_cate
05d0: 67 6f 72 79 0a 20 20 20 20 63 61 6e 6f 6e 69 63  gory.    canonic
05e0: 61 6c 5f 63 6f 6d 62 69 6e 69 6e 67 5f 63 6c 61  al_combining_cla
05f0: 73 73 65 73 0a 20 20 20 20 62 69 64 69 72 65 63  sses.    bidirec
0600: 74 69 6f 6e 61 6c 5f 63 61 74 65 67 6f 72 79 0a  tional_category.
0610: 20 20 20 20 63 68 61 72 61 63 74 65 72 5f 64 65      character_de
0620: 63 6f 6d 70 6f 73 69 74 69 6f 6e 5f 6d 61 70 70  composition_mapp
0630: 69 6e 67 0a 20 20 20 20 64 65 63 69 6d 61 6c 5f  ing.    decimal_
0640: 64 69 67 69 74 5f 76 61 6c 75 65 0a 20 20 20 20  digit_value.    
0650: 64 69 67 69 74 5f 76 61 6c 75 65 0a 20 20 20 20  digit_value.    
0660: 6e 75 6d 65 72 69 63 5f 76 61 6c 75 65 0a 20 20  numeric_value.  
0670: 20 20 6d 69 72 72 6f 72 65 64 0a 20 20 20 20 75    mirrored.    u
0680: 6e 69 63 6f 64 65 5f 31 5f 6e 61 6d 65 0a 20 20  nicode_1_name.  
0690: 20 20 69 73 6f 31 30 36 34 36 5f 63 6f 6d 6d 65    iso10646_comme
06a0: 6e 74 5f 66 69 65 6c 64 0a 20 20 20 20 75 70 70  nt_field.    upp
06b0: 65 72 63 61 73 65 5f 6d 61 70 70 69 6e 67 0a 20  ercase_mapping. 
06c0: 20 20 20 6c 6f 77 65 72 63 61 73 65 5f 6d 61 70     lowercase_map
06d0: 70 69 6e 67 0a 20 20 20 20 74 69 74 6c 65 63 61  ping.    titleca
06e0: 73 65 5f 6d 61 70 70 69 6e 67 0a 20 20 7d 0a 20  se_mapping.  }. 
06f0: 20 73 65 74 20 6c 52 65 74 20 5b 6c 69 73 74 5d   set lRet [list]
0700: 0a 0a 20 20 77 68 69 6c 65 20 7b 20 21 5b 65 6f  ..  while { ![eo
0710: 66 20 24 66 64 5d 20 7d 20 7b 0a 20 20 20 20 73  f $fd] } {.    s
0720: 65 74 20 6c 69 6e 65 20 5b 67 65 74 73 20 24 66  et line [gets $f
0730: 64 5d 0a 20 20 20 20 69 66 20 7b 24 6c 69 6e 65  d].    if {$line
0740: 20 3d 3d 20 22 22 7d 20 63 6f 6e 74 69 6e 75 65   == ""} continue
0750: 0a 0a 20 20 20 20 73 65 74 20 66 69 65 6c 64 73  ..    set fields
0760: 20 5b 73 70 6c 69 74 20 24 6c 69 6e 65 20 22 3b   [split $line ";
0770: 22 5d 0a 20 20 20 20 69 66 20 7b 5b 6c 6c 65 6e  "].    if {[llen
0780: 67 74 68 20 24 66 69 65 6c 64 73 5d 20 21 3d 20  gth $fields] != 
0790: 5b 6c 6c 65 6e 67 74 68 20 24 6c 46 69 65 6c 64  [llength $lField
07a0: 5d 7d 20 7b 20 65 72 72 6f 72 20 22 70 61 72 73  ]} { error "pars
07b0: 65 20 65 72 72 6f 72 3a 20 24 6c 69 6e 65 22 20  e error: $line" 
07c0: 7d 0a 20 20 20 20 66 6f 72 65 61 63 68 20 24 6c  }.    foreach $l
07d0: 46 69 65 6c 64 20 24 66 69 65 6c 64 73 20 7b 7d  Field $fields {}
07e0: 0a 20 20 20 20 69 66 20 7b 20 5b 6c 6c 65 6e 67  .    if { [lleng
07f0: 74 68 20 24 63 68 61 72 61 63 74 65 72 5f 64 65  th $character_de
0800: 63 6f 6d 70 6f 73 69 74 69 6f 6e 5f 6d 61 70 70  composition_mapp
0810: 69 6e 67 5d 21 3d 32 0a 20 20 20 20 20 20 7c 7c  ing]!=2.      ||
0820: 20 5b 73 74 72 69 6e 67 20 69 73 20 78 64 69 67   [string is xdig
0830: 69 74 20 5b 6c 69 6e 64 65 78 20 24 63 68 61 72  it [lindex $char
0840: 61 63 74 65 72 5f 64 65 63 6f 6d 70 6f 73 69 74  acter_decomposit
0850: 69 6f 6e 5f 6d 61 70 70 69 6e 67 20 30 5d 5d 3d  ion_mapping 0]]=
0860: 3d 30 0a 20 20 20 20 7d 20 7b 0a 20 20 20 20 20  =0.    } {.     
0870: 20 63 6f 6e 74 69 6e 75 65 0a 20 20 20 20 7d 0a   continue.    }.
0880: 0a 20 20 20 20 73 65 74 20 69 43 6f 64 65 20 20  .    set iCode  
0890: 5b 65 78 70 72 20 22 30 78 24 63 6f 64 65 22 5d  [expr "0x$code"]
08a0: 0a 20 20 20 20 73 65 74 20 69 41 73 63 69 69 20  .    set iAscii 
08b0: 5b 65 78 70 72 20 22 30 78 5b 6c 69 6e 64 65 78  [expr "0x[lindex
08c0: 20 24 63 68 61 72 61 63 74 65 72 5f 64 65 63 6f   $character_deco
08d0: 6d 70 6f 73 69 74 69 6f 6e 5f 6d 61 70 70 69 6e  mposition_mappin
08e0: 67 20 30 5d 22 5d 0a 20 20 20 20 73 65 74 20 69  g 0]"].    set i
08f0: 44 69 61 20 20 20 5b 65 78 70 72 20 22 30 78 5b  Dia   [expr "0x[
0900: 6c 69 6e 64 65 78 20 24 63 68 61 72 61 63 74 65  lindex $characte
0910: 72 5f 64 65 63 6f 6d 70 6f 73 69 74 69 6f 6e 5f  r_decomposition_
0920: 6d 61 70 70 69 6e 67 20 31 5d 22 5d 0a 0a 20 20  mapping 1]"]..  
0930: 20 20 23 20 46 69 6c 74 65 72 20 6f 75 74 20 75    # Filter out u
0940: 70 70 65 72 2d 63 61 73 65 20 63 68 61 72 61 63  pper-case charac
0950: 74 65 72 73 2c 20 61 73 20 74 68 65 79 20 77 69  ters, as they wi
0960: 6c 6c 20 62 65 20 6d 61 70 70 65 64 20 74 6f 20  ll be mapped to 
0970: 74 68 65 69 72 0a 20 20 20 20 23 20 6c 6f 77 65  their.    # lowe
0980: 72 2d 63 61 73 65 20 65 71 75 69 76 61 6c 65 6e  r-case equivalen
0990: 74 73 20 62 65 66 6f 72 65 20 74 68 69 73 20 64  ts before this d
09a0: 61 74 61 20 69 73 20 75 73 65 64 2e 0a 20 20 20  ata is used..   
09b0: 20 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74   if {[info exist
09c0: 73 20 74 6c 5f 6c 6f 6f 6b 75 70 5f 74 61 62 6c  s tl_lookup_tabl
09d0: 65 28 24 69 43 6f 64 65 29 5d 7d 20 63 6f 6e 74  e($iCode)]} cont
09e0: 69 6e 75 65 0a 0a 20 20 20 20 23 20 43 68 65 63  inue..    # Chec
09f0: 6b 20 69 66 20 74 68 69 73 20 69 73 20 61 6e 20  k if this is an 
0a00: 69 6e 64 69 72 65 63 74 20 6d 61 70 70 69 6e 67  indirect mapping
0a10: 2e 20 49 66 20 73 6f 2c 20 73 65 74 20 62 49 6e  . If so, set bIn
0a20: 64 69 72 65 63 74 20 74 6f 20 74 72 75 65 0a 20  direct to true. 
0a30: 20 20 20 23 20 61 6e 64 20 63 68 61 6e 67 65 20     # and change 
0a40: 24 69 41 73 63 69 69 20 74 6f 20 74 68 65 20 69  $iAscii to the i
0a50: 6e 64 69 72 65 63 74 6c 79 20 6d 61 70 70 70 65  ndirectly mapppe
0a60: 64 20 41 53 43 49 49 20 63 68 61 72 61 63 74 65  d ASCII characte
0a70: 72 2e 0a 20 20 20 20 73 65 74 20 62 49 6e 64 69  r..    set bIndi
0a80: 72 65 63 74 20 30 0a 20 20 20 20 69 66 20 7b 5b  rect 0.    if {[
0a90: 69 6e 66 6f 20 65 78 69 73 74 73 20 64 69 61 28  info exists dia(
0aa0: 24 69 44 69 61 29 5d 20 26 26 20 5b 69 6e 66 6f  $iDia)] && [info
0ab0: 20 65 78 69 73 74 73 20 6d 61 70 70 69 6e 67 28   exists mapping(
0ac0: 24 69 41 73 63 69 69 29 5d 7d 20 7b 0a 20 20 20  $iAscii)]} {.   
0ad0: 20 20 20 73 65 74 20 69 41 73 63 69 69 20 24 6d     set iAscii $m
0ae0: 61 70 70 69 6e 67 28 24 69 41 73 63 69 69 29 0a  apping($iAscii).
0af0: 20 20 20 20 20 20 73 65 74 20 62 49 6e 64 69 72        set bIndir
0b00: 65 63 74 20 31 0a 20 20 20 20 7d 0a 0a 20 20 20  ect 1.    }..   
0b10: 20 69 66 20 7b 20 28 24 69 41 73 63 69 69 20 3e   if { ($iAscii >
0b20: 3d 20 39 37 20 26 26 20 24 69 41 73 63 69 69 20  = 97 && $iAscii 
0b30: 3c 3d 20 31 32 32 29 0a 20 20 20 20 20 20 7c 7c  <= 122).      ||
0b40: 20 28 24 69 41 73 63 69 69 20 3e 3d 20 36 35 20   ($iAscii >= 65 
0b50: 26 26 20 24 69 41 73 63 69 69 20 3c 3d 20 39 30  && $iAscii <= 90
0b60: 29 0a 20 20 20 20 7d 20 7b 0a 20 20 20 20 20 20  ).    } {.      
0b70: 6c 61 70 70 65 6e 64 20 6c 52 65 74 20 5b 6c 69  lappend lRet [li
0b80: 73 74 20 24 69 43 6f 64 65 20 5b 73 74 72 69 6e  st $iCode [strin
0b90: 67 20 74 6f 6c 6f 77 65 72 20 5b 66 6f 72 6d 61  g tolower [forma
0ba0: 74 20 25 63 20 24 69 41 73 63 69 69 5d 5d 20 24  t %c $iAscii]] $
0bb0: 62 49 6e 64 69 72 65 63 74 5d 0a 20 20 20 20 20  bIndirect].     
0bc0: 20 73 65 74 20 6d 61 70 70 69 6e 67 28 24 69 43   set mapping($iC
0bd0: 6f 64 65 29 20 24 69 41 73 63 69 69 0a 20 20 20  ode) $iAscii.   
0be0: 20 20 20 73 65 74 20 64 69 61 28 24 69 44 69 61     set dia($iDia
0bf0: 29 20 31 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  ) 1.    }.  }.. 
0c00: 20 66 6f 72 65 61 63 68 20 64 20 5b 61 72 72 61   foreach d [arra
0c10: 79 20 6e 61 6d 65 73 20 64 69 61 5d 20 7b 0a 20  y names dia] {. 
0c20: 20 20 20 6c 61 70 70 65 6e 64 20 6c 52 65 74 20     lappend lRet 
0c30: 5b 6c 69 73 74 20 24 64 20 22 22 20 30 5d 0a 20  [list $d "" 0]. 
0c40: 20 7d 0a 20 20 73 65 74 20 6c 52 65 74 20 5b 6c   }.  set lRet [l
0c50: 73 6f 72 74 20 2d 69 6e 74 65 67 65 72 20 2d 69  sort -integer -i
0c60: 6e 64 65 78 20 30 20 24 6c 52 65 74 5d 0a 0a 20  ndex 0 $lRet].. 
0c70: 20 63 6c 6f 73 65 20 24 66 64 0a 20 20 73 65 74   close $fd.  set
0c80: 20 6c 52 65 74 0a 7d 0a 0a 23 2d 2d 2d 2d 2d 2d   lRet.}..#------
0c90: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0ca0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0cb0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0cc0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0cd0: 2d 2d 2d 0a 23 20 50 61 72 61 6d 65 74 65 72 20  ---.# Parameter 
0ce0: 24 7a 4e 61 6d 65 20 6d 75 73 74 20 62 65 20 61  $zName must be a
0cf0: 20 70 61 74 68 20 74 6f 20 74 68 65 20 66 69 6c   path to the fil
0d00: 65 20 55 6e 69 63 6f 64 65 44 61 74 61 2e 74 78  e UnicodeData.tx
0d10: 74 2e 20 54 68 69 73 20 63 6f 6d 6d 61 6e 64 0a  t. This command.
0d20: 23 20 72 65 61 64 73 20 74 68 65 20 66 69 6c 65  # reads the file
0d30: 20 61 6e 64 20 72 65 74 75 72 6e 73 20 61 20 6c   and returns a l
0d40: 69 73 74 20 6f 66 20 63 6f 64 65 70 6f 69 6e 74  ist of codepoint
0d50: 73 20 28 69 6e 74 65 67 65 72 73 29 2e 20 54 68  s (integers). Th
0d60: 65 20 6c 69 73 74 0a 23 20 63 6f 6e 74 61 69 6e  e list.# contain
0d70: 73 20 61 6c 6c 20 63 6f 64 65 70 6f 69 6e 74 73  s all codepoints
0d80: 20 69 6e 20 74 68 65 20 55 6e 69 63 6f 64 65 44   in the UnicodeD
0d90: 61 74 61 2e 74 78 74 20 61 73 73 69 67 6e 65 64  ata.txt assigned
0da0: 20 74 6f 20 61 6e 79 20 22 47 65 6e 65 72 61 6c   to any "General
0db0: 0a 23 20 43 61 74 65 67 6f 72 79 22 20 74 68 61  .# Category" tha
0dc0: 74 20 69 73 20 6e 6f 74 20 61 20 22 4c 65 74 74  t is not a "Lett
0dd0: 65 72 22 20 6f 72 20 22 4e 75 6d 62 65 72 22 2e  er" or "Number".
0de0: 0a 23 0a 70 72 6f 63 20 61 6e 5f 6c 6f 61 64 5f  .#.proc an_load_
0df0: 75 6e 69 63 6f 64 65 64 61 74 61 5f 74 65 78 74  unicodedata_text
0e00: 20 7b 7a 4e 61 6d 65 7d 20 7b 0a 20 20 73 65 74   {zName} {.  set
0e10: 20 66 64 20 5b 6f 70 65 6e 20 24 7a 4e 61 6d 65   fd [open $zName
0e20: 5d 0a 20 20 73 65 74 20 6c 46 69 65 6c 64 20 7b  ].  set lField {
0e30: 0a 20 20 20 20 63 6f 64 65 0a 20 20 20 20 63 68  .    code.    ch
0e40: 61 72 61 63 74 65 72 5f 6e 61 6d 65 0a 20 20 20  aracter_name.   
0e50: 20 67 65 6e 65 72 61 6c 5f 63 61 74 65 67 6f 72   general_categor
0e60: 79 0a 20 20 20 20 63 61 6e 6f 6e 69 63 61 6c 5f  y.    canonical_
0e70: 63 6f 6d 62 69 6e 69 6e 67 5f 63 6c 61 73 73 65  combining_classe
0e80: 73 0a 20 20 20 20 62 69 64 69 72 65 63 74 69 6f  s.    bidirectio
0e90: 6e 61 6c 5f 63 61 74 65 67 6f 72 79 0a 20 20 20  nal_category.   
0ea0: 20 63 68 61 72 61 63 74 65 72 5f 64 65 63 6f 6d   character_decom
0eb0: 70 6f 73 69 74 69 6f 6e 5f 6d 61 70 70 69 6e 67  position_mapping
0ec0: 0a 20 20 20 20 64 65 63 69 6d 61 6c 5f 64 69 67  .    decimal_dig
0ed0: 69 74 5f 76 61 6c 75 65 0a 20 20 20 20 64 69 67  it_value.    dig
0ee0: 69 74 5f 76 61 6c 75 65 0a 20 20 20 20 6e 75 6d  it_value.    num
0ef0: 65 72 69 63 5f 76 61 6c 75 65 0a 20 20 20 20 6d  eric_value.    m
0f00: 69 72 72 6f 72 65 64 0a 20 20 20 20 75 6e 69 63  irrored.    unic
0f10: 6f 64 65 5f 31 5f 6e 61 6d 65 0a 20 20 20 20 69  ode_1_name.    i
0f20: 73 6f 31 30 36 34 36 5f 63 6f 6d 6d 65 6e 74 5f  so10646_comment_
0f30: 66 69 65 6c 64 0a 20 20 20 20 75 70 70 65 72 63  field.    upperc
0f40: 61 73 65 5f 6d 61 70 70 69 6e 67 0a 20 20 20 20  ase_mapping.    
0f50: 6c 6f 77 65 72 63 61 73 65 5f 6d 61 70 70 69 6e  lowercase_mappin
0f60: 67 0a 20 20 20 20 74 69 74 6c 65 63 61 73 65 5f  g.    titlecase_
0f70: 6d 61 70 70 69 6e 67 0a 20 20 7d 0a 20 20 73 65  mapping.  }.  se
0f80: 74 20 6c 52 65 74 20 5b 6c 69 73 74 5d 0a 0a 20  t lRet [list].. 
0f90: 20 77 68 69 6c 65 20 7b 20 21 5b 65 6f 66 20 24   while { ![eof $
0fa0: 66 64 5d 20 7d 20 7b 0a 20 20 20 20 73 65 74 20  fd] } {.    set 
0fb0: 6c 69 6e 65 20 5b 67 65 74 73 20 24 66 64 5d 0a  line [gets $fd].
0fc0: 20 20 20 20 69 66 20 7b 24 6c 69 6e 65 20 3d 3d      if {$line ==
0fd0: 20 22 22 7d 20 63 6f 6e 74 69 6e 75 65 0a 0a 20   ""} continue.. 
0fe0: 20 20 20 73 65 74 20 66 69 65 6c 64 73 20 5b 73     set fields [s
0ff0: 70 6c 69 74 20 24 6c 69 6e 65 20 22 3b 22 5d 0a  plit $line ";"].
1000: 20 20 20 20 69 66 20 7b 5b 6c 6c 65 6e 67 74 68      if {[llength
1010: 20 24 66 69 65 6c 64 73 5d 20 21 3d 20 5b 6c 6c   $fields] != [ll
1020: 65 6e 67 74 68 20 24 6c 46 69 65 6c 64 5d 7d 20  ength $lField]} 
1030: 7b 20 65 72 72 6f 72 20 22 70 61 72 73 65 20 65  { error "parse e
1040: 72 72 6f 72 3a 20 24 6c 69 6e 65 22 20 7d 0a 20  rror: $line" }. 
1050: 20 20 20 66 6f 72 65 61 63 68 20 24 6c 46 69 65     foreach $lFie
1060: 6c 64 20 24 66 69 65 6c 64 73 20 7b 7d 0a 0a 20  ld $fields {}.. 
1070: 20 20 20 73 65 74 20 69 43 6f 64 65 20 5b 65 78     set iCode [ex
1080: 70 72 20 22 30 78 24 63 6f 64 65 22 5d 0a 20 20  pr "0x$code"].  
1090: 20 20 73 65 74 20 62 41 6c 6e 75 6d 20 5b 65 78    set bAlnum [ex
10a0: 70 72 20 7b 0a 20 20 20 20 20 20 20 20 20 5b 6c  pr {.         [l
10b0: 73 65 61 72 63 68 20 7b 4c 20 4e 7d 20 5b 73 74  search {L N} [st
10c0: 72 69 6e 67 20 72 61 6e 67 65 20 24 67 65 6e 65  ring range $gene
10d0: 72 61 6c 5f 63 61 74 65 67 6f 72 79 20 30 20 30  ral_category 0 0
10e0: 5d 5d 20 3e 3d 20 30 0a 20 20 20 20 20 20 7c 7c  ]] >= 0.      ||
10f0: 20 24 67 65 6e 65 72 61 6c 5f 63 61 74 65 67 6f   $general_catego
1100: 72 79 3d 3d 22 43 6f 22 0a 20 20 20 20 7d 5d 0a  ry=="Co".    }].
1110: 0a 20 20 20 20 69 66 20 7b 20 21 24 62 41 6c 6e  .    if { !$bAln
1120: 75 6d 20 7d 20 7b 20 6c 61 70 70 65 6e 64 20 6c  um } { lappend l
1130: 52 65 74 20 24 69 43 6f 64 65 20 7d 0a 20 20 7d  Ret $iCode }.  }
1140: 0a 0a 20 20 63 6c 6f 73 65 20 24 66 64 0a 20 20  ..  close $fd.  
1150: 73 65 74 20 6c 52 65 74 0a 7d 0a 0a 70 72 6f 63  set lRet.}..proc
1160: 20 74 6c 5f 6c 6f 61 64 5f 63 61 73 65 66 6f 6c   tl_load_casefol
1170: 64 69 6e 67 5f 74 78 74 20 7b 7a 4e 61 6d 65 7d  ding_txt {zName}
1180: 20 7b 0a 20 20 67 6c 6f 62 61 6c 20 74 6c 5f 6c   {.  global tl_l
1190: 6f 6f 6b 75 70 5f 74 61 62 6c 65 0a 0a 20 20 73  ookup_table..  s
11a0: 65 74 20 66 64 20 5b 6f 70 65 6e 20 24 7a 4e 61  et fd [open $zNa
11b0: 6d 65 5d 0a 20 20 77 68 69 6c 65 20 7b 20 21 5b  me].  while { ![
11c0: 65 6f 66 20 24 66 64 5d 20 7d 20 7b 0a 20 20 20  eof $fd] } {.   
11d0: 20 73 65 74 20 6c 69 6e 65 20 5b 67 65 74 73 20   set line [gets 
11e0: 24 66 64 5d 0a 20 20 20 20 69 66 20 7b 5b 73 74  $fd].    if {[st
11f0: 72 69 6e 67 20 72 61 6e 67 65 20 24 6c 69 6e 65  ring range $line
1200: 20 30 20 30 5d 20 3d 3d 20 22 23 22 7d 20 63 6f   0 0] == "#"} co
1210: 6e 74 69 6e 75 65 0a 20 20 20 20 69 66 20 7b 24  ntinue.    if {$
1220: 6c 69 6e 65 20 3d 3d 20 22 22 7d 20 63 6f 6e 74  line == ""} cont
1230: 69 6e 75 65 0a 0a 20 20 20 20 66 6f 72 65 61 63  inue..    foreac
1240: 68 20 78 20 7b 61 20 62 20 63 20 64 7d 20 7b 75  h x {a b c d} {u
1250: 6e 73 65 74 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e  nset -nocomplain
1260: 20 24 78 7d 0a 20 20 20 20 66 6f 72 65 61 63 68   $x}.    foreach
1270: 20 7b 61 20 62 20 63 20 64 7d 20 5b 73 70 6c 69   {a b c d} [spli
1280: 74 20 24 6c 69 6e 65 20 22 3b 22 5d 20 7b 7d 0a  t $line ";"] {}.
1290: 0a 20 20 20 20 73 65 74 20 61 32 20 5b 6c 69 73  .    set a2 [lis
12a0: 74 5d 0a 20 20 20 20 73 65 74 20 63 32 20 5b 6c  t].    set c2 [l
12b0: 69 73 74 5d 0a 20 20 20 20 66 6f 72 65 61 63 68  ist].    foreach
12c0: 20 65 6c 65 6d 20 24 61 20 7b 20 6c 61 70 70 65   elem $a { lappe
12d0: 6e 64 20 61 32 20 5b 65 78 70 72 20 22 30 78 5b  nd a2 [expr "0x[
12e0: 73 74 72 69 6e 67 20 74 72 69 6d 20 24 65 6c 65  string trim $ele
12f0: 6d 5d 22 5d 20 7d 0a 20 20 20 20 66 6f 72 65 61  m]"] }.    forea
1300: 63 68 20 65 6c 65 6d 20 24 63 20 7b 20 6c 61 70  ch elem $c { lap
1310: 70 65 6e 64 20 63 32 20 5b 65 78 70 72 20 22 30  pend c2 [expr "0
1320: 78 5b 73 74 72 69 6e 67 20 74 72 69 6d 20 24 65  x[string trim $e
1330: 6c 65 6d 5d 22 5d 20 7d 0a 20 20 20 20 73 65 74  lem]"] }.    set
1340: 20 62 20 5b 73 74 72 69 6e 67 20 74 72 69 6d 20   b [string trim 
1350: 24 62 5d 0a 20 20 20 20 73 65 74 20 64 20 5b 73  $b].    set d [s
1360: 74 72 69 6e 67 20 74 72 69 6d 20 24 64 5d 0a 0a  tring trim $d]..
1370: 20 20 20 20 69 66 20 7b 24 62 3d 3d 22 43 22 20      if {$b=="C" 
1380: 7c 7c 20 24 62 3d 3d 22 53 22 7d 20 7b 20 73 65  || $b=="S"} { se
1390: 74 20 74 6c 5f 6c 6f 6f 6b 75 70 5f 74 61 62 6c  t tl_lookup_tabl
13a0: 65 28 24 61 32 29 20 24 63 32 20 7d 0a 20 20 7d  e($a2) $c2 }.  }
13b0: 0a 7d 0a 0a 70 72 6f 63 20 63 63 5f 6c 6f 61 64  .}..proc cc_load
13c0: 5f 75 6e 69 63 6f 64 65 64 61 74 61 5f 74 65 78  _unicodedata_tex
13d0: 74 20 7b 7a 4e 61 6d 65 7d 20 7b 0a 20 20 73 65  t {zName} {.  se
13e0: 74 20 66 64 20 5b 6f 70 65 6e 20 24 7a 4e 61 6d  t fd [open $zNam
13f0: 65 5d 0a 20 20 73 65 74 20 6c 46 69 65 6c 64 20  e].  set lField 
1400: 7b 0a 20 20 20 20 63 6f 64 65 0a 20 20 20 20 63  {.    code.    c
1410: 68 61 72 61 63 74 65 72 5f 6e 61 6d 65 0a 20 20  haracter_name.  
1420: 20 20 67 65 6e 65 72 61 6c 5f 63 61 74 65 67 6f    general_catego
1430: 72 79 0a 20 20 20 20 63 61 6e 6f 6e 69 63 61 6c  ry.    canonical
1440: 5f 63 6f 6d 62 69 6e 69 6e 67 5f 63 6c 61 73 73  _combining_class
1450: 65 73 0a 20 20 20 20 62 69 64 69 72 65 63 74 69  es.    bidirecti
1460: 6f 6e 61 6c 5f 63 61 74 65 67 6f 72 79 0a 20 20  onal_category.  
1470: 20 20 63 68 61 72 61 63 74 65 72 5f 64 65 63 6f    character_deco
1480: 6d 70 6f 73 69 74 69 6f 6e 5f 6d 61 70 70 69 6e  mposition_mappin
1490: 67 0a 20 20 20 20 64 65 63 69 6d 61 6c 5f 64 69  g.    decimal_di
14a0: 67 69 74 5f 76 61 6c 75 65 0a 20 20 20 20 64 69  git_value.    di
14b0: 67 69 74 5f 76 61 6c 75 65 0a 20 20 20 20 6e 75  git_value.    nu
14c0: 6d 65 72 69 63 5f 76 61 6c 75 65 0a 20 20 20 20  meric_value.    
14d0: 6d 69 72 72 6f 72 65 64 0a 20 20 20 20 75 6e 69  mirrored.    uni
14e0: 63 6f 64 65 5f 31 5f 6e 61 6d 65 0a 20 20 20 20  code_1_name.    
14f0: 69 73 6f 31 30 36 34 36 5f 63 6f 6d 6d 65 6e 74  iso10646_comment
1500: 5f 66 69 65 6c 64 0a 20 20 20 20 75 70 70 65 72  _field.    upper
1510: 63 61 73 65 5f 6d 61 70 70 69 6e 67 0a 20 20 20  case_mapping.   
1520: 20 6c 6f 77 65 72 63 61 73 65 5f 6d 61 70 70 69   lowercase_mappi
1530: 6e 67 0a 20 20 20 20 74 69 74 6c 65 63 61 73 65  ng.    titlecase
1540: 5f 6d 61 70 70 69 6e 67 0a 20 20 7d 0a 20 20 73  _mapping.  }.  s
1550: 65 74 20 6c 52 65 74 20 5b 6c 69 73 74 5d 0a 0a  et lRet [list]..
1560: 20 20 77 68 69 6c 65 20 7b 20 21 5b 65 6f 66 20    while { ![eof 
1570: 24 66 64 5d 20 7d 20 7b 0a 20 20 20 20 73 65 74  $fd] } {.    set
1580: 20 6c 69 6e 65 20 5b 67 65 74 73 20 24 66 64 5d   line [gets $fd]
1590: 0a 20 20 20 20 69 66 20 7b 24 6c 69 6e 65 20 3d  .    if {$line =
15a0: 3d 20 22 22 7d 20 63 6f 6e 74 69 6e 75 65 0a 0a  = ""} continue..
15b0: 20 20 20 20 73 65 74 20 66 69 65 6c 64 73 20 5b      set fields [
15c0: 73 70 6c 69 74 20 24 6c 69 6e 65 20 22 3b 22 5d  split $line ";"]
15d0: 0a 20 20 20 20 69 66 20 7b 5b 6c 6c 65 6e 67 74  .    if {[llengt
15e0: 68 20 24 66 69 65 6c 64 73 5d 20 21 3d 20 5b 6c  h $fields] != [l
15f0: 6c 65 6e 67 74 68 20 24 6c 46 69 65 6c 64 5d 7d  length $lField]}
1600: 20 7b 20 65 72 72 6f 72 20 22 70 61 72 73 65 20   { error "parse 
1610: 65 72 72 6f 72 3a 20 24 6c 69 6e 65 22 20 7d 0a  error: $line" }.
1620: 20 20 20 20 66 6f 72 65 61 63 68 20 24 6c 46 69      foreach $lFi
1630: 65 6c 64 20 24 66 69 65 6c 64 73 20 7b 7d 0a 0a  eld $fields {}..
1640: 20 20 20 20 6c 61 70 70 65 6e 64 20 6c 52 65 74      lappend lRet
1650: 20 5b 6c 69 73 74 20 24 63 6f 64 65 20 24 67 65   [list $code $ge
1660: 6e 65 72 61 6c 5f 63 61 74 65 67 6f 72 79 5d 0a  neral_category].
1670: 20 20 7d 0a 0a 20 20 63 6c 6f 73 65 20 24 66 64    }..  close $fd
1680: 0a 20 20 73 65 74 20 6c 52 65 74 0a 7d 0a 0a 0a  .  set lRet.}...