// DirectionString reports the direction of the given label as defined by RFC // 5893. The Bidi Rule does not have to be applied to labels of the category // LeftToRight. func DirectionString(s string) bidi.Direction { for i := 0; i < len(s); { e, sz := bidi.LookupString(s[i:]) if sz == 0 { i++ } c := e.Class() if c == bidi.R || c == bidi.AL || c == bidi.AN { return bidi.RightToLeft } i += sz } return bidi.LeftToRight }
func (t *Transformer) advanceString(s string) (n int, ok bool) { var e bidi.Properties var sz int for n < len(s) { if s[n] < utf8.RuneSelf { e, sz = asciiTable[s[n]], 1 } else { e, sz = bidi.LookupString(s[n:]) if sz <= 1 { if sz == 1 { return n, false // invalid UTF-8 } return n, true // incomplete UTF-8 encoding } } // TODO: using CompactClass results in noticeable speedup. // See unicode/bidi/prop.go:Properties.CompactClass. c := uint16(1 << e.Class()) t.seen |= c if t.seen&exclusiveRTL == exclusiveRTL { t.state = ruleInvalid return n, false } switch tr := transitions[t.state]; { case tr[0].mask&c != 0: t.state = tr[0].next case tr[1].mask&c != 0: t.state = tr[1].next default: t.state = ruleInvalid if t.isRTL() { return n, false } } n += sz } return n, true }