|
| 1 | +#! /usr/bin/env lua |
| 2 | +-- vim:set ft=lua:sw=3:ts=3: |
| 3 | + |
| 4 | +local help_text = [[Usage: %s [-w<path>] [-z<path>] [-a<path>] [-p<path>] [--help | -h] |
| 5 | +
|
| 6 | + -w<path> Path to wide characters table (default: widetab.lua) |
| 7 | + -z<path> Path to zero-width characters table (default: zerotab.lua) |
| 8 | + -a<path> Path to ambiguous width characters table (default: ambitab.lua) |
| 9 | + -p<path> Path prefix to prepend to all above paths (default: .) |
| 10 | + -h, --help Show this help text. |
| 11 | +
|
| 12 | +]] |
| 13 | + |
| 14 | +local path_prefix = "." |
| 15 | +local wide_tab_path = "widetab.lua" |
| 16 | +local zero_tab_path = "zerotab.lua" |
| 17 | +local ambi_tab_path = "ambitab.lua" |
| 18 | + |
| 19 | +for _, item in ipairs(arg) do |
| 20 | + if item == "-h" or item == "--help" then |
| 21 | + io.stdout:write(help_text:format(arg[0])) |
| 22 | + os.exit(0) |
| 23 | + end |
| 24 | + local prefix = item:sub(1, 2) |
| 25 | + local suffix = item:sub(3) |
| 26 | + if prefix == "-w" then |
| 27 | + wide_tab_path = suffix |
| 28 | + elseif prefix == "-z" then |
| 29 | + zero_tab_path = suffix |
| 30 | + elseif prefix == "-a" then |
| 31 | + ambi_tab_path = suffix |
| 32 | + elseif prefix == "-p" then |
| 33 | + path_prefix = suffix |
| 34 | + else |
| 35 | + io.stderr:write(("Unrecognized command line option: %s\n\n"):format(item)) |
| 36 | + io.stderr:write(help_text:format(arg[0])) |
| 37 | + os.exit(1) |
| 38 | + end |
| 39 | +end |
| 40 | + |
| 41 | +local pat_range = "^(%x+)%.%.(%x+)%s*;%s*(%w+)" |
| 42 | +local pat_rune = "^(%x+)%s*;%s*(%w+)" |
| 43 | + |
| 44 | +local wide_tab = {} |
| 45 | +local zero_tab = {} |
| 46 | +local ambi_tab = {} |
| 47 | + |
| 48 | +local wide_attrs = { |
| 49 | + F = true, |
| 50 | + W = true, |
| 51 | +} |
| 52 | +local zero_attrs = { |
| 53 | + Cf = true, |
| 54 | + Mc = true, |
| 55 | + Me = true, |
| 56 | + Mn = true, |
| 57 | + Zl = true, |
| 58 | + Zp = true, |
| 59 | +} |
| 60 | +local ambi_attrs = { |
| 61 | + A = true, |
| 62 | +} |
| 63 | + |
| 64 | +for line in io.lines() do |
| 65 | + local range_start, range_end, attribute, range_start_s, range_end_s |
| 66 | + |
| 67 | + range_start_s, attribute = line:match(pat_rune) |
| 68 | + if range_start_s then |
| 69 | + range_start = tonumber(range_start_s, 16) |
| 70 | + range_end = range_start |
| 71 | + else |
| 72 | + range_start_s, range_end_s, attribute = line:match(pat_range) |
| 73 | + if range_start_s then |
| 74 | + range_start = tonumber(range_start_s, 16) |
| 75 | + range_end = tonumber(range_end_s, 16) |
| 76 | + end |
| 77 | + end |
| 78 | + |
| 79 | + if range_start then |
| 80 | + local tab |
| 81 | + if wide_attrs[attribute] then |
| 82 | + tab = wide_tab |
| 83 | + elseif zero_attrs[attribute] then |
| 84 | + tab = zero_tab |
| 85 | + elseif ambi_attrs[attribute] then |
| 86 | + tab = ambi_tab |
| 87 | + end |
| 88 | + if tab then |
| 89 | + tab[#tab + 1] = { range_start, range_end } |
| 90 | + end |
| 91 | + end |
| 92 | +end |
| 93 | + |
| 94 | +local function tab_sort_compare(a, b) |
| 95 | + return a[1] < b[1] |
| 96 | +end |
| 97 | + |
| 98 | +table.sort(wide_tab, tab_sort_compare) |
| 99 | +table.sort(zero_tab, tab_sort_compare) |
| 100 | +table.sort(ambi_tab, tab_sort_compare) |
| 101 | + |
| 102 | +local tab_dump_line_format = "\t0x%X, 0x%X,\n" |
| 103 | +local function tab_dump(tab, out) |
| 104 | + out:write("-- Automatically generated, do not edit\n") |
| 105 | + out:write("return {\n") |
| 106 | + for _, item in ipairs(tab) do |
| 107 | + out:write(tab_dump_line_format:format(item[1], item[2])) |
| 108 | + end |
| 109 | + out:write("}\n") |
| 110 | +end |
| 111 | + |
| 112 | +tab_dump(wide_tab, io.open(path_prefix .. "/" .. wide_tab_path, "w")) |
| 113 | +tab_dump(zero_tab, io.open(path_prefix .. "/" .. zero_tab_path, "w")) |
| 114 | +tab_dump(ambi_tab, io.open(path_prefix .. "/" .. ambi_tab_path, "w")) |
0 commit comments