-
Notifications
You must be signed in to change notification settings - Fork 1
/
base.go
118 lines (105 loc) · 2.86 KB
/
base.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package bidih
import (
"github.com/apaxa-go/helper/mathh"
"github.com/apaxa-go/helper/unicodeh/bidih/internal/bidi"
)
type EmbeddingLevel uint8
func (level EmbeddingLevel) direction() bidi.Class {
if level%2 == 0 {
return bidi.LeftToRight
}
return bidi.RightToLeft
}
const (
LeftToRightParagraph EmbeddingLevel = 0
RightToLeftParagraph EmbeddingLevel = 1
MaxEmbeddingLevel EmbeddingLevel = 125
AutoParagraphDirection EmbeddingLevel = mathh.MaxUint8
//internalUnset EmbeddingLevel = mathh.MaxUint8
)
type Text struct {
// User defined
str string
paragraphEmbeddingLevel EmbeddingLevel
// Caches
runes []rune // Next runes
rawClasses []bidi.Class // Classes (as-is) of next runes
// Result
res []rune
}
func Parse(str string, paragraphEmbeddingLevel EmbeddingLevel) []rune {
t := Text{
// User defined
str: str,
paragraphEmbeddingLevel: paragraphEmbeddingLevel,
// Caches
// Result
res: make([]rune, 0, len(str)), // TODO may be be more carefully about memory???
}
return t.res
}
/*
func (t *Text) parse() {
nextStartNewParagraph := true
// Paragraph dependent data
var paragraphEL EmbeddingLevel
for runeI, r := range t.str {
var rawClass bidi.Class
if len(t.runes) > 0 {
t.runes = t.runes[1:]
rawClass = t.rawClasses[0]
t.rawClasses = t.rawClasses[1:]
} else {
rawClass = unicodeh.GetBidiClass(r)
}
if nextStartNewParagraph {
if t.paragraphEmbeddingLevel == AutoParagraphDirection {
// Paragraph embedding level auto detection
paragraphEL = t.determineParagraphLevel(rawClass, runeI+utf8.RuneLen(r))
} else {
// Paragraph embedding level defined by user
paragraphEL = t.paragraphEmbeddingLevel
}
}
// Rule P1
nextStartNewParagraph = rawClass == bidi.ParagraphSeparator
}
}
// returns AutoParagraphDirection if passed class is not enough
func decideParagraphLevel(rawClass bidi.Class) EmbeddingLevel {
switch rawClass {
case bidi.ArabicLetter, bidi.RightToLeft:
return RightToLeftParagraph
case bidi.LeftToRight, bidi.ParagraphSeparator:
return LeftToRightParagraph
default:
return AutoParagraphDirection
}
}
// Rule P2 & P3
func (t *Text) determineParagraphLevel(rawClass bidi.Class, nextRunePos int) EmbeddingLevel {
// By current rune
if res := decideParagraphLevel(rawClass); res != AutoParagraphDirection {
return res
}
// By cached runes
for i, rawClass := range t.rawClasses {
if res := decideParagraphLevel(rawClass); res != AutoParagraphDirection {
return res
}
nextRunePos += utf8.RuneLen(t.runes[i])
}
// By estimated string
for _, r := range t.str[nextRunePos:] {
rawClass = unicodeh.GetBidiClass(r)
// Cache
t.runes = append(t.runes, r)
t.rawClasses = append(t.rawClasses, rawClass)
//
if res := decideParagraphLevel(rawClass); res != AutoParagraphDirection {
return res
}
}
return LeftToRightParagraph
}
*/