diff options
author | Bohdan Horbeshko <bodqhrohro@gmail.com> | 2022-03-12 04:27:15 +0300 |
---|---|---|
committer | Bohdan Horbeshko <bodqhrohro@gmail.com> | 2022-03-12 04:27:15 +0300 |
commit | c6556eb6b86d4267bb35b7a27c34a0046668e3b9 (patch) | |
tree | dce73e18ffa5c46c03f877d8700f72bf1551cfdf /telegram/formatter/formatter.go | |
parent | ae8152ad87b32c827fa681285717b7b6ae3176fd (diff) |
Clasp directives to the following span as required by XEP-0393
Diffstat (limited to 'telegram/formatter/formatter.go')
-rw-r--r-- | telegram/formatter/formatter.go | 51 |
1 files changed, 50 insertions, 1 deletions
diff --git a/telegram/formatter/formatter.go b/telegram/formatter/formatter.go index eca514a..d6541cb 100644 --- a/telegram/formatter/formatter.go +++ b/telegram/formatter/formatter.go @@ -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)) |