1const std = @import("std");
2const common = @import("./_common.zig");
3
4pub usingnamespace common.Main(struct {
5 pub const source_file = "UnicodeData";
6
7 pub const dest_file = "src/unicode_data.zig";
8
9 pub const dest_header =
10 \\const ucd = @import("./lib.zig");
11 \\const std = @import("std");
12 \\const extras = @import("extras");
13 \\
14 \\pub const data_soa = extras.StaticMultiList(Codepoint).initComptime(&data);
15 \\
16 \\pub const Codepoint = struct {
17 \\ u21, // U+ code
18 \\ []const u8, // name
19 \\ ucd.GeneralCategory,
20 \\ u8, // Canonical_Combining_Class
21 \\ ucd.BidiClass,
22 \\ Decomposition, // __none for none
23 \\ []const u21, // decomposition mapping, empty for none
24 \\ []const u8, // Numeric_Type=Decimal value
25 \\ []const u8, // Numeric_Type=Digit value
26 \\ []const u8, // Numeric_Type=Numeric value
27 \\ bool, // Bidi_Mirrored?
28 \\ ?u21, // Simple_Uppercase_Mapping
29 \\ ?u21, // Simple_Lowercase_Mapping
30 \\ ?u21, // Simple_Titlecase_Mapping
31 \\};
32 \\
33 \\pub const Decomposition = enum {
34 \\ __none,
35 \\ __canonical,
36 \\ noBreak,
37 \\ compat,
38 \\ super,
39 \\ fraction,
40 \\ sub,
41 \\ font,
42 \\ circle,
43 \\ wide,
44 \\ vertical,
45 \\ square,
46 \\ isolated,
47 \\ final,
48 \\ initial,
49 \\ medial,
50 \\ small,
51 \\ narrow,
52 \\};
53 \\
54 \\pub fn find(cp: u21) Codepoint {
55 \\ return data[binarySearchClosest(u21, data_soa[0], cp, compare)];
56 \\}
57 \\
58 \\fn binarySearchClosest(comptime T: type, items: []const T, context: anytype, comptime compareFn: fn (@TypeOf(context), T) std.math.Order) usize {
59 \\ var low: usize = 0;
60 \\ var high: usize = items.len;
61 \\ while (low < high) {
62 \\ const mid = low + (high - low) / 2;
63 \\ switch (compareFn(context, items[mid])) {
64 \\ .eq => return mid,
65 \\ .gt => low = mid + 1,
66 \\ .lt => high = mid,
67 \\ }
68 \\ }
69 \\ std.debug.assert(low == high);
70 \\ return high;
71 \\}
72 \\
73 \\pub fn compare(needle: u21, row: u21) std.math.Order {
74 \\ if (needle < row) return .lt;
75 \\ if (needle > row) return .gt;
76 \\ return .eq;
77 \\}
78 \\
79 \\pub const data = [_]Codepoint{
80 \\
81 ;
82
83 pub const dest_footer =
84 \\};
85 \\
86 ;
87
88 pub fn exec(alloc: std.mem.Allocator, line: []const u8, writer: anytype) !void {
89 _ = alloc;
90 var it = std.mem.splitScalar(u8, line, ';');
91
92 try writer.writeAll(" .{");
93 try writer.print(" 0x{s},", .{it.next().?});
94 try writer.print(" \"{}\",", .{std.zig.fmtEscapes(it.next().?)});
95 try writer.print(" .{s},", .{it.next().?});
96 try writer.print(" {s},", .{it.next().?});
97 try writer.print(" .{s},", .{it.next().?});
98 {
99 var next = it.next().?;
100 if (next.len > 0) {
101 if (std.mem.indexOfScalar(u8, next, '>')) |idx| {
102 try writer.print(" .{s},", .{next[1..idx]});
103 next = next[idx + 2 ..];
104 } else {
105 try writer.writeAll(" .__canonical,");
106 }
107 var jt = std.mem.splitScalar(u8, next, ' ');
108 try writer.writeAll(" &.{");
109 while (jt.next()) |sp| {
110 try writer.writeAll("0x");
111 try writer.writeAll(sp);
112 if (jt.index != null) try writer.writeAll(",");
113 }
114 try writer.writeAll("},");
115 } else {
116 try writer.writeAll(" .__none,");
117 try writer.writeAll(" &.{},");
118 }
119 }
120 try writer.print(" \"{}\",", .{std.zig.fmtEscapes(it.next().?)});
121 try writer.print(" \"{}\",", .{std.zig.fmtEscapes(it.next().?)});
122 try writer.print(" \"{}\",", .{std.zig.fmtEscapes(it.next().?)});
123 try writer.print(" {},", .{std.mem.eql(u8, it.next().?, "Y")});
124 _ = it.next().?; // [skip] Unicode_1_Name (Obsolete as of 6.2.0)
125 _ = it.next().?; // [skip] ISO_Comment (Obsolete as of 5.2.0; Deprecated and Stabilized as of 6.0.0)
126 if (common.nullify(it.next())) |res| try writer.print(" 0x{s},", .{res}) else try writer.writeAll(" null,");
127 if (common.nullify(it.next())) |res| try writer.print(" 0x{s},", .{res}) else try writer.writeAll(" null,");
128 if (common.nullify(it.next())) |res| try writer.print(" 0x{s},", .{res}) else try writer.writeAll(" null,");
129
130 try writer.writeAll(" },\n");
131 }
132});