Skip to content

Commit

Permalink
Quote support
Browse files Browse the repository at this point in the history
Change dlimiter processing to line-by-line
  • Loading branch information
noborus committed Aug 24, 2024
1 parent e0d04b4 commit a16d4ea
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 35 deletions.
73 changes: 39 additions & 34 deletions oviewer/convert_align.go
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
package oviewer

import (
"regexp"

"github.com/mattn/go-runewidth"
)

// align is a converter that aligns columns.
// It is used to align columns when the delimiter is reached or to align columns by adding spaces to the end of the line.
type align struct {
es *escapeSequence
maxWidths []int // column max width
orgWidths []int
WidthF bool
delimiter []rune
delmCount int
count int
columnNum int
es *escapeSequence
maxWidths []int // column max width
orgWidths []int
WidthF bool
delimiter string
delimiterReg *regexp.Regexp
count int
}

func newAlignConverter(widthF bool) *align {
return &align{
es: newESConverter(),
count: 0,
columnNum: 0,
WidthF: widthF,
es: newESConverter(),
count: 0,
WidthF: widthF,
}
}

Expand All @@ -34,14 +36,18 @@ func (a *align) convert(st *parseState) bool {
return true
}

if a.columnNum >= len(a.maxWidths) {
if len(a.maxWidths) == 0 {
return false
}
a.count += 1
if runewidth.RuneWidth(st.mainc) > 1 {
a.count += 1
}

if st.mainc != '\n' {
return false
}

if a.WidthF {
return a.convertWidth(st)
}
Expand All @@ -50,37 +56,36 @@ func (a *align) convert(st *parseState) bool {

func (a *align) reset() {
a.count = 0
a.columnNum = 0
a.delmCount = 0
}

// convertWidth accumulates one line and then adds spaces to align the column widths.
// convertDelm aligns the column widths by adding spaces when it reaches a delimiter.
// convertDelm works line by line.
func (a *align) convertDelm(st *parseState) bool {
if a.delmCount < len(a.delimiter) && st.mainc == a.delimiter[a.delmCount] {
a.delmCount += 1
} else {
a.delmCount = 0
str, pos := ContentsToStr(st.lc)
indexes := allIndex(str, a.delimiter, a.delimiterReg)
if len(indexes) == 0 {
return false
}
if a.delmCount > len(a.delimiter) {
return false
}
// Add space to align columns.
for ; a.count < a.maxWidths[a.columnNum]; a.count++ {
st.lc = append(st.lc, SpaceContent)
s := 0
lc := make(contents, 0, len(st.lc))
for c := 0; c < len(indexes); c++ {
e := pos.x(indexes[c][0])
lc = append(lc, st.lc[s:e]...)
width := e - s
// Add space to align columns.
for ; width < a.maxWidths[c]; width++ {
lc = append(lc, SpaceContent)
}
s = e
}
a.columnNum++
a.count = 0
a.delmCount = 0

lc = append(lc, st.lc[s:]...)
st.lc = lc
return false
}

// convertDelm aligns the column widths by adding spaces when it reaches a delimiter.
// convertWidth accumulates one line and then adds spaces to align the column widths.
// convertWidth works line by line.
func (a *align) convertWidth(st *parseState) bool {
if st.mainc != '\n' {
return false
}
s := 0
lc := make(contents, 0, len(st.lc))
for i := 0; i < len(a.orgWidths); i++ {
Expand Down
3 changes: 2 additions & 1 deletion oviewer/prepare_draw.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ func (root *Root) setAlignColumnWidths() {
m := root.Doc
m.alignConv.WidthF = m.ColumnWidth
if !m.alignConv.WidthF {
root.Doc.alignConv.delimiter = []rune(root.Doc.ColumnDelimiter)
root.Doc.alignConv.delimiter = m.ColumnDelimiter
root.Doc.alignConv.delimiterReg = m.ColumnDelimiterReg
}

maxWidths := make([]int, 0, len(m.alignConv.maxWidths))
Expand Down
7 changes: 7 additions & 0 deletions oviewer/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ func allStringIndex(s string, substr string) [][]int {
s = s[pos+width:]
result = append(result, []int{pos + offSet, pos + offSet + width})
offSet += pos + width

if len(s) > 0 && s[0] == '"' {
qpos := strings.Index(s[1:], `"`)
s = s[qpos+2:]
offSet += qpos + 2
}

pos = strings.Index(s, substr)
}
return result
Expand Down
22 changes: 22 additions & 0 deletions oviewer/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,28 @@ func Test_allStringIndex(t *testing.T) {
},
want: nil,
},
{
name: "testDoubleQuote",
args: args{
s: `a,"b,c",d`,
substr: ",",
},
want: [][]int{
{1, 2},
{7, 8},
},
},
{
name: "testDoubleQuote2",
args: args{
s: `a,"060 ",d`,
substr: ",",
},
want: [][]int{
{1, 2},
{9, 10},
},
},
}
for _, tt := range tests {
tt := tt
Expand Down

0 comments on commit a16d4ea

Please sign in to comment.