Skip to content

Commit

Permalink
Add WSegSpace support for in word boundaries from Unicode 11
Browse files Browse the repository at this point in the history
  • Loading branch information
Manishearth committed Oct 29, 2019
1 parent 98c9457 commit df71866
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
//!
//! let s = "The quick (\"brown\") fox";
//! let w = s.split_word_bounds().collect::<Vec<&str>>();
//! let b: &[_] = &["The", " ", "quick", " ", "(", "\"", "brown", "\"", ")", " ", " ", "fox"];
//! let b: &[_] = &["The", " ", "quick", " ", "(", "\"", "brown", "\"", ")", " ", "fox"];
//! assert_eq!(w, b);
//! }
//! ```
Expand Down Expand Up @@ -156,7 +156,7 @@ pub trait UnicodeSegmentation {
/// ```
/// # use self::unicode_segmentation::UnicodeSegmentation;
/// let swu1 = "The quick (\"brown\") fox".split_word_bounds().collect::<Vec<&str>>();
/// let b: &[_] = &["The", " ", "quick", " ", "(", "\"", "brown", "\"", ")", " ", " ", "fox"];
/// let b: &[_] = &["The", " ", "quick", " ", "(", "\"", "brown", "\"", ")", " ", "fox"];
///
/// assert_eq!(&swu1[..], b);
/// ```
Expand Down
25 changes: 25 additions & 0 deletions src/word.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ enum UWordBoundsState {
FormatExtend(FormatExtendType),
Zwj,
Emoji,
WSegSpace,
}

// subtypes for FormatExtend state in UWordBoundsState
Expand Down Expand Up @@ -156,6 +157,8 @@ impl<'a> Iterator for UWordBounds<'a> {
// Whether or not the previous category was ZWJ
// ZWJs get collapsed, so this handles precedence of WB3c over WB4
let mut prev_zwj;
// If extend/format/zwj were skipped. Handles precedence of WB3d over WB4
let mut skipped_format_extend = false;
for (curr, ch) in self.string.char_indices() {
idx = curr;
prev_zwj = cat == wd::WC_ZWJ;
Expand All @@ -177,6 +180,7 @@ impl<'a> Iterator for UWordBounds<'a> {
if state != Start {
match cat {
wd::WC_Extend | wd::WC_Format | wd::WC_ZWJ => {
skipped_format_extend = true;
continue
}
_ => {}
Expand Down Expand Up @@ -219,6 +223,7 @@ impl<'a> Iterator for UWordBounds<'a> {
wd::WC_Regional_Indicator => Regional(RegionalState::Half), // rule WB13c
wd::WC_LF | wd::WC_Newline => break, // rule WB3a
wd::WC_ZWJ => Zwj, // rule WB3c
wd::WC_WSegSpace => WSegSpace, // rule WB3d
_ => {
if let Some(ncat) = self.get_next_cat(idx) { // rule WB4
if ncat == wd::WC_Format || ncat == wd::WC_Extend || ncat == wd::WC_ZWJ {
Expand All @@ -230,6 +235,13 @@ impl<'a> Iterator for UWordBounds<'a> {
break; // rule WB999
}
},
WSegSpace => match cat {
wd::WC_WSegSpace if !skipped_format_extend => WSegSpace,
_ => {
take_curr = false;
break;
}
},
Zwj => {
// We already handle WB3c above.
take_curr = false;
Expand Down Expand Up @@ -371,6 +383,8 @@ impl<'a> DoubleEndedIterator for UWordBounds<'a> {
let mut savestate = Start;
let mut cat = wd::WC_Any;

let mut skipped_format_extend = false;

for (curr, ch) in self.string.char_indices().rev() {
previdx = idx;
idx = curr;
Expand Down Expand Up @@ -409,6 +423,7 @@ impl<'a> DoubleEndedIterator for UWordBounds<'a> {
state = savestate;
previdx = saveidx;
take_cat = false;
skipped_format_extend = true;
}

// Don't use `continue` in this match without updating `catb`
Expand All @@ -427,6 +442,7 @@ impl<'a> DoubleEndedIterator for UWordBounds<'a> {
saveidx = idx;
FormatExtend(AcceptQLetter) // rule WB7a
},
wd::WC_WSegSpace => WSegSpace,
wd::WC_CR | wd::WC_LF | wd::WC_Newline => {
if state == Start {
if cat == wd::WC_LF {
Expand All @@ -451,6 +467,15 @@ impl<'a> DoubleEndedIterator for UWordBounds<'a> {
break;
}
},
WSegSpace => match cat { // rule WB3d
wd::WC_WSegSpace if !skipped_format_extend => {
WSegSpace
}
_ => {
take_curr = false;
break;
}
},
Letter | HLetter => match cat {
wd::WC_ALetter => Letter, // rule WB5
wd::WC_Hebrew_Letter => HLetter, // rule WB5
Expand Down

0 comments on commit df71866

Please sign in to comment.