|
|
|
@ -2,6 +2,7 @@ package formatter
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"sort"
|
|
|
|
|
"unicode"
|
|
|
|
|
|
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
|
"github.com/zelenin/go-tdlib/client"
|
|
|
|
@ -118,6 +119,54 @@ func MergeAdjacentEntities(entities []*client.TextEntity) []*client.TextEntity {
|
|
|
|
|
return mergedEntities
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ClaspDirectives to the following span as required by XEP-0393
|
|
|
|
|
func ClaspDirectives(text string, entities []*client.TextEntity) []*client.TextEntity {
|
|
|
|
|
alignedEntities := make([]*client.TextEntity, len(entities))
|
|
|
|
|
copy(alignedEntities, entities)
|
|
|
|
|
|
|
|
|
|
// transform the source text into a form with uniform runes and code points,
|
|
|
|
|
// by duplicating the Basic Multilingual Plane
|
|
|
|
|
doubledRunes := make([]rune, 0, len(text)*2)
|
|
|
|
|
|
|
|
|
|
for _, cp := range text {
|
|
|
|
|
if cp > 0x0000ffff {
|
|
|
|
|
doubledRunes = append(doubledRunes, cp, cp)
|
|
|
|
|
} else {
|
|
|
|
|
doubledRunes = append(doubledRunes, cp)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for i, entity := range alignedEntities {
|
|
|
|
|
var dirty bool
|
|
|
|
|
endOffset := entity.Offset + entity.Length
|
|
|
|
|
|
|
|
|
|
if unicode.IsSpace(doubledRunes[entity.Offset]) {
|
|
|
|
|
for j, r := range doubledRunes[entity.Offset+1:endOffset] {
|
|
|
|
|
if !unicode.IsSpace(r) {
|
|
|
|
|
dirty = true
|
|
|
|
|
entity.Offset += int32(j+1)
|
|
|
|
|
entity.Length -= int32(j+1)
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if unicode.IsSpace(doubledRunes[endOffset-1]) {
|
|
|
|
|
for j := endOffset-2; j >= entity.Offset; j-- {
|
|
|
|
|
if !unicode.IsSpace(doubledRunes[j]) {
|
|
|
|
|
dirty = true
|
|
|
|
|
entity.Length = j+1-entity.Offset
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if dirty {
|
|
|
|
|
alignedEntities[i] = entity
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return alignedEntities
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func markupBraces(entity *client.TextEntity, lbrace, rbrace []rune) (*Insertion, *Insertion) {
|
|
|
|
|
return &Insertion{
|
|
|
|
|
Offset: entity.Offset,
|
|
|
|
@ -191,7 +240,7 @@ func Format(
|
|
|
|
|
return sourceText
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mergedEntities := SortEntities(MergeAdjacentEntities(SortEntities(entities)))
|
|
|
|
|
mergedEntities := SortEntities(ClaspDirectives(sourceText, MergeAdjacentEntities(SortEntities(entities))))
|
|
|
|
|
|
|
|
|
|
startStack := make(InsertionStack, 0, len(sourceText))
|
|
|
|
|
endStack := make(InsertionStack, 0, len(sourceText))
|
|
|
|
|