Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 38 additions & 1 deletion scripts/unicode.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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")

Expand Down
35 changes: 30 additions & 5 deletions src/grapheme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down
124 changes: 0 additions & 124 deletions src/tables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Loading