app/src/main/kotlin/space/subread/overlay/Words.kt (1281 bytes)
1 package space.subread.overlay 2 3 import android.icu.text.BreakIterator 4 5 /** Finds the word under a finger. */ 6 object Words { 7 8 /** 9 * The range of the word of [text] that has the character at [offset]; null on a space or a 10 * punctuation mark. 11 * 12 * ICU cuts Japanese, Chinese and Thai with a dictionary, and other scripts at spaces and 13 * punctuation. The cut is a good first try, not a parse: the user can drag to make the 14 * selection longer. 15 */ 16 fun at(text: CharSequence, offset: Int): IntRange? { 17 if (offset !in text.indices) return null 18 val words = BreakIterator.getWordInstance() 19 words.setText(text.toString()) 20 val end = words.following(offset) 21 if (end == BreakIterator.DONE) return null 22 val isWord = words.ruleStatus != BreakIterator.WORD_NONE 23 val start = words.previous() 24 return if (isWord && start != BreakIterator.DONE) start until end else null 25 } 26 27 /** The range from the word at [anchor] to the word at [offset], in the order of the text. */ 28 fun between(text: CharSequence, anchor: IntRange, offset: Int): IntRange { 29 val other = at(text, offset) ?: return anchor 30 return minOf(anchor.first, other.first)..maxOf(anchor.last, other.last) 31 } 32 }