diff --git a/scripts/unicode.py b/scripts/unicode.py index d253dcd..404b242 100755 --- a/scripts/unicode.py +++ b/scripts/unicode.py @@ -283,6 +283,41 @@ def emit_property_module(f, mod, tbl, emit: "list[str | tuple[str, str]]"): f.write(" }\n\n") f.write("}\n\n") +def check_incb_derivable(grapheme_table, incb_extend, incb_linker): + """Check that `InCB=Extend` can be recovered from the Grapheme_Cluster_Break category. + + `grapheme::is_incb_extend` in src/grapheme.rs derives it as + `[\\p{gcb=Extend} \\p{gcb=ZWJ}] - \\p{InCB=Linker} - U+200C` instead of carrying a range table for it, + which also lets the cursor skip the lookup for every category that is neither `Extend` nor `ZWJ`. + + Both facts are checked here so that a Unicode version which invalidates + either fails loudly instead of silently mis-segmenting Indic text. + """ + extend_or_zwj = set() + for (lo, hi, cat) in grapheme_table: + if cat in ("Extend", "ZWJ"): + extend_or_zwj.update(range(lo, hi + 1)) + linkers = {cp for (lo, hi) in incb_linker for cp in range(lo, hi + 1)} + actual = {cp for (lo, hi) in incb_extend for cp in range(lo, hi + 1)} + + stray = sorted(linkers - extend_or_zwj) + if stray: + raise AssertionError( + "InCB=Linker is no longer a subset of gcb=Extend and gcb=ZWJ (%s); " + "grapheme::is_incb_extend in src/grapheme.rs would miss it" + % [hex(c) for c in stray[:8]]) + + derived = extend_or_zwj - linkers - {0x200C} + if actual != derived: + raise AssertionError( + "InCB=Extend is no longer [gcb=Extend gcb=ZWJ] - InCB=Linker - U+200C; " + "grapheme::is_incb_extend in src/grapheme.rs would be wrong. missing=%s extra=%s" + % ([hex(c) for c in sorted(actual - derived)[:8]], + [hex(c) for c in sorted(derived - actual)[:8]])) + + sys.stderr.write( + "InCB=Extend: %d codepoints, all derivable from the grapheme category\n" % len(actual)) + def emit_break_module(f, break_table, break_cats, name): Name = name.capitalize() f.write("""pub mod %s { @@ -408,7 +443,7 @@ def emit_break_module(f, break_table, break_cats, name): emit_util_mod(rf) for (name, cat, pfuns) in ("general_category", gencats, ["N"]), \ - ("derived_property", derived, ["Alphabetic", ("InCB", "Extend")]): + ("derived_property", derived, ["Alphabetic"]): emit_property_module(rf, name, cat, pfuns) rf.write("""pub fn is_incb_linker(c: char) -> bool { @@ -444,6 +479,8 @@ def emit_break_module(f, break_table, break_cats, name): if chars[0] <= last: raise "Grapheme tables and Extended_Pictographic values overlap; need to store these separately!" last = chars[1] + check_incb_derivable(grapheme_table, derived[("InCB", "Extend")], + derived[("InCB", "Linker")]) emit_break_module(rf, grapheme_table, list(grapheme_cats.keys()), "grapheme") rf.write("\n") diff --git a/src/grapheme.rs b/src/grapheme.rs index d33a351..0b39f0c 100644 --- a/src/grapheme.rs +++ b/src/grapheme.rs @@ -284,6 +284,30 @@ fn check_pair(before: GraphemeCat, after: GraphemeCat) -> PairResult { } } +/// Whether `ch`, whose grapheme category is `cat`, has `Indic_Conjunct_Break=Extend`. +/// +/// `InCB=Extend` is defined as +/// `[\p{gcb=Extend} \p{gcb=ZWJ}] - \p{InCB=Linker} - \p{InCB=Consonant} - U+200C`, +/// and no `InCB=Consonant` is `gcb=Extend` or `gcb=ZWJ`, +/// so the grapheme category the caller already has, plus two equality tests, decides it. +/// +/// That saves a binary search over a range table of its own for every codepoint the cursor walks over. +/// +/// `scripts/unicode.py` checks the derivation against the UCD when it regenerates `src/tables.rs`, +/// so a future Unicode version cannot silently invalidate it. +#[inline] +fn is_incb_extend(cat: GraphemeCat, ch: char) -> bool { + // ZWNJ is `gcb=Extend` but `InCB=None`. + may_be_incb(cat) && ch != '\u{200c}' && !crate::tables::is_incb_linker(ch) +} + +/// Both `InCB=Linker` and `InCB=Extend` are subsets of `gcb=Extend` and `gcb=ZWJ`, +/// so any other category rules out both roles without inspecting the codepoint. +#[inline] +fn may_be_incb(cat: GraphemeCat) -> bool { + matches!(cat, GraphemeCat::GC_Extend | GraphemeCat::GC_ZWJ) +} + impl GraphemeCursor { /// Create a new cursor. The string and initial offset are given at creation /// time, but the contents of the string are not. The `is_extended` parameter @@ -492,7 +516,7 @@ impl GraphemeCursor { // We found an InCB linker incb_linker_count += 1; self.incb_linker_count = Some(incb_linker_count); - } else if tables::derived_property::InCB_Extend(ch) { + } else if is_incb_extend(self.grapheme_category(ch), ch) { // We ignore InCB extends, continue } else { // Prev character is neither linker nor extend, break suppressed iff it's InCB=Consonant @@ -724,10 +748,11 @@ impl GraphemeCursor { if self.cat_before.is_none() { self.cat_before = Some(self.grapheme_category(ch)); } - if crate::tables::is_incb_linker(ch) { - self.incb_linker_count = Some(self.incb_linker_count.map_or(1, |c| c + 1)); - } else if !crate::tables::derived_property::InCB_Extend(ch) { + // ZWNJ is the one `gcb=Extend` that is `InCB=None`. + if !may_be_incb(self.cat_before.unwrap()) || ch == '\u{200c}' { self.incb_linker_count = Some(0); + } else if crate::tables::is_incb_linker(ch) { + self.incb_linker_count = Some(self.incb_linker_count.map_or(1, |c| c + 1)); } if self.cat_before.unwrap() == GraphemeCat::GC_Regional_Indicator { self.ris_count = self.ris_count.map(|c| c + 1); @@ -816,7 +841,7 @@ impl GraphemeCursor { self.incb_linker_count = if incb_linker_count > 0 && crate::tables::is_incb_linker(ch) { Some(incb_linker_count - 1) - } else if crate::tables::derived_property::InCB_Extend(ch) { + } else if is_incb_extend(self.grapheme_category(ch), ch) { Some(incb_linker_count) } else { None diff --git a/src/tables.rs b/src/tables.rs index efa2a41..645642b 100644 --- a/src/tables.rs +++ b/src/tables.rs @@ -361,130 +361,6 @@ pub mod derived_property { super::util::bsearch_range_table(c, Alphabetic_table) } - const InCB_Extend_table: &[(char, char)] = &[ - ('\u{300}', '\u{36f}'), ('\u{483}', '\u{489}'), ('\u{591}', '\u{5bd}'), ('\u{5bf}', - '\u{5bf}'), ('\u{5c1}', '\u{5c2}'), ('\u{5c4}', '\u{5c5}'), ('\u{5c7}', '\u{5c7}'), - ('\u{610}', '\u{61a}'), ('\u{64b}', '\u{65f}'), ('\u{670}', '\u{670}'), ('\u{6d6}', - '\u{6dc}'), ('\u{6df}', '\u{6e4}'), ('\u{6e7}', '\u{6e8}'), ('\u{6ea}', '\u{6ed}'), - ('\u{711}', '\u{711}'), ('\u{730}', '\u{74a}'), ('\u{7a6}', '\u{7b0}'), ('\u{7eb}', - '\u{7f3}'), ('\u{7fd}', '\u{7fd}'), ('\u{816}', '\u{819}'), ('\u{81b}', '\u{823}'), - ('\u{825}', '\u{827}'), ('\u{829}', '\u{82d}'), ('\u{859}', '\u{85b}'), ('\u{897}', - '\u{89f}'), ('\u{8ca}', '\u{8e1}'), ('\u{8e3}', '\u{902}'), ('\u{93a}', '\u{93a}'), - ('\u{93c}', '\u{93c}'), ('\u{941}', '\u{948}'), ('\u{951}', '\u{957}'), ('\u{962}', - '\u{963}'), ('\u{981}', '\u{981}'), ('\u{9bc}', '\u{9bc}'), ('\u{9be}', '\u{9be}'), - ('\u{9c1}', '\u{9c4}'), ('\u{9d7}', '\u{9d7}'), ('\u{9e2}', '\u{9e3}'), ('\u{9fe}', - '\u{9fe}'), ('\u{a01}', '\u{a02}'), ('\u{a3c}', '\u{a3c}'), ('\u{a41}', '\u{a42}'), - ('\u{a47}', '\u{a48}'), ('\u{a4b}', '\u{a4d}'), ('\u{a51}', '\u{a51}'), ('\u{a70}', - '\u{a71}'), ('\u{a75}', '\u{a75}'), ('\u{a81}', '\u{a82}'), ('\u{abc}', '\u{abc}'), - ('\u{ac1}', '\u{ac5}'), ('\u{ac7}', '\u{ac8}'), ('\u{ae2}', '\u{ae3}'), ('\u{afa}', - '\u{aff}'), ('\u{b01}', '\u{b01}'), ('\u{b3c}', '\u{b3c}'), ('\u{b3e}', '\u{b3f}'), - ('\u{b41}', '\u{b44}'), ('\u{b55}', '\u{b57}'), ('\u{b62}', '\u{b63}'), ('\u{b82}', - '\u{b82}'), ('\u{bbe}', '\u{bbe}'), ('\u{bc0}', '\u{bc0}'), ('\u{bcd}', '\u{bcd}'), - ('\u{bd7}', '\u{bd7}'), ('\u{c00}', '\u{c00}'), ('\u{c04}', '\u{c04}'), ('\u{c3c}', - '\u{c3c}'), ('\u{c3e}', '\u{c40}'), ('\u{c46}', '\u{c48}'), ('\u{c4a}', '\u{c4c}'), - ('\u{c55}', '\u{c56}'), ('\u{c62}', '\u{c63}'), ('\u{c81}', '\u{c81}'), ('\u{cbc}', - '\u{cbc}'), ('\u{cbf}', '\u{cc0}'), ('\u{cc2}', '\u{cc2}'), ('\u{cc6}', '\u{cc8}'), - ('\u{cca}', '\u{ccd}'), ('\u{cd5}', '\u{cd6}'), ('\u{ce2}', '\u{ce3}'), ('\u{d00}', - '\u{d01}'), ('\u{d3b}', '\u{d3c}'), ('\u{d3e}', '\u{d3e}'), ('\u{d41}', '\u{d44}'), - ('\u{d57}', '\u{d57}'), ('\u{d62}', '\u{d63}'), ('\u{d81}', '\u{d81}'), ('\u{dca}', - '\u{dca}'), ('\u{dcf}', '\u{dcf}'), ('\u{dd2}', '\u{dd4}'), ('\u{dd6}', '\u{dd6}'), - ('\u{ddf}', '\u{ddf}'), ('\u{e31}', '\u{e31}'), ('\u{e34}', '\u{e3a}'), ('\u{e47}', - '\u{e4e}'), ('\u{eb1}', '\u{eb1}'), ('\u{eb4}', '\u{ebc}'), ('\u{ec8}', '\u{ece}'), - ('\u{f18}', '\u{f19}'), ('\u{f35}', '\u{f35}'), ('\u{f37}', '\u{f37}'), ('\u{f39}', - '\u{f39}'), ('\u{f71}', '\u{f7e}'), ('\u{f80}', '\u{f84}'), ('\u{f86}', '\u{f87}'), - ('\u{f8d}', '\u{f97}'), ('\u{f99}', '\u{fbc}'), ('\u{fc6}', '\u{fc6}'), ('\u{102d}', - '\u{1030}'), ('\u{1032}', '\u{1037}'), ('\u{103a}', '\u{103a}'), ('\u{103d}', '\u{103e}'), - ('\u{1058}', '\u{1059}'), ('\u{105e}', '\u{1060}'), ('\u{1071}', '\u{1074}'), ('\u{1082}', - '\u{1082}'), ('\u{1085}', '\u{1086}'), ('\u{108d}', '\u{108d}'), ('\u{109d}', '\u{109d}'), - ('\u{135d}', '\u{135f}'), ('\u{1712}', '\u{1715}'), ('\u{1732}', '\u{1734}'), ('\u{1752}', - '\u{1753}'), ('\u{1772}', '\u{1773}'), ('\u{17b4}', '\u{17b5}'), ('\u{17b7}', '\u{17bd}'), - ('\u{17c6}', '\u{17c6}'), ('\u{17c9}', '\u{17d1}'), ('\u{17d3}', '\u{17d3}'), ('\u{17dd}', - '\u{17dd}'), ('\u{180b}', '\u{180d}'), ('\u{180f}', '\u{180f}'), ('\u{1885}', '\u{1886}'), - ('\u{18a9}', '\u{18a9}'), ('\u{1920}', '\u{1922}'), ('\u{1927}', '\u{1928}'), ('\u{1932}', - '\u{1932}'), ('\u{1939}', '\u{193b}'), ('\u{1a17}', '\u{1a18}'), ('\u{1a1b}', '\u{1a1b}'), - ('\u{1a56}', '\u{1a56}'), ('\u{1a58}', '\u{1a5e}'), ('\u{1a62}', '\u{1a62}'), ('\u{1a65}', - '\u{1a6c}'), ('\u{1a73}', '\u{1a7c}'), ('\u{1a7f}', '\u{1a7f}'), ('\u{1ab0}', '\u{1add}'), - ('\u{1ae0}', '\u{1aeb}'), ('\u{1b00}', '\u{1b03}'), ('\u{1b34}', '\u{1b3d}'), ('\u{1b42}', - '\u{1b43}'), ('\u{1b6b}', '\u{1b73}'), ('\u{1b80}', '\u{1b81}'), ('\u{1ba2}', '\u{1ba5}'), - ('\u{1ba8}', '\u{1baa}'), ('\u{1bac}', '\u{1bad}'), ('\u{1be6}', '\u{1be6}'), ('\u{1be8}', - '\u{1be9}'), ('\u{1bed}', '\u{1bed}'), ('\u{1bef}', '\u{1bf3}'), ('\u{1c2c}', '\u{1c33}'), - ('\u{1c36}', '\u{1c37}'), ('\u{1cd0}', '\u{1cd2}'), ('\u{1cd4}', '\u{1ce0}'), ('\u{1ce2}', - '\u{1ce8}'), ('\u{1ced}', '\u{1ced}'), ('\u{1cf4}', '\u{1cf4}'), ('\u{1cf8}', '\u{1cf9}'), - ('\u{1dc0}', '\u{1dff}'), ('\u{200d}', '\u{200d}'), ('\u{20d0}', '\u{20f0}'), ('\u{2cef}', - '\u{2cf1}'), ('\u{2d7f}', '\u{2d7f}'), ('\u{2de0}', '\u{2dff}'), ('\u{302a}', '\u{302f}'), - ('\u{3099}', '\u{309a}'), ('\u{a66f}', '\u{a672}'), ('\u{a674}', '\u{a67d}'), ('\u{a69e}', - '\u{a69f}'), ('\u{a6f0}', '\u{a6f1}'), ('\u{a802}', '\u{a802}'), ('\u{a806}', '\u{a806}'), - ('\u{a80b}', '\u{a80b}'), ('\u{a825}', '\u{a826}'), ('\u{a82c}', '\u{a82c}'), ('\u{a8c4}', - '\u{a8c5}'), ('\u{a8e0}', '\u{a8f1}'), ('\u{a8ff}', '\u{a8ff}'), ('\u{a926}', '\u{a92d}'), - ('\u{a947}', '\u{a951}'), ('\u{a953}', '\u{a953}'), ('\u{a980}', '\u{a982}'), ('\u{a9b3}', - '\u{a9b3}'), ('\u{a9b6}', '\u{a9b9}'), ('\u{a9bc}', '\u{a9bd}'), ('\u{a9e5}', '\u{a9e5}'), - ('\u{aa29}', '\u{aa2e}'), ('\u{aa31}', '\u{aa32}'), ('\u{aa35}', '\u{aa36}'), ('\u{aa43}', - '\u{aa43}'), ('\u{aa4c}', '\u{aa4c}'), ('\u{aa7c}', '\u{aa7c}'), ('\u{aab0}', '\u{aab0}'), - ('\u{aab2}', '\u{aab4}'), ('\u{aab7}', '\u{aab8}'), ('\u{aabe}', '\u{aabf}'), ('\u{aac1}', - '\u{aac1}'), ('\u{aaec}', '\u{aaed}'), ('\u{abe5}', '\u{abe5}'), ('\u{abe8}', '\u{abe8}'), - ('\u{abed}', '\u{abed}'), ('\u{fb1e}', '\u{fb1e}'), ('\u{fe00}', '\u{fe0f}'), ('\u{fe20}', - '\u{fe2f}'), ('\u{ff9e}', '\u{ff9f}'), ('\u{101fd}', '\u{101fd}'), ('\u{102e0}', - '\u{102e0}'), ('\u{10376}', '\u{1037a}'), ('\u{10a01}', '\u{10a03}'), ('\u{10a05}', - '\u{10a06}'), ('\u{10a0c}', '\u{10a0f}'), ('\u{10a38}', '\u{10a3a}'), ('\u{10ae5}', - '\u{10ae6}'), ('\u{10d24}', '\u{10d27}'), ('\u{10d69}', '\u{10d6d}'), ('\u{10eab}', - '\u{10eac}'), ('\u{10efa}', '\u{10eff}'), ('\u{10f46}', '\u{10f50}'), ('\u{10f82}', - '\u{10f85}'), ('\u{11001}', '\u{11001}'), ('\u{11038}', '\u{11046}'), ('\u{11070}', - '\u{11070}'), ('\u{11073}', '\u{11074}'), ('\u{1107f}', '\u{11081}'), ('\u{110b3}', - '\u{110b6}'), ('\u{110b9}', '\u{110ba}'), ('\u{110c2}', '\u{110c2}'), ('\u{11100}', - '\u{11102}'), ('\u{11127}', '\u{1112b}'), ('\u{1112d}', '\u{11132}'), ('\u{11134}', - '\u{11134}'), ('\u{11173}', '\u{11173}'), ('\u{11180}', '\u{11181}'), ('\u{111b6}', - '\u{111be}'), ('\u{111c0}', '\u{111c0}'), ('\u{111c9}', '\u{111cc}'), ('\u{111cf}', - '\u{111cf}'), ('\u{1122f}', '\u{11231}'), ('\u{11234}', '\u{11237}'), ('\u{1123e}', - '\u{1123e}'), ('\u{11241}', '\u{11241}'), ('\u{112df}', '\u{112df}'), ('\u{112e3}', - '\u{112ea}'), ('\u{11300}', '\u{11301}'), ('\u{1133b}', '\u{1133c}'), ('\u{1133e}', - '\u{1133e}'), ('\u{11340}', '\u{11340}'), ('\u{1134d}', '\u{1134d}'), ('\u{11357}', - '\u{11357}'), ('\u{11366}', '\u{1136c}'), ('\u{11370}', '\u{11374}'), ('\u{113b8}', - '\u{113b8}'), ('\u{113bb}', '\u{113c0}'), ('\u{113c2}', '\u{113c2}'), ('\u{113c5}', - '\u{113c5}'), ('\u{113c7}', '\u{113c9}'), ('\u{113ce}', '\u{113cf}'), ('\u{113d2}', - '\u{113d2}'), ('\u{113e1}', '\u{113e2}'), ('\u{11438}', '\u{1143f}'), ('\u{11442}', - '\u{11444}'), ('\u{11446}', '\u{11446}'), ('\u{1145e}', '\u{1145e}'), ('\u{114b0}', - '\u{114b0}'), ('\u{114b3}', '\u{114b8}'), ('\u{114ba}', '\u{114ba}'), ('\u{114bd}', - '\u{114bd}'), ('\u{114bf}', '\u{114c0}'), ('\u{114c2}', '\u{114c3}'), ('\u{115af}', - '\u{115af}'), ('\u{115b2}', '\u{115b5}'), ('\u{115bc}', '\u{115bd}'), ('\u{115bf}', - '\u{115c0}'), ('\u{115dc}', '\u{115dd}'), ('\u{11633}', '\u{1163a}'), ('\u{1163d}', - '\u{1163d}'), ('\u{1163f}', '\u{11640}'), ('\u{116ab}', '\u{116ab}'), ('\u{116ad}', - '\u{116ad}'), ('\u{116b0}', '\u{116b7}'), ('\u{1171d}', '\u{1171d}'), ('\u{1171f}', - '\u{1171f}'), ('\u{11722}', '\u{11725}'), ('\u{11727}', '\u{1172b}'), ('\u{1182f}', - '\u{11837}'), ('\u{11839}', '\u{1183a}'), ('\u{11930}', '\u{11930}'), ('\u{1193b}', - '\u{1193d}'), ('\u{11943}', '\u{11943}'), ('\u{119d4}', '\u{119d7}'), ('\u{119da}', - '\u{119db}'), ('\u{119e0}', '\u{119e0}'), ('\u{11a01}', '\u{11a0a}'), ('\u{11a33}', - '\u{11a38}'), ('\u{11a3b}', '\u{11a3e}'), ('\u{11a51}', '\u{11a56}'), ('\u{11a59}', - '\u{11a5b}'), ('\u{11a8a}', '\u{11a96}'), ('\u{11a98}', '\u{11a98}'), ('\u{11b60}', - '\u{11b60}'), ('\u{11b62}', '\u{11b64}'), ('\u{11b66}', '\u{11b66}'), ('\u{11c30}', - '\u{11c36}'), ('\u{11c38}', '\u{11c3d}'), ('\u{11c3f}', '\u{11c3f}'), ('\u{11c92}', - '\u{11ca7}'), ('\u{11caa}', '\u{11cb0}'), ('\u{11cb2}', '\u{11cb3}'), ('\u{11cb5}', - '\u{11cb6}'), ('\u{11d31}', '\u{11d36}'), ('\u{11d3a}', '\u{11d3a}'), ('\u{11d3c}', - '\u{11d3d}'), ('\u{11d3f}', '\u{11d45}'), ('\u{11d47}', '\u{11d47}'), ('\u{11d90}', - '\u{11d91}'), ('\u{11d95}', '\u{11d95}'), ('\u{11d97}', '\u{11d97}'), ('\u{11ef3}', - '\u{11ef4}'), ('\u{11f00}', '\u{11f01}'), ('\u{11f36}', '\u{11f3a}'), ('\u{11f40}', - '\u{11f41}'), ('\u{11f5a}', '\u{11f5a}'), ('\u{13440}', '\u{13440}'), ('\u{13447}', - '\u{13455}'), ('\u{1611e}', '\u{16129}'), ('\u{1612d}', '\u{1612f}'), ('\u{16af0}', - '\u{16af4}'), ('\u{16b30}', '\u{16b36}'), ('\u{16f4f}', '\u{16f4f}'), ('\u{16f8f}', - '\u{16f92}'), ('\u{16fe4}', '\u{16fe4}'), ('\u{16ff0}', '\u{16ff1}'), ('\u{1bc9d}', - '\u{1bc9e}'), ('\u{1cf00}', '\u{1cf2d}'), ('\u{1cf30}', '\u{1cf46}'), ('\u{1d165}', - '\u{1d169}'), ('\u{1d16d}', '\u{1d172}'), ('\u{1d17b}', '\u{1d182}'), ('\u{1d185}', - '\u{1d18b}'), ('\u{1d1aa}', '\u{1d1ad}'), ('\u{1d242}', '\u{1d244}'), ('\u{1da00}', - '\u{1da36}'), ('\u{1da3b}', '\u{1da6c}'), ('\u{1da75}', '\u{1da75}'), ('\u{1da84}', - '\u{1da84}'), ('\u{1da9b}', '\u{1da9f}'), ('\u{1daa1}', '\u{1daaf}'), ('\u{1e000}', - '\u{1e006}'), ('\u{1e008}', '\u{1e018}'), ('\u{1e01b}', '\u{1e021}'), ('\u{1e023}', - '\u{1e024}'), ('\u{1e026}', '\u{1e02a}'), ('\u{1e08f}', '\u{1e08f}'), ('\u{1e130}', - '\u{1e136}'), ('\u{1e2ae}', '\u{1e2ae}'), ('\u{1e2ec}', '\u{1e2ef}'), ('\u{1e4ec}', - '\u{1e4ef}'), ('\u{1e5ee}', '\u{1e5ef}'), ('\u{1e6e3}', '\u{1e6e3}'), ('\u{1e6e6}', - '\u{1e6e6}'), ('\u{1e6ee}', '\u{1e6ef}'), ('\u{1e6f5}', '\u{1e6f5}'), ('\u{1e8d0}', - '\u{1e8d6}'), ('\u{1e944}', '\u{1e94a}'), ('\u{1f3fb}', '\u{1f3ff}'), ('\u{e0020}', - '\u{e007f}'), ('\u{e0100}', '\u{e01ef}') - ]; - - #[inline] - pub fn InCB_Extend(c: char) -> bool { - super::util::bsearch_range_table(c, InCB_Extend_table) - } - } pub fn is_incb_linker(c: char) -> bool {