Source file charInfo_width.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
open CamomileLibraryDefault.Camomile
open Result
module Cfg = Cfg
let width ?(cfg: Cfg.t option= None) uchar=
let ucs= UChar.int_of uchar in
if ucs >= 0x20 && ucs < 0x7f then
1
else if ucs = 0 then
0
else if ucs < 0x20 || ucs >= 0x7f && ucs < 0xa0 then
-1
else if Combining.(Codes.mem uchar set) then
0
else if Fullwidth.is_fullwidth ucs then
2
else
match cfg with
| Some widthTable->
if Codes.mem uchar widthTable.unprintable then
-1
else if Codes.mem uchar widthTable.combining then
0
else if Codes.mem uchar widthTable.w2 then
2
else if Codes.mem uchar widthTable.w3 then
3
else if Codes.mem uchar widthTable.w4 then
4
else if Codes.mem uchar widthTable.w5 then
5
else if Codes.mem uchar widthTable.w6 then
6
else
1
| None-> 1
let width_exn ?(cfg: Cfg.t option= None) uchar=
let w= width ~cfg uchar in
if w = -1 then
raise (Failure "unprintable character")
else
w
module type UnicodeString_mini = sig
type t
val get : t -> int -> UChar.t
val length : t -> int
end
module String(US:UnicodeString_mini) = struct
let width ?(cfg: Cfg.t option= None) (us: US.t)=
let length= US.length us in
let rec aux ws i=
if i < length then
let wc= width ~cfg (US.get us i) in
if wc = -1 then
Error i
else
aux (ws+wc) (i+1)
else
Ok ws
in
aux 0 0
end