mirror of
https://github.com/tinode/chat.git
synced 2025-03-14 10:05:07 +00:00
forgot to add file
This commit is contained in:
81
server/drafty/grapheme.go
Normal file
81
server/drafty/grapheme.go
Normal file
@ -0,0 +1,81 @@
|
||||
package drafty
|
||||
|
||||
import (
|
||||
"github.com/rivo/uniseg"
|
||||
)
|
||||
|
||||
// graphemes is a container holding lengths of graphemes in a string.
|
||||
type graphemes struct {
|
||||
// The original string.
|
||||
original string
|
||||
|
||||
// Sizes of grapheme clusters within the original string.
|
||||
sizes []byte
|
||||
}
|
||||
|
||||
// prepareGraphemes returns a parsed grapheme container by splitting the string into grapheme clusters
|
||||
// and saving their lengths.
|
||||
func prepareGraphemes(str string) *graphemes {
|
||||
// Split the string into grapheme clusters and save the size of each cluster.
|
||||
sizes := make([]byte, 0, len(str))
|
||||
for state, remaining, cluster := -1, str, ""; len(remaining) > 0; {
|
||||
cluster, remaining, _, state = uniseg.StepString(remaining, state)
|
||||
sizes = append(sizes, byte(len(cluster)))
|
||||
}
|
||||
|
||||
return &graphemes{
|
||||
original: str,
|
||||
sizes: sizes,
|
||||
}
|
||||
}
|
||||
|
||||
// length returns the number of grapheme clusters in the original string.
|
||||
func (g *graphemes) length() int {
|
||||
if g == nil {
|
||||
return 0
|
||||
}
|
||||
return len(g.sizes)
|
||||
}
|
||||
|
||||
// string returns the original string from which the grapheme was created from.
|
||||
func (g *graphemes) string() string {
|
||||
if g == nil {
|
||||
return ""
|
||||
}
|
||||
return g.original
|
||||
}
|
||||
|
||||
// slice returns a new grapheme iterator containing graphemes from 'start' to 'end'.
|
||||
func (g *graphemes) slice(start, end int) *graphemes {
|
||||
|
||||
// Convert grapheme offsets to string offsets.
|
||||
s := 0
|
||||
for i := 0; i < start; i++ {
|
||||
s += int(g.sizes[i])
|
||||
}
|
||||
e := s
|
||||
for i := start; i < end; i++ {
|
||||
e += int(g.sizes[i])
|
||||
}
|
||||
|
||||
if e == 0 {
|
||||
println("G= ", g)
|
||||
}
|
||||
|
||||
return &graphemes{
|
||||
original: g.original[s:e],
|
||||
sizes: g.sizes[start:end],
|
||||
}
|
||||
}
|
||||
|
||||
// append appends 'other' grapheme iterator to 'g' iterator and returns g.
|
||||
// If g is nil, 'other' is returned.
|
||||
func (g *graphemes) append(other *graphemes) *graphemes {
|
||||
if g == nil {
|
||||
return other
|
||||
}
|
||||
|
||||
g.original += other.original
|
||||
g.sizes = append(g.sizes, other.sizes...)
|
||||
return g
|
||||
}
|
Reference in New Issue
Block a user