Bump github.com/jedib0t/go-pretty/v6 from 6.6.4 to 6.6.5
Bumps [github.com/jedib0t/go-pretty/v6](https://github.com/jedib0t/go-pretty) from 6.6.4 to 6.6.5. - [Release notes](https://github.com/jedib0t/go-pretty/releases) - [Commits](https://github.com/jedib0t/go-pretty/compare/v6.6.4...v6.6.5) --- updated-dependencies: - dependency-name: github.com/jedib0t/go-pretty/v6 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
parent
e69838b678
commit
e96145833c
21 changed files with 8656 additions and 46 deletions
2
go.mod
2
go.mod
|
|
@ -19,7 +19,7 @@ require (
|
||||||
github.com/gorilla/handlers v1.5.2
|
github.com/gorilla/handlers v1.5.2
|
||||||
github.com/gorilla/mux v1.8.1
|
github.com/gorilla/mux v1.8.1
|
||||||
github.com/gorilla/websocket v1.5.4-0.20240702125206-a62d9d2a8413
|
github.com/gorilla/websocket v1.5.4-0.20240702125206-a62d9d2a8413
|
||||||
github.com/jedib0t/go-pretty/v6 v6.6.4
|
github.com/jedib0t/go-pretty/v6 v6.6.5
|
||||||
github.com/juju/clock v1.1.1
|
github.com/juju/clock v1.1.1
|
||||||
github.com/juju/retry v1.0.1
|
github.com/juju/retry v1.0.1
|
||||||
github.com/manifoldco/promptui v0.9.0
|
github.com/manifoldco/promptui v0.9.0
|
||||||
|
|
|
||||||
4
go.sum
4
go.sum
|
|
@ -90,8 +90,8 @@ github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw=
|
||||||
github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
|
github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
|
||||||
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
|
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
|
||||||
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||||
github.com/jedib0t/go-pretty/v6 v6.6.4 h1:B51RjA+Sytv0C0Je7PHGDXZBF2JpS5dZEWWRueBLP6U=
|
github.com/jedib0t/go-pretty/v6 v6.6.5 h1:9PgMJOVBedpgYLI56jQRJYqngxYAAzfEUua+3NgSqAo=
|
||||||
github.com/jedib0t/go-pretty/v6 v6.6.4/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E=
|
github.com/jedib0t/go-pretty/v6 v6.6.5/go.mod h1:Uq/HrbhuFty5WSVNfjpQQe47x16RwVGXIveNGEyGtHs=
|
||||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||||
|
|
|
||||||
8
vendor/github.com/jedib0t/go-pretty/v6/table/render.go
generated
vendored
8
vendor/github.com/jedib0t/go-pretty/v6/table/render.go
generated
vendored
|
|
@ -227,7 +227,7 @@ func (t *Table) renderLine(out *strings.Builder, row rowStr, hint renderHint) {
|
||||||
|
|
||||||
func (t *Table) renderLineMergeOutputs(out *strings.Builder, outLine *strings.Builder) {
|
func (t *Table) renderLineMergeOutputs(out *strings.Builder, outLine *strings.Builder) {
|
||||||
outLineStr := outLine.String()
|
outLineStr := outLine.String()
|
||||||
if text.RuneWidthWithoutEscSequences(outLineStr) > t.style.Size.WidthMax {
|
if text.StringWidthWithoutEscSequences(outLineStr) > t.style.Size.WidthMax {
|
||||||
trimLength := t.style.Size.WidthMax - utf8.RuneCountInString(t.style.Box.UnfinishedRow)
|
trimLength := t.style.Size.WidthMax - utf8.RuneCountInString(t.style.Box.UnfinishedRow)
|
||||||
if trimLength > 0 {
|
if trimLength > 0 {
|
||||||
out.WriteString(text.Trim(outLineStr, trimLength))
|
out.WriteString(text.Trim(outLineStr, trimLength))
|
||||||
|
|
@ -392,15 +392,15 @@ func (t *Table) renderTitle(out *strings.Builder) {
|
||||||
rowLength = wm
|
rowLength = wm
|
||||||
}
|
}
|
||||||
if t.style.Options.DrawBorder {
|
if t.style.Options.DrawBorder {
|
||||||
lenBorder := rowLength - text.RuneWidthWithoutEscSequences(t.style.Box.TopLeft+t.style.Box.TopRight)
|
lenBorder := rowLength - text.StringWidthWithoutEscSequences(t.style.Box.TopLeft+t.style.Box.TopRight)
|
||||||
out.WriteString(colorsBorder.Sprint(t.style.Box.TopLeft))
|
out.WriteString(colorsBorder.Sprint(t.style.Box.TopLeft))
|
||||||
out.WriteString(colorsBorder.Sprint(text.RepeatAndTrim(t.style.Box.MiddleHorizontal, lenBorder)))
|
out.WriteString(colorsBorder.Sprint(text.RepeatAndTrim(t.style.Box.MiddleHorizontal, lenBorder)))
|
||||||
out.WriteString(colorsBorder.Sprint(t.style.Box.TopRight))
|
out.WriteString(colorsBorder.Sprint(t.style.Box.TopRight))
|
||||||
}
|
}
|
||||||
|
|
||||||
lenText := rowLength - text.RuneWidthWithoutEscSequences(t.style.Box.PaddingLeft+t.style.Box.PaddingRight)
|
lenText := rowLength - text.StringWidthWithoutEscSequences(t.style.Box.PaddingLeft+t.style.Box.PaddingRight)
|
||||||
if t.style.Options.DrawBorder {
|
if t.style.Options.DrawBorder {
|
||||||
lenText -= text.RuneWidthWithoutEscSequences(t.style.Box.Left + t.style.Box.Right)
|
lenText -= text.StringWidthWithoutEscSequences(t.style.Box.Left + t.style.Box.Right)
|
||||||
}
|
}
|
||||||
titleText := text.WrapText(t.title, lenText)
|
titleText := text.WrapText(t.title, lenText)
|
||||||
for _, titleLine := range strings.Split(titleText, "\n") {
|
for _, titleLine := range strings.Split(titleText, "\n") {
|
||||||
|
|
|
||||||
16
vendor/github.com/jedib0t/go-pretty/v6/table/render_init.go
generated
vendored
16
vendor/github.com/jedib0t/go-pretty/v6/table/render_init.go
generated
vendored
|
|
@ -78,7 +78,7 @@ func (t *Table) extractMaxColumnLengthsFromRow(row rowStr, mci mergedColumnIndic
|
||||||
|
|
||||||
func (t *Table) extractMaxColumnLengthsFromRowForMergedColumns(colIdx int, mergedColumnLength int, mci mergedColumnIndices) {
|
func (t *Table) extractMaxColumnLengthsFromRowForMergedColumns(colIdx int, mergedColumnLength int, mci mergedColumnIndices) {
|
||||||
numMergedColumns := mci.len(colIdx)
|
numMergedColumns := mci.len(colIdx)
|
||||||
mergedColumnLength -= (numMergedColumns - 1) * text.RuneWidthWithoutEscSequences(t.style.Box.MiddleSeparator)
|
mergedColumnLength -= (numMergedColumns - 1) * text.StringWidthWithoutEscSequences(t.style.Box.MiddleSeparator)
|
||||||
maxLengthSplitAcrossColumns := mergedColumnLength / numMergedColumns
|
maxLengthSplitAcrossColumns := mergedColumnLength / numMergedColumns
|
||||||
if maxLengthSplitAcrossColumns > t.maxColumnLengths[colIdx] {
|
if maxLengthSplitAcrossColumns > t.maxColumnLengths[colIdx] {
|
||||||
t.maxColumnLengths[colIdx] = maxLengthSplitAcrossColumns
|
t.maxColumnLengths[colIdx] = maxLengthSplitAcrossColumns
|
||||||
|
|
@ -177,22 +177,22 @@ func (t *Table) initForRenderHideColumns() {
|
||||||
func (t *Table) initForRenderMaxRowLength() {
|
func (t *Table) initForRenderMaxRowLength() {
|
||||||
t.maxRowLength = 0
|
t.maxRowLength = 0
|
||||||
if t.autoIndex {
|
if t.autoIndex {
|
||||||
t.maxRowLength += text.RuneWidthWithoutEscSequences(t.style.Box.PaddingLeft)
|
t.maxRowLength += text.StringWidthWithoutEscSequences(t.style.Box.PaddingLeft)
|
||||||
t.maxRowLength += len(fmt.Sprint(len(t.rows)))
|
t.maxRowLength += len(fmt.Sprint(len(t.rows)))
|
||||||
t.maxRowLength += text.RuneWidthWithoutEscSequences(t.style.Box.PaddingRight)
|
t.maxRowLength += text.StringWidthWithoutEscSequences(t.style.Box.PaddingRight)
|
||||||
if t.style.Options.SeparateColumns {
|
if t.style.Options.SeparateColumns {
|
||||||
t.maxRowLength += text.RuneWidthWithoutEscSequences(t.style.Box.MiddleSeparator)
|
t.maxRowLength += text.StringWidthWithoutEscSequences(t.style.Box.MiddleSeparator)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if t.style.Options.SeparateColumns {
|
if t.style.Options.SeparateColumns {
|
||||||
t.maxRowLength += text.RuneWidthWithoutEscSequences(t.style.Box.MiddleSeparator) * (t.numColumns - 1)
|
t.maxRowLength += text.StringWidthWithoutEscSequences(t.style.Box.MiddleSeparator) * (t.numColumns - 1)
|
||||||
}
|
}
|
||||||
for _, maxColumnLength := range t.maxColumnLengths {
|
for _, maxColumnLength := range t.maxColumnLengths {
|
||||||
maxColumnLength += text.RuneWidthWithoutEscSequences(t.style.Box.PaddingLeft + t.style.Box.PaddingRight)
|
maxColumnLength += text.StringWidthWithoutEscSequences(t.style.Box.PaddingLeft + t.style.Box.PaddingRight)
|
||||||
t.maxRowLength += maxColumnLength
|
t.maxRowLength += maxColumnLength
|
||||||
}
|
}
|
||||||
if t.style.Options.DrawBorder {
|
if t.style.Options.DrawBorder {
|
||||||
t.maxRowLength += text.RuneWidthWithoutEscSequences(t.style.Box.Left + t.style.Box.Right)
|
t.maxRowLength += text.StringWidthWithoutEscSequences(t.style.Box.Left + t.style.Box.Right)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -282,7 +282,7 @@ func (t *Table) initForRenderRowPainterColors() {
|
||||||
func (t *Table) initForRenderRowSeparator() {
|
func (t *Table) initForRenderRowSeparator() {
|
||||||
t.rowSeparator = make(rowStr, t.numColumns)
|
t.rowSeparator = make(rowStr, t.numColumns)
|
||||||
for colIdx, maxColumnLength := range t.maxColumnLengths {
|
for colIdx, maxColumnLength := range t.maxColumnLengths {
|
||||||
maxColumnLength += text.RuneWidthWithoutEscSequences(t.style.Box.PaddingLeft + t.style.Box.PaddingRight)
|
maxColumnLength += text.StringWidthWithoutEscSequences(t.style.Box.PaddingLeft + t.style.Box.PaddingRight)
|
||||||
t.rowSeparator[colIdx] = text.RepeatAndTrim(t.style.Box.MiddleHorizontal, maxColumnLength)
|
t.rowSeparator[colIdx] = text.RepeatAndTrim(t.style.Box.MiddleHorizontal, maxColumnLength)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
4
vendor/github.com/jedib0t/go-pretty/v6/table/table.go
generated
vendored
4
vendor/github.com/jedib0t/go-pretty/v6/table/table.go
generated
vendored
|
|
@ -603,9 +603,9 @@ func (t *Table) getFormat(hint renderHint) text.Format {
|
||||||
|
|
||||||
func (t *Table) getMaxColumnLengthForMerging(colIdx int) int {
|
func (t *Table) getMaxColumnLengthForMerging(colIdx int) int {
|
||||||
maxColumnLength := t.maxColumnLengths[colIdx]
|
maxColumnLength := t.maxColumnLengths[colIdx]
|
||||||
maxColumnLength += text.RuneWidthWithoutEscSequences(t.style.Box.PaddingRight + t.style.Box.PaddingLeft)
|
maxColumnLength += text.StringWidthWithoutEscSequences(t.style.Box.PaddingRight + t.style.Box.PaddingLeft)
|
||||||
if t.style.Options.SeparateColumns {
|
if t.style.Options.SeparateColumns {
|
||||||
maxColumnLength += text.RuneWidthWithoutEscSequences(t.style.Box.EmptySeparator)
|
maxColumnLength += text.StringWidthWithoutEscSequences(t.style.Box.EmptySeparator)
|
||||||
}
|
}
|
||||||
return maxColumnLength
|
return maxColumnLength
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2
vendor/github.com/jedib0t/go-pretty/v6/text/align.go
generated
vendored
2
vendor/github.com/jedib0t/go-pretty/v6/text/align.go
generated
vendored
|
|
@ -40,7 +40,7 @@ func (a Align) Apply(text string, maxLength int) string {
|
||||||
|
|
||||||
text = aComputed.trimString(text)
|
text = aComputed.trimString(text)
|
||||||
sLen := utf8.RuneCountInString(text)
|
sLen := utf8.RuneCountInString(text)
|
||||||
sLenWoE := RuneWidthWithoutEscSequences(text)
|
sLenWoE := StringWidthWithoutEscSequences(text)
|
||||||
numEscChars := sLen - sLenWoE
|
numEscChars := sLen - sLenWoE
|
||||||
|
|
||||||
// now, align the text
|
// now, align the text
|
||||||
|
|
|
||||||
2
vendor/github.com/jedib0t/go-pretty/v6/text/ansi.go
generated
vendored
2
vendor/github.com/jedib0t/go-pretty/v6/text/ansi.go
generated
vendored
|
|
@ -39,7 +39,7 @@ func Escape(str string, escapeSeq string) string {
|
||||||
// StripEscape("\x1b[91mNymeria \x1b[94mGhost\x1b[0m\x1b[91m Lady\x1b[0m") == "Nymeria Ghost Lady"
|
// StripEscape("\x1b[91mNymeria \x1b[94mGhost\x1b[0m\x1b[91m Lady\x1b[0m") == "Nymeria Ghost Lady"
|
||||||
func StripEscape(str string) string {
|
func StripEscape(str string) string {
|
||||||
var out strings.Builder
|
var out strings.Builder
|
||||||
out.Grow(RuneWidthWithoutEscSequences(str))
|
out.Grow(StringWidthWithoutEscSequences(str))
|
||||||
|
|
||||||
isEscSeq := false
|
isEscSeq := false
|
||||||
for _, sChr := range str {
|
for _, sChr := range str {
|
||||||
|
|
|
||||||
9
vendor/github.com/jedib0t/go-pretty/v6/text/direction.go
generated
vendored
9
vendor/github.com/jedib0t/go-pretty/v6/text/direction.go
generated
vendored
|
|
@ -11,14 +11,19 @@ const (
|
||||||
RightToLeft
|
RightToLeft
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
RuneL2R = '\u202a'
|
||||||
|
RuneR2L = '\u202b'
|
||||||
|
)
|
||||||
|
|
||||||
// Modifier returns a character to force the given direction for the text that
|
// Modifier returns a character to force the given direction for the text that
|
||||||
// follows the modifier.
|
// follows the modifier.
|
||||||
func (d Direction) Modifier() string {
|
func (d Direction) Modifier() string {
|
||||||
switch d {
|
switch d {
|
||||||
case LeftToRight:
|
case LeftToRight:
|
||||||
return "\u202a"
|
return string(RuneL2R)
|
||||||
case RightToLeft:
|
case RightToLeft:
|
||||||
return "\u202b"
|
return string(RuneR2L)
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
|
||||||
84
vendor/github.com/jedib0t/go-pretty/v6/text/string.go
generated
vendored
84
vendor/github.com/jedib0t/go-pretty/v6/text/string.go
generated
vendored
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"github.com/mattn/go-runewidth"
|
"github.com/mattn/go-runewidth"
|
||||||
|
"golang.org/x/text/width"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RuneWidth stuff
|
// RuneWidth stuff
|
||||||
|
|
@ -24,7 +25,7 @@ func InsertEveryN(str string, runeToInsert rune, n int) string {
|
||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
|
|
||||||
sLen := RuneWidthWithoutEscSequences(str)
|
sLen := StringWidthWithoutEscSequences(str)
|
||||||
var out strings.Builder
|
var out strings.Builder
|
||||||
out.Grow(sLen + (sLen / n))
|
out.Grow(sLen + (sLen / n))
|
||||||
outLen, esp := 0, escSeqParser{}
|
outLen, esp := 0, escSeqParser{}
|
||||||
|
|
@ -102,7 +103,7 @@ func OverrideRuneWidthEastAsianWidth(val bool) {
|
||||||
// Pad("Ghost", 7, ' ') == "Ghost "
|
// Pad("Ghost", 7, ' ') == "Ghost "
|
||||||
// Pad("Ghost", 10, '.') == "Ghost....."
|
// Pad("Ghost", 10, '.') == "Ghost....."
|
||||||
func Pad(str string, maxLen int, paddingChar rune) string {
|
func Pad(str string, maxLen int, paddingChar rune) string {
|
||||||
strLen := RuneWidthWithoutEscSequences(str)
|
strLen := StringWidthWithoutEscSequences(str)
|
||||||
if strLen < maxLen {
|
if strLen < maxLen {
|
||||||
str += strings.Repeat(string(paddingChar), maxLen-strLen)
|
str += strings.Repeat(string(paddingChar), maxLen-strLen)
|
||||||
}
|
}
|
||||||
|
|
@ -180,7 +181,7 @@ func RepeatAndTrim(str string, maxRunes int) string {
|
||||||
//
|
//
|
||||||
// Deprecated: in favor of RuneWidthWithoutEscSequences
|
// Deprecated: in favor of RuneWidthWithoutEscSequences
|
||||||
func RuneCount(str string) int {
|
func RuneCount(str string) int {
|
||||||
return RuneWidthWithoutEscSequences(str)
|
return StringWidthWithoutEscSequences(str)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RuneWidth returns the mostly accurate character-width of the rune. This is
|
// RuneWidth returns the mostly accurate character-width of the rune. This is
|
||||||
|
|
@ -203,19 +204,10 @@ func RuneWidth(r rune) int {
|
||||||
// RuneWidthWithoutEscSequences("Ghost") == 5
|
// RuneWidthWithoutEscSequences("Ghost") == 5
|
||||||
// RuneWidthWithoutEscSequences("\x1b[33mGhost\x1b[0m") == 5
|
// RuneWidthWithoutEscSequences("\x1b[33mGhost\x1b[0m") == 5
|
||||||
// RuneWidthWithoutEscSequences("\x1b[33mGhost\x1b[0") == 5
|
// RuneWidthWithoutEscSequences("\x1b[33mGhost\x1b[0") == 5
|
||||||
|
//
|
||||||
|
// deprecated: use StringWidthWithoutEscSequences instead
|
||||||
func RuneWidthWithoutEscSequences(str string) int {
|
func RuneWidthWithoutEscSequences(str string) int {
|
||||||
count, esp := 0, escSeqParser{}
|
return StringWidthWithoutEscSequences(str)
|
||||||
for _, c := range str {
|
|
||||||
if esp.InSequence() {
|
|
||||||
esp.Consume(c)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
esp.Consume(c)
|
|
||||||
if !esp.InSequence() {
|
|
||||||
count += RuneWidth(c)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Snip returns the given string with a fixed length. For ex.:
|
// Snip returns the given string with a fixed length. For ex.:
|
||||||
|
|
@ -228,15 +220,48 @@ func RuneWidthWithoutEscSequences(str string) int {
|
||||||
// Snip("\x1b[33mGhost\x1b[0m", 7, "~") == "\x1b[33mGhost\x1b[0m "
|
// Snip("\x1b[33mGhost\x1b[0m", 7, "~") == "\x1b[33mGhost\x1b[0m "
|
||||||
func Snip(str string, length int, snipIndicator string) string {
|
func Snip(str string, length int, snipIndicator string) string {
|
||||||
if length > 0 {
|
if length > 0 {
|
||||||
lenStr := RuneWidthWithoutEscSequences(str)
|
lenStr := StringWidthWithoutEscSequences(str)
|
||||||
if lenStr > length {
|
if lenStr > length {
|
||||||
lenStrFinal := length - RuneWidthWithoutEscSequences(snipIndicator)
|
lenStrFinal := length - StringWidthWithoutEscSequences(snipIndicator)
|
||||||
return Trim(str, lenStrFinal) + snipIndicator
|
return Trim(str, lenStrFinal) + snipIndicator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StringWidth is similar to RuneWidth, except it works on a string. For
|
||||||
|
// ex.:
|
||||||
|
//
|
||||||
|
// StringWidth("Ghost 生命"): 10
|
||||||
|
// StringWidth("\x1b[33mGhost 生命\x1b[0m"): 19
|
||||||
|
func StringWidth(str string) int {
|
||||||
|
return rwCondition.StringWidth(str)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringWidthWithoutEscSequences is similar to RuneWidth, except for the fact
|
||||||
|
// that it ignores escape sequences while counting. For ex.:
|
||||||
|
//
|
||||||
|
// StringWidthWithoutEscSequences("") == 0
|
||||||
|
// StringWidthWithoutEscSequences("Ghost") == 5
|
||||||
|
// StringWidthWithoutEscSequences("\x1b[33mGhost\x1b[0m") == 5
|
||||||
|
// StringWidthWithoutEscSequences("\x1b[33mGhost\x1b[0") == 5
|
||||||
|
// StringWidthWithoutEscSequences("Ghost 生命"): 10
|
||||||
|
// StringWidthWithoutEscSequences("\x1b[33mGhost 生命\x1b[0m"): 10
|
||||||
|
func StringWidthWithoutEscSequences(str string) int {
|
||||||
|
count, esp := 0, escSeqParser{}
|
||||||
|
for _, c := range str {
|
||||||
|
if esp.InSequence() {
|
||||||
|
esp.Consume(c)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
esp.Consume(c)
|
||||||
|
if !esp.InSequence() {
|
||||||
|
count += RuneWidth(c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
|
||||||
// Trim trims a string to the given length while ignoring escape sequences. For
|
// Trim trims a string to the given length while ignoring escape sequences. For
|
||||||
// ex.:
|
// ex.:
|
||||||
//
|
//
|
||||||
|
|
@ -272,3 +297,28 @@ func Trim(str string, maxLen int) string {
|
||||||
}
|
}
|
||||||
return out.String()
|
return out.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Widen is like width.Widen.String() but ignores escape sequences. For ex:
|
||||||
|
//
|
||||||
|
// Widen("Ghost 生命"): "Ghost\u3000生命"
|
||||||
|
// Widen("\x1b[33mGhost 生命\x1b[0m"): "\x1b[33mGhost\u3000生命\x1b[0m"
|
||||||
|
func Widen(str string) string {
|
||||||
|
sb := strings.Builder{}
|
||||||
|
sb.Grow(len(str))
|
||||||
|
|
||||||
|
esp := escSeqParser{}
|
||||||
|
for _, c := range str {
|
||||||
|
if esp.InSequence() {
|
||||||
|
sb.WriteRune(c)
|
||||||
|
esp.Consume(c)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
esp.Consume(c)
|
||||||
|
if !esp.InSequence() {
|
||||||
|
sb.WriteString(width.Widen.String(string(c)))
|
||||||
|
} else {
|
||||||
|
sb.WriteRune(c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb.String()
|
||||||
|
}
|
||||||
|
|
|
||||||
13
vendor/github.com/jedib0t/go-pretty/v6/text/wrap.go
generated
vendored
13
vendor/github.com/jedib0t/go-pretty/v6/text/wrap.go
generated
vendored
|
|
@ -2,7 +2,6 @@ package text
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
"unicode/utf8"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// WrapHard wraps a string to the given length using a newline. Handles strings
|
// WrapHard wraps a string to the given length using a newline. Handles strings
|
||||||
|
|
@ -15,7 +14,7 @@ func WrapHard(str string, wrapLen int) string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
str = strings.Replace(str, "\t", " ", -1)
|
str = strings.Replace(str, "\t", " ", -1)
|
||||||
sLen := utf8.RuneCountInString(str)
|
sLen := StringWidthWithoutEscSequences(str)
|
||||||
if sLen <= wrapLen {
|
if sLen <= wrapLen {
|
||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
|
|
@ -43,7 +42,7 @@ func WrapSoft(str string, wrapLen int) string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
str = strings.Replace(str, "\t", " ", -1)
|
str = strings.Replace(str, "\t", " ", -1)
|
||||||
sLen := utf8.RuneCountInString(str)
|
sLen := StringWidthWithoutEscSequences(str)
|
||||||
if sLen <= wrapLen {
|
if sLen <= wrapLen {
|
||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
|
|
@ -70,7 +69,7 @@ func WrapText(str string, wrapLen int) string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
str = strings.Replace(str, "\t", " ", -1)
|
str = strings.Replace(str, "\t", " ", -1)
|
||||||
sLen := utf8.RuneCountInString(str)
|
sLen := StringWidthWithoutEscSequences(str)
|
||||||
if sLen <= wrapLen {
|
if sLen <= wrapLen {
|
||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
|
|
@ -111,7 +110,7 @@ func appendChar(char rune, wrapLen int, lineLen *int, inEscSeq bool, lastSeenEsc
|
||||||
|
|
||||||
// increment the line index if not in the middle of an escape sequence
|
// increment the line index if not in the middle of an escape sequence
|
||||||
if !inEscSeq {
|
if !inEscSeq {
|
||||||
*lineLen++
|
*lineLen += RuneWidth(char)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -170,7 +169,7 @@ func wrapHard(paragraph string, wrapLen int, out *strings.Builder) {
|
||||||
lineLen++
|
lineLen++
|
||||||
}
|
}
|
||||||
|
|
||||||
wordLen := RuneWidthWithoutEscSequences(word)
|
wordLen := StringWidthWithoutEscSequences(word)
|
||||||
if lineLen+wordLen <= wrapLen { // word fits within the line
|
if lineLen+wordLen <= wrapLen { // word fits within the line
|
||||||
out.WriteString(word)
|
out.WriteString(word)
|
||||||
lineLen += wordLen
|
lineLen += wordLen
|
||||||
|
|
@ -196,7 +195,7 @@ func wrapSoft(paragraph string, wrapLen int, out *strings.Builder) {
|
||||||
}
|
}
|
||||||
|
|
||||||
spacing, spacingLen := wrapSoftSpacing(lineLen)
|
spacing, spacingLen := wrapSoftSpacing(lineLen)
|
||||||
wordLen := RuneWidthWithoutEscSequences(word)
|
wordLen := StringWidthWithoutEscSequences(word)
|
||||||
if lineLen+spacingLen+wordLen <= wrapLen { // word fits within the line
|
if lineLen+spacingLen+wordLen <= wrapLen { // word fits within the line
|
||||||
out.WriteString(spacing)
|
out.WriteString(spacing)
|
||||||
out.WriteString(word)
|
out.WriteString(word)
|
||||||
|
|
|
||||||
28
vendor/golang.org/x/text/width/kind_string.go
generated
vendored
Normal file
28
vendor/golang.org/x/text/width/kind_string.go
generated
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
// Code generated by "stringer -type=Kind"; DO NOT EDIT.
|
||||||
|
|
||||||
|
package width
|
||||||
|
|
||||||
|
import "strconv"
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[Neutral-0]
|
||||||
|
_ = x[EastAsianAmbiguous-1]
|
||||||
|
_ = x[EastAsianWide-2]
|
||||||
|
_ = x[EastAsianNarrow-3]
|
||||||
|
_ = x[EastAsianFullwidth-4]
|
||||||
|
_ = x[EastAsianHalfwidth-5]
|
||||||
|
}
|
||||||
|
|
||||||
|
const _Kind_name = "NeutralEastAsianAmbiguousEastAsianWideEastAsianNarrowEastAsianFullwidthEastAsianHalfwidth"
|
||||||
|
|
||||||
|
var _Kind_index = [...]uint8{0, 7, 25, 38, 53, 71, 89}
|
||||||
|
|
||||||
|
func (i Kind) String() string {
|
||||||
|
if i < 0 || i >= Kind(len(_Kind_index)-1) {
|
||||||
|
return "Kind(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||||
|
}
|
||||||
|
return _Kind_name[_Kind_index[i]:_Kind_index[i+1]]
|
||||||
|
}
|
||||||
1328
vendor/golang.org/x/text/width/tables10.0.0.go
generated
vendored
Normal file
1328
vendor/golang.org/x/text/width/tables10.0.0.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
1340
vendor/golang.org/x/text/width/tables11.0.0.go
generated
vendored
Normal file
1340
vendor/golang.org/x/text/width/tables11.0.0.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
1360
vendor/golang.org/x/text/width/tables12.0.0.go
generated
vendored
Normal file
1360
vendor/golang.org/x/text/width/tables12.0.0.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
1361
vendor/golang.org/x/text/width/tables13.0.0.go
generated
vendored
Normal file
1361
vendor/golang.org/x/text/width/tables13.0.0.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
1367
vendor/golang.org/x/text/width/tables15.0.0.go
generated
vendored
Normal file
1367
vendor/golang.org/x/text/width/tables15.0.0.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
1296
vendor/golang.org/x/text/width/tables9.0.0.go
generated
vendored
Normal file
1296
vendor/golang.org/x/text/width/tables9.0.0.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
239
vendor/golang.org/x/text/width/transform.go
generated
vendored
Normal file
239
vendor/golang.org/x/text/width/transform.go
generated
vendored
Normal file
|
|
@ -0,0 +1,239 @@
|
||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package width
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unicode/utf8"
|
||||||
|
|
||||||
|
"golang.org/x/text/transform"
|
||||||
|
)
|
||||||
|
|
||||||
|
type foldTransform struct {
|
||||||
|
transform.NopResetter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (foldTransform) Span(src []byte, atEOF bool) (n int, err error) {
|
||||||
|
for n < len(src) {
|
||||||
|
if src[n] < utf8.RuneSelf {
|
||||||
|
// ASCII fast path.
|
||||||
|
for n++; n < len(src) && src[n] < utf8.RuneSelf; n++ {
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
v, size := trie.lookup(src[n:])
|
||||||
|
if size == 0 { // incomplete UTF-8 encoding
|
||||||
|
if !atEOF {
|
||||||
|
err = transform.ErrShortSrc
|
||||||
|
} else {
|
||||||
|
n = len(src)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if elem(v)&tagNeedsFold != 0 {
|
||||||
|
err = transform.ErrEndOfSpan
|
||||||
|
break
|
||||||
|
}
|
||||||
|
n += size
|
||||||
|
}
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (foldTransform) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
||||||
|
for nSrc < len(src) {
|
||||||
|
if src[nSrc] < utf8.RuneSelf {
|
||||||
|
// ASCII fast path.
|
||||||
|
start, end := nSrc, len(src)
|
||||||
|
if d := len(dst) - nDst; d < end-start {
|
||||||
|
end = nSrc + d
|
||||||
|
}
|
||||||
|
for nSrc++; nSrc < end && src[nSrc] < utf8.RuneSelf; nSrc++ {
|
||||||
|
}
|
||||||
|
n := copy(dst[nDst:], src[start:nSrc])
|
||||||
|
if nDst += n; nDst == len(dst) {
|
||||||
|
nSrc = start + n
|
||||||
|
if nSrc == len(src) {
|
||||||
|
return nDst, nSrc, nil
|
||||||
|
}
|
||||||
|
if src[nSrc] < utf8.RuneSelf {
|
||||||
|
return nDst, nSrc, transform.ErrShortDst
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
v, size := trie.lookup(src[nSrc:])
|
||||||
|
if size == 0 { // incomplete UTF-8 encoding
|
||||||
|
if !atEOF {
|
||||||
|
return nDst, nSrc, transform.ErrShortSrc
|
||||||
|
}
|
||||||
|
size = 1 // gobble 1 byte
|
||||||
|
}
|
||||||
|
if elem(v)&tagNeedsFold == 0 {
|
||||||
|
if size != copy(dst[nDst:], src[nSrc:nSrc+size]) {
|
||||||
|
return nDst, nSrc, transform.ErrShortDst
|
||||||
|
}
|
||||||
|
nDst += size
|
||||||
|
} else {
|
||||||
|
data := inverseData[byte(v)]
|
||||||
|
if len(dst)-nDst < int(data[0]) {
|
||||||
|
return nDst, nSrc, transform.ErrShortDst
|
||||||
|
}
|
||||||
|
i := 1
|
||||||
|
for end := int(data[0]); i < end; i++ {
|
||||||
|
dst[nDst] = data[i]
|
||||||
|
nDst++
|
||||||
|
}
|
||||||
|
dst[nDst] = data[i] ^ src[nSrc+size-1]
|
||||||
|
nDst++
|
||||||
|
}
|
||||||
|
nSrc += size
|
||||||
|
}
|
||||||
|
return nDst, nSrc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type narrowTransform struct {
|
||||||
|
transform.NopResetter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (narrowTransform) Span(src []byte, atEOF bool) (n int, err error) {
|
||||||
|
for n < len(src) {
|
||||||
|
if src[n] < utf8.RuneSelf {
|
||||||
|
// ASCII fast path.
|
||||||
|
for n++; n < len(src) && src[n] < utf8.RuneSelf; n++ {
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
v, size := trie.lookup(src[n:])
|
||||||
|
if size == 0 { // incomplete UTF-8 encoding
|
||||||
|
if !atEOF {
|
||||||
|
err = transform.ErrShortSrc
|
||||||
|
} else {
|
||||||
|
n = len(src)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if k := elem(v).kind(); byte(v) == 0 || k != EastAsianFullwidth && k != EastAsianWide && k != EastAsianAmbiguous {
|
||||||
|
} else {
|
||||||
|
err = transform.ErrEndOfSpan
|
||||||
|
break
|
||||||
|
}
|
||||||
|
n += size
|
||||||
|
}
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (narrowTransform) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
||||||
|
for nSrc < len(src) {
|
||||||
|
if src[nSrc] < utf8.RuneSelf {
|
||||||
|
// ASCII fast path.
|
||||||
|
start, end := nSrc, len(src)
|
||||||
|
if d := len(dst) - nDst; d < end-start {
|
||||||
|
end = nSrc + d
|
||||||
|
}
|
||||||
|
for nSrc++; nSrc < end && src[nSrc] < utf8.RuneSelf; nSrc++ {
|
||||||
|
}
|
||||||
|
n := copy(dst[nDst:], src[start:nSrc])
|
||||||
|
if nDst += n; nDst == len(dst) {
|
||||||
|
nSrc = start + n
|
||||||
|
if nSrc == len(src) {
|
||||||
|
return nDst, nSrc, nil
|
||||||
|
}
|
||||||
|
if src[nSrc] < utf8.RuneSelf {
|
||||||
|
return nDst, nSrc, transform.ErrShortDst
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
v, size := trie.lookup(src[nSrc:])
|
||||||
|
if size == 0 { // incomplete UTF-8 encoding
|
||||||
|
if !atEOF {
|
||||||
|
return nDst, nSrc, transform.ErrShortSrc
|
||||||
|
}
|
||||||
|
size = 1 // gobble 1 byte
|
||||||
|
}
|
||||||
|
if k := elem(v).kind(); byte(v) == 0 || k != EastAsianFullwidth && k != EastAsianWide && k != EastAsianAmbiguous {
|
||||||
|
if size != copy(dst[nDst:], src[nSrc:nSrc+size]) {
|
||||||
|
return nDst, nSrc, transform.ErrShortDst
|
||||||
|
}
|
||||||
|
nDst += size
|
||||||
|
} else {
|
||||||
|
data := inverseData[byte(v)]
|
||||||
|
if len(dst)-nDst < int(data[0]) {
|
||||||
|
return nDst, nSrc, transform.ErrShortDst
|
||||||
|
}
|
||||||
|
i := 1
|
||||||
|
for end := int(data[0]); i < end; i++ {
|
||||||
|
dst[nDst] = data[i]
|
||||||
|
nDst++
|
||||||
|
}
|
||||||
|
dst[nDst] = data[i] ^ src[nSrc+size-1]
|
||||||
|
nDst++
|
||||||
|
}
|
||||||
|
nSrc += size
|
||||||
|
}
|
||||||
|
return nDst, nSrc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type wideTransform struct {
|
||||||
|
transform.NopResetter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wideTransform) Span(src []byte, atEOF bool) (n int, err error) {
|
||||||
|
for n < len(src) {
|
||||||
|
// TODO: Consider ASCII fast path. Special-casing ASCII handling can
|
||||||
|
// reduce the ns/op of BenchmarkWideASCII by about 30%. This is probably
|
||||||
|
// not enough to warrant the extra code and complexity.
|
||||||
|
v, size := trie.lookup(src[n:])
|
||||||
|
if size == 0 { // incomplete UTF-8 encoding
|
||||||
|
if !atEOF {
|
||||||
|
err = transform.ErrShortSrc
|
||||||
|
} else {
|
||||||
|
n = len(src)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if k := elem(v).kind(); byte(v) == 0 || k != EastAsianHalfwidth && k != EastAsianNarrow {
|
||||||
|
} else {
|
||||||
|
err = transform.ErrEndOfSpan
|
||||||
|
break
|
||||||
|
}
|
||||||
|
n += size
|
||||||
|
}
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wideTransform) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
||||||
|
for nSrc < len(src) {
|
||||||
|
// TODO: Consider ASCII fast path. Special-casing ASCII handling can
|
||||||
|
// reduce the ns/op of BenchmarkWideASCII by about 30%. This is probably
|
||||||
|
// not enough to warrant the extra code and complexity.
|
||||||
|
v, size := trie.lookup(src[nSrc:])
|
||||||
|
if size == 0 { // incomplete UTF-8 encoding
|
||||||
|
if !atEOF {
|
||||||
|
return nDst, nSrc, transform.ErrShortSrc
|
||||||
|
}
|
||||||
|
size = 1 // gobble 1 byte
|
||||||
|
}
|
||||||
|
if k := elem(v).kind(); byte(v) == 0 || k != EastAsianHalfwidth && k != EastAsianNarrow {
|
||||||
|
if size != copy(dst[nDst:], src[nSrc:nSrc+size]) {
|
||||||
|
return nDst, nSrc, transform.ErrShortDst
|
||||||
|
}
|
||||||
|
nDst += size
|
||||||
|
} else {
|
||||||
|
data := inverseData[byte(v)]
|
||||||
|
if len(dst)-nDst < int(data[0]) {
|
||||||
|
return nDst, nSrc, transform.ErrShortDst
|
||||||
|
}
|
||||||
|
i := 1
|
||||||
|
for end := int(data[0]); i < end; i++ {
|
||||||
|
dst[nDst] = data[i]
|
||||||
|
nDst++
|
||||||
|
}
|
||||||
|
dst[nDst] = data[i] ^ src[nSrc+size-1]
|
||||||
|
nDst++
|
||||||
|
}
|
||||||
|
nSrc += size
|
||||||
|
}
|
||||||
|
return nDst, nSrc, nil
|
||||||
|
}
|
||||||
30
vendor/golang.org/x/text/width/trieval.go
generated
vendored
Normal file
30
vendor/golang.org/x/text/width/trieval.go
generated
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||||
|
|
||||||
|
package width
|
||||||
|
|
||||||
|
// elem is an entry of the width trie. The high byte is used to encode the type
|
||||||
|
// of the rune. The low byte is used to store the index to a mapping entry in
|
||||||
|
// the inverseData array.
|
||||||
|
type elem uint16
|
||||||
|
|
||||||
|
const (
|
||||||
|
tagNeutral elem = iota << typeShift
|
||||||
|
tagAmbiguous
|
||||||
|
tagWide
|
||||||
|
tagNarrow
|
||||||
|
tagFullwidth
|
||||||
|
tagHalfwidth
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
numTypeBits = 3
|
||||||
|
typeShift = 16 - numTypeBits
|
||||||
|
|
||||||
|
// tagNeedsFold is true for all fullwidth and halfwidth runes except for
|
||||||
|
// the Won sign U+20A9.
|
||||||
|
tagNeedsFold = 0x1000
|
||||||
|
|
||||||
|
// The Korean Won sign is halfwidth, but SHOULD NOT be mapped to a wide
|
||||||
|
// variant.
|
||||||
|
wonSign rune = 0x20A9
|
||||||
|
)
|
||||||
206
vendor/golang.org/x/text/width/width.go
generated
vendored
Normal file
206
vendor/golang.org/x/text/width/width.go
generated
vendored
Normal file
|
|
@ -0,0 +1,206 @@
|
||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:generate stringer -type=Kind
|
||||||
|
//go:generate go run gen.go gen_common.go gen_trieval.go
|
||||||
|
|
||||||
|
// Package width provides functionality for handling different widths in text.
|
||||||
|
//
|
||||||
|
// Wide characters behave like ideographs; they tend to allow line breaks after
|
||||||
|
// each character and remain upright in vertical text layout. Narrow characters
|
||||||
|
// are kept together in words or runs that are rotated sideways in vertical text
|
||||||
|
// layout.
|
||||||
|
//
|
||||||
|
// For more information, see https://unicode.org/reports/tr11/.
|
||||||
|
package width // import "golang.org/x/text/width"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unicode/utf8"
|
||||||
|
|
||||||
|
"golang.org/x/text/transform"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// 1) Reduce table size by compressing blocks.
|
||||||
|
// 2) API proposition for computing display length
|
||||||
|
// (approximation, fixed pitch only).
|
||||||
|
// 3) Implement display length.
|
||||||
|
|
||||||
|
// Kind indicates the type of width property as defined in https://unicode.org/reports/tr11/.
|
||||||
|
type Kind int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Neutral characters do not occur in legacy East Asian character sets.
|
||||||
|
Neutral Kind = iota
|
||||||
|
|
||||||
|
// EastAsianAmbiguous characters that can be sometimes wide and sometimes
|
||||||
|
// narrow and require additional information not contained in the character
|
||||||
|
// code to further resolve their width.
|
||||||
|
EastAsianAmbiguous
|
||||||
|
|
||||||
|
// EastAsianWide characters are wide in its usual form. They occur only in
|
||||||
|
// the context of East Asian typography. These runes may have explicit
|
||||||
|
// halfwidth counterparts.
|
||||||
|
EastAsianWide
|
||||||
|
|
||||||
|
// EastAsianNarrow characters are narrow in its usual form. They often have
|
||||||
|
// fullwidth counterparts.
|
||||||
|
EastAsianNarrow
|
||||||
|
|
||||||
|
// Note: there exist Narrow runes that do not have fullwidth or wide
|
||||||
|
// counterparts, despite what the definition says (e.g. U+27E6).
|
||||||
|
|
||||||
|
// EastAsianFullwidth characters have a compatibility decompositions of type
|
||||||
|
// wide that map to a narrow counterpart.
|
||||||
|
EastAsianFullwidth
|
||||||
|
|
||||||
|
// EastAsianHalfwidth characters have a compatibility decomposition of type
|
||||||
|
// narrow that map to a wide or ambiguous counterpart, plus U+20A9 ₩ WON
|
||||||
|
// SIGN.
|
||||||
|
EastAsianHalfwidth
|
||||||
|
|
||||||
|
// Note: there exist runes that have a halfwidth counterparts but that are
|
||||||
|
// classified as Ambiguous, rather than wide (e.g. U+2190).
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO: the generated tries need to return size 1 for invalid runes for the
|
||||||
|
// width to be computed correctly (each byte should render width 1)
|
||||||
|
|
||||||
|
var trie = newWidthTrie(0)
|
||||||
|
|
||||||
|
// Lookup reports the Properties of the first rune in b and the number of bytes
|
||||||
|
// of its UTF-8 encoding.
|
||||||
|
func Lookup(b []byte) (p Properties, size int) {
|
||||||
|
v, sz := trie.lookup(b)
|
||||||
|
return Properties{elem(v), b[sz-1]}, sz
|
||||||
|
}
|
||||||
|
|
||||||
|
// LookupString reports the Properties of the first rune in s and the number of
|
||||||
|
// bytes of its UTF-8 encoding.
|
||||||
|
func LookupString(s string) (p Properties, size int) {
|
||||||
|
v, sz := trie.lookupString(s)
|
||||||
|
return Properties{elem(v), s[sz-1]}, sz
|
||||||
|
}
|
||||||
|
|
||||||
|
// LookupRune reports the Properties of rune r.
|
||||||
|
func LookupRune(r rune) Properties {
|
||||||
|
var buf [4]byte
|
||||||
|
n := utf8.EncodeRune(buf[:], r)
|
||||||
|
v, _ := trie.lookup(buf[:n])
|
||||||
|
last := byte(r)
|
||||||
|
if r >= utf8.RuneSelf {
|
||||||
|
last = 0x80 + byte(r&0x3f)
|
||||||
|
}
|
||||||
|
return Properties{elem(v), last}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Properties provides access to width properties of a rune.
|
||||||
|
type Properties struct {
|
||||||
|
elem elem
|
||||||
|
last byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e elem) kind() Kind {
|
||||||
|
return Kind(e >> typeShift)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kind returns the Kind of a rune as defined in Unicode TR #11.
|
||||||
|
// See https://unicode.org/reports/tr11/ for more details.
|
||||||
|
func (p Properties) Kind() Kind {
|
||||||
|
return p.elem.kind()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Folded returns the folded variant of a rune or 0 if the rune is canonical.
|
||||||
|
func (p Properties) Folded() rune {
|
||||||
|
if p.elem&tagNeedsFold != 0 {
|
||||||
|
buf := inverseData[byte(p.elem)]
|
||||||
|
buf[buf[0]] ^= p.last
|
||||||
|
r, _ := utf8.DecodeRune(buf[1 : 1+buf[0]])
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Narrow returns the narrow variant of a rune or 0 if the rune is already
|
||||||
|
// narrow or doesn't have a narrow variant.
|
||||||
|
func (p Properties) Narrow() rune {
|
||||||
|
if k := p.elem.kind(); byte(p.elem) != 0 && (k == EastAsianFullwidth || k == EastAsianWide || k == EastAsianAmbiguous) {
|
||||||
|
buf := inverseData[byte(p.elem)]
|
||||||
|
buf[buf[0]] ^= p.last
|
||||||
|
r, _ := utf8.DecodeRune(buf[1 : 1+buf[0]])
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wide returns the wide variant of a rune or 0 if the rune is already
|
||||||
|
// wide or doesn't have a wide variant.
|
||||||
|
func (p Properties) Wide() rune {
|
||||||
|
if k := p.elem.kind(); byte(p.elem) != 0 && (k == EastAsianHalfwidth || k == EastAsianNarrow) {
|
||||||
|
buf := inverseData[byte(p.elem)]
|
||||||
|
buf[buf[0]] ^= p.last
|
||||||
|
r, _ := utf8.DecodeRune(buf[1 : 1+buf[0]])
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO for Properties:
|
||||||
|
// - Add Fullwidth/Halfwidth or Inverted methods for computing variants
|
||||||
|
// mapping.
|
||||||
|
// - Add width information (including information on non-spacing runes).
|
||||||
|
|
||||||
|
// Transformer implements the transform.Transformer interface.
|
||||||
|
type Transformer struct {
|
||||||
|
t transform.SpanningTransformer
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset implements the transform.Transformer interface.
|
||||||
|
func (t Transformer) Reset() { t.t.Reset() }
|
||||||
|
|
||||||
|
// Transform implements the transform.Transformer interface.
|
||||||
|
func (t Transformer) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
||||||
|
return t.t.Transform(dst, src, atEOF)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Span implements the transform.SpanningTransformer interface.
|
||||||
|
func (t Transformer) Span(src []byte, atEOF bool) (n int, err error) {
|
||||||
|
return t.t.Span(src, atEOF)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bytes returns a new byte slice with the result of applying t to b.
|
||||||
|
func (t Transformer) Bytes(b []byte) []byte {
|
||||||
|
b, _, _ = transform.Bytes(t, b)
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns a string with the result of applying t to s.
|
||||||
|
func (t Transformer) String(s string) string {
|
||||||
|
s, _, _ = transform.String(t, s)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
// Fold is a transform that maps all runes to their canonical width.
|
||||||
|
//
|
||||||
|
// Note that the NFKC and NFKD transforms in golang.org/x/text/unicode/norm
|
||||||
|
// provide a more generic folding mechanism.
|
||||||
|
Fold Transformer = Transformer{foldTransform{}}
|
||||||
|
|
||||||
|
// Widen is a transform that maps runes to their wide variant, if
|
||||||
|
// available.
|
||||||
|
Widen Transformer = Transformer{wideTransform{}}
|
||||||
|
|
||||||
|
// Narrow is a transform that maps runes to their narrow variant, if
|
||||||
|
// available.
|
||||||
|
Narrow Transformer = Transformer{narrowTransform{}}
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO: Consider the following options:
|
||||||
|
// - Treat Ambiguous runes that have a halfwidth counterpart as wide, or some
|
||||||
|
// generalized variant of this.
|
||||||
|
// - Consider a wide Won character to be the default width (or some generalized
|
||||||
|
// variant of this).
|
||||||
|
// - Filter the set of characters that gets converted (the preferred approach is
|
||||||
|
// to allow applying filters to transforms).
|
||||||
3
vendor/modules.txt
vendored
3
vendor/modules.txt
vendored
|
|
@ -121,7 +121,7 @@ github.com/gorilla/websocket
|
||||||
# github.com/inconshreveable/mousetrap v1.1.0
|
# github.com/inconshreveable/mousetrap v1.1.0
|
||||||
## explicit; go 1.18
|
## explicit; go 1.18
|
||||||
github.com/inconshreveable/mousetrap
|
github.com/inconshreveable/mousetrap
|
||||||
# github.com/jedib0t/go-pretty/v6 v6.6.4
|
# github.com/jedib0t/go-pretty/v6 v6.6.5
|
||||||
## explicit; go 1.17
|
## explicit; go 1.17
|
||||||
github.com/jedib0t/go-pretty/v6/table
|
github.com/jedib0t/go-pretty/v6/table
|
||||||
github.com/jedib0t/go-pretty/v6/text
|
github.com/jedib0t/go-pretty/v6/text
|
||||||
|
|
@ -322,6 +322,7 @@ golang.org/x/text/internal/tag
|
||||||
golang.org/x/text/language
|
golang.org/x/text/language
|
||||||
golang.org/x/text/transform
|
golang.org/x/text/transform
|
||||||
golang.org/x/text/unicode/norm
|
golang.org/x/text/unicode/norm
|
||||||
|
golang.org/x/text/width
|
||||||
# google.golang.org/protobuf v1.35.2
|
# google.golang.org/protobuf v1.35.2
|
||||||
## explicit; go 1.21
|
## explicit; go 1.21
|
||||||
google.golang.org/protobuf/encoding/protodelim
|
google.golang.org/protobuf/encoding/protodelim
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue