@@ -18,6 +18,7 @@ package bidi // import "golang.org/x/text/unicode/bidi"
18
18
19
19
import (
20
20
"bytes"
21
+ "unicode"
21
22
)
22
23
23
24
// This API tries to avoid dealing with embedding levels for now. Under the hood
@@ -321,23 +322,36 @@ func (r *Run) Pos() (start, end int) {
321
322
// and returns the result. Modifiers will still follow the runes they modify.
322
323
// Brackets are replaced with their counterparts.
323
324
func AppendReverse (out , in []byte ) []byte {
324
- ret := make ([]byte , len (in )+ len (out ))
325
- copy (ret , out )
326
325
inRunes := bytes .Runes (in )
327
-
326
+ li := len (inRunes )
327
+ ret := make ([]rune , li )
328
+ modifiers := make ([]rune , 0 , li )
328
329
for i , r := range inRunes {
330
+ if unicode .In (r , unicode .M , unicode .Sk ) {
331
+ modifiers = append (modifiers , r )
332
+ continue
333
+ }
334
+ if len (modifiers ) > 0 {
335
+ ret [li - i ] = ret [li - i + len (modifiers )]
336
+ copy (ret [li - i + 1 :li - i + 1 + len (modifiers )], modifiers )
337
+ modifiers = nil
338
+ }
329
339
prop , _ := LookupRune (r )
330
340
if prop .IsBracket () {
331
- inRunes [i ] = prop .reverseBracket (r )
341
+ ret [li - i - 1 ] = prop .reverseBracket (r )
342
+ } else {
343
+ ret [li - i - 1 ] = r
332
344
}
333
345
}
334
-
335
- for i , j := 0 , len (inRunes ) - 1 ; i < j ; i , j = i + 1 , j - 1 {
336
- inRunes [ i ], inRunes [ j ] = inRunes [ j ], inRunes [ i ]
346
+ if len ( modifiers ) > 0 {
347
+ ret [ 0 ] = ret [ len (modifiers )]
348
+ copy ( ret [ 1 : 1 + len ( modifiers ) ], modifiers )
337
349
}
338
- copy (ret [len (out ):], string (inRunes ))
339
350
340
- return ret
351
+ res := make ([]byte , len (in )+ len (out ))
352
+ copy (res , out )
353
+ copy (res [len (out ):], string (ret ))
354
+ return res
341
355
}
342
356
343
357
// ReverseString reverses the order of characters in s and returns a new string.
@@ -347,13 +361,27 @@ func ReverseString(s string) string {
347
361
input := []rune (s )
348
362
li := len (input )
349
363
ret := make ([]rune , li )
364
+ modifiers := make ([]rune , 0 , li )
350
365
for i , r := range input {
366
+ if unicode .In (r , unicode .M , unicode .Sk ) {
367
+ modifiers = append (modifiers , r )
368
+ continue
369
+ }
370
+ if len (modifiers ) > 0 {
371
+ ret [li - i ] = ret [li - i + len (modifiers )]
372
+ copy (ret [li - i + 1 :li - i + 1 + len (modifiers )], modifiers )
373
+ modifiers = nil
374
+ }
351
375
prop , _ := LookupRune (r )
352
376
if prop .IsBracket () {
353
377
ret [li - i - 1 ] = prop .reverseBracket (r )
354
378
} else {
355
379
ret [li - i - 1 ] = r
356
380
}
357
381
}
382
+ if len (modifiers ) > 0 {
383
+ ret [0 ] = ret [len (modifiers )]
384
+ copy (ret [1 :1 + len (modifiers )], modifiers )
385
+ }
358
386
return string (ret )
359
387
}
0 commit comments