diff options
Diffstat (limited to 'telegram/formatter/formatter.go')
-rw-r--r-- | telegram/formatter/formatter.go | 54 |
1 files changed, 52 insertions, 2 deletions
diff --git a/telegram/formatter/formatter.go b/telegram/formatter/formatter.go index 999d659..5ea5cdb 100644 --- a/telegram/formatter/formatter.go +++ b/telegram/formatter/formatter.go @@ -22,7 +22,7 @@ var boldRunesXEP0393 = []rune("*") var italicRunes = []rune("_") var codeRunes = []rune("\n```\n") -// rebalance pumps all the values at given offset to current stack (growing +// rebalance pumps all the values until the given offset to current stack (growing // from start) from given stack (growing from end); should be called // before any insertions to the current stack at the given offset func (s InsertionStack) rebalance(s2 InsertionStack, offset int32) (InsertionStack, InsertionStack) { @@ -66,6 +66,54 @@ func SortEntities(entities []*client.TextEntity) []*client.TextEntity { return sortedEntities } +// MergeAdjacentEntities merges entities of a same kind +func MergeAdjacentEntities(entities []*client.TextEntity) []*client.TextEntity { + mergedEntities := make([]*client.TextEntity, 0, len(entities)) + excludedIndices := make(map[int]bool) + + for i, entity := range entities { + if excludedIndices[i] { + continue + } + + typ := entity.Type.TextEntityTypeType() + start := entity.Offset + end := start + entity.Length + ei := make(map[int]bool) + + // collect continuations + for j, entity2 := range entities[i+1:] { + if entity2.Type.TextEntityTypeType() == typ && entity2.Offset == end { + end += entity2.Length + ei[j+i+1] = true + } + } + + // check for intersections with other entities + var isIntersecting bool + if len(ei) > 0 { + for _, entity2 := range entities { + entity2End := entity2.Offset + entity2.Length + if (entity2.Offset < start && entity2End > start && entity2End < end) || + (entity2.Offset > start && entity2.Offset < end && entity2End > end) { + isIntersecting = true + break + } + } + } + + if !isIntersecting { + entity.Length = end - start + for j := range ei { + excludedIndices[j] = true + } + } + mergedEntities = append(mergedEntities, entity) + } + + return mergedEntities +} + func markupBraces(entity *client.TextEntity, lbrace, rbrace []rune) (*Insertion, *Insertion) { return &Insertion{ Offset: entity.Offset, @@ -132,12 +180,14 @@ func Format( return sourceText } + mergedEntities := SortEntities(MergeAdjacentEntities(SortEntities(entities))) + startStack := make(InsertionStack, 0, len(sourceText)) endStack := make(InsertionStack, 0, len(sourceText)) // convert entities to a stack of brackets var maxEndOffset int32 - for _, entity := range entities { + for _, entity := range mergedEntities { log.Debugf("%#v", entity) if entity.Length <= 0 { continue |