Codebase list golang-github-rivo-uniseg / run/6ee89ecd-7000-4b73-b56e-0076d3e1c72c/main
New upstream release. Debian Janitor 1 year, 4 months ago
6 changed file(s) with 110 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
132132 - [`FirstSentence`](https://pkg.go.dev/github.com/rivo/uniseg#FirstSentence) or [`FirstSentenceInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstSentenceInString) for sentence segmentation only, and
133133 - [`FirstLineSegment`](https://pkg.go.dev/github.com/rivo/uniseg#FirstLineSegment) or [`FirstLineSegmentInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstLineSegmentInString) for line breaking / word wrapping (although using [`Step`](https://pkg.go.dev/github.com/rivo/uniseg#Step) or [`StepString`](https://pkg.go.dev/github.com/rivo/uniseg#StepString) is preferred as it will observe grapheme cluster boundaries).
134134
135 Finally, if you need to reverse a string while preserving grapheme clusters, use [`ReverseString`](https://pkg.go.dev/github.com/rivo/uniseg#ReverseString):
136
137 ```go
138 fmt.Println(uniseg.ReverseString("πŸ‡©πŸ‡ͺπŸ³οΈβ€πŸŒˆ"))
139 // πŸ³οΈβ€πŸŒˆπŸ‡©πŸ‡ͺ
140 ```
141
135142 ## Documentation
136143
137144 Refer to https://pkg.go.dev/github.com/rivo/uniseg for the package's documentation.
0 golang-github-rivo-uniseg (0.4.3-1) UNRELEASED; urgency=low
1
2 * New upstream release.
3
4 -- Debian Janitor <janitor@jelmer.uk> Sun, 01 Jan 2023 04:19:43 -0000
5
06 golang-github-rivo-uniseg (0.4.2-1) unstable; urgency=medium
17
28 * New upstream release
6969 Monospace width, as referred to in this package, is the width of a string in a
7070 monospace font. This is commonly used in terminal user interfaces or text
7171 displays or editors that don't support proportional fonts. A width of 1
72 corresponds to a single character cell. The C function [wcwidth()] and its
72 corresponds to a single character cell. The C function [wcswidth()] and its
7373 implementation in other programming languages is in widespread use for the same
7474 purpose. However, there is no standard for the calculation of such widths, and
75 this package differs from wcwidth() in a number of ways, presumably to generate
75 this package differs from wcswidth() in a number of ways, presumably to generate
7676 more visually pleasing results.
7777
7878 To start, we assume that every code point has a width of 1, with the following
102102 render engine, to which extent it conforms to the Unicode Standard, and its
103103 choice of font.
104104
105 [wcwidth()]: https://man7.org/linux/man-pages/man3/wcwidth.3.html
105 [wcswidth()]: https://man7.org/linux/man-pages/man3/wcswidth.3.html
106106 */
107107 package uniseg
162162 return
163163 }
164164
165 // ReverseString reverses the given string while observing grapheme cluster
166 // boundaries.
167 func ReverseString(s string) string {
168 str := []byte(s)
169 reversed := make([]byte, len(str))
170 state := -1
171 index := len(str)
172 for len(str) > 0 {
173 var cluster []byte
174 cluster, str, _, state = FirstGraphemeCluster(str, state)
175 index -= len(cluster)
176 copy(reversed[index:], cluster)
177 if index <= len(str)/2 {
178 break
179 }
180 }
181 return string(reversed)
182 }
183
165184 // The number of bits the grapheme property must be shifted to make place for
166185 // grapheme states.
167186 const shiftGraphemePropState = 4
335335 }
336336 }
337337
338 // Test the ReverseString function.
339 func TestReverseString(t *testing.T) {
340 for _, testCase := range testCases {
341 var r []rune
342 for index := len(testCase.expected) - 1; index >= 0; index-- {
343 r = append(r, testCase.expected[index]...)
344 }
345 if string(r) != ReverseString(testCase.original) {
346 t.Errorf(`Exepected reverse of %q to be %q, got %q`, testCase.original, string(r), ReverseString(testCase.original))
347 }
348 }
349
350 // Three additional ones, for good measure.
351 if ReverseString("πŸ‡©πŸ‡ͺπŸ³οΈβ€πŸŒˆ") != "πŸ³οΈβ€πŸŒˆπŸ‡©πŸ‡ͺ" {
352 t.Error("Flags weren't reversed correctly")
353 }
354 if ReverseString("πŸ³οΈβ€πŸŒˆ") != "πŸ³οΈβ€πŸŒˆ" {
355 t.Error("Flag wasn't reversed correctly")
356 }
357 if ReverseString("") != "" {
358 t.Error("Empty string wasn't reversed correctly")
359 }
360 }
361
338362 // Run all lists of test cases using the Graphemes function for byte slices.
339363 func TestGraphemesFunctionBytes(t *testing.T) {
340364 allCases := append(testCases, graphemeBreakTestCases...)
00 package uniseg
11
2 import "testing"
2 import (
3 "testing"
4 )
35
46 // widthTestCases is a list of test cases for the calculation of string widths.
57 var widthTestCases = []struct {
326328 {"\U0001f3f3\ufe0f\u200d\U0001f308", 2}, // Rainbow flag
327329 {"\U0001f1e9\U0001f1ea", 2}, // German flag
328330 {"\u0916\u093e", 2}, // ΰ€–ΰ€Ύ (Hindi, "eat")
331 {"\u0915\u0948\u0938\u0947", 2}, // ΰ€•ΰ₯ˆΰ€Έΰ₯‡ (Hindi, "how")
329332 {"\U0001f468\u200d\U0001f469\u200d\U0001f467\u200d\U0001f466", 2}, // Family: Man, Woman, Girl, Boy
330333 {"\u1112\u116f\u11b6", 2}, // α„’α…―α†Ά (Hangul, conjoining Jamo, "h+weo+lh")
331334 {"\ud6ef", 2}, // ν›― (Hangul, precomposed, "h+weo+lh")
427430 }
428431 }
429432 }
433
434 func TestRunesWidth(t *testing.T) {
435 tc := []struct {
436 name string
437 raw string
438 width int
439 }{
440 {"latin ", "long", 4},
441 {"chinese ", "δΈ­ε›½", 4},
442 {"combining", "shangha\u0308\u0308i", 8},
443 {
444 "emoji 1", "🏝",
445 1,
446 },
447 {
448 "emoji 2", "πŸ—»",
449 2,
450 },
451 {
452 "emoji 3", "πŸ–",
453 1,
454 },
455 {
456 "flags", "πŸ‡³πŸ‡±πŸ‡§πŸ‡·i",
457 5,
458 },
459 {
460 "flag 2", "πŸ‡¨πŸ‡³",
461 2,
462 },
463 }
464
465 for _, v := range tc {
466 graphemes := NewGraphemes(v.raw)
467 width := 0
468 var rs []rune
469 for graphemes.Next() {
470 rs = graphemes.Runes()
471 width += StringWidth(string(rs))
472 }
473
474 if v.width != width {
475 t.Logf("%s :\t %q %U\n", v.name, v.raw, rs)
476 t.Errorf("%s:\t %q expect width %d, got %d\n", v.name, v.raw, v.width, width)
477 }
478 }
479 }