-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathconvert.go
142 lines (121 loc) · 3.13 KB
/
convert.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package main
import (
"encoding/csv"
"fmt"
"os"
"strings"
"unicode/utf8"
)
const (
VERTICAL_DEVIDER = "|"
HORIZONTAL_DEVIDER = "-"
)
func ConvertAll(args *Args) error {
for _, file := range args.Files {
md, err := Convert(file, args)
if err != nil {
return err
}
// print markdown
fmt.Println(md)
}
return nil
}
func Convert(file string, args *Args) (string, error) {
records, err := CsvToArray(file, args.Delim)
if err != nil {
return "", err
}
if len(records) < 1 { // when csv is empty
return "", nil
}
// modify content
records = Modify(records)
// array to markdown
md, err := ArrayToMd(records, args)
if err != nil {
return "", err
}
return md, nil
}
func CsvToArray(file, delim string) ([][]string, error) {
fp, err := os.Open(file)
if err != nil {
return nil, err
}
defer fp.Close()
reader := csv.NewReader(fp)
reader.Comma = []rune(delim)[0]
reader.LazyQuotes = true
return reader.ReadAll()
}
func ArrayToMd(records [][]string, args *Args) (string, error) {
colSizes := colMaxSize(records)
records, err := padCells(records, colSizes)
if err != nil {
return "", err
}
horiz := createHorizontalDivder(colSizes, args.Pad)
rows := concateWithSep(records, args.Pad)
md := []string{}
md = append(md, rows[0]) // header
md = append(md, horiz) // horizontal devider
for _, v := range rows[1:] {
md = append(md, v)
}
return strings.Join(md, "\n"), nil
}
func Modify(records [][]string) [][]string {
for i, row := range records {
for j, ele := range row {
records[i][j] = strings.ReplaceAll(ele, "\n", "<br/>")
}
}
return records
}
func padCells(records [][]string, colSizes []int) ([][]string, error) {
for i, row := range records {
for j, v := range row {
if diff := colSizes[j] - utf8.RuneCountInString(v); diff >= 0 {
records[i][j] = v + strings.Repeat(" ", diff)
} else {
fmt.Println(v)
fmt.Println(colSizes[j])
fmt.Println(utf8.RuneCountInString(v))
return nil, fmt.Errorf("Internal error: column size is bigger than max.")
}
}
}
return records, nil
}
func colMaxSize(records [][]string) []int {
var sizes []int = make([]int, len(records[0]))
for _, row := range records {
for j, v := range row {
if cur := utf8.RuneCountInString(v); sizes[j] < cur {
sizes[j] = cur
}
}
}
return sizes
}
func createHorizontalDivder(colSizes []int, pad int) string {
var dividers []string
for _, v := range colSizes {
dividers = append(dividers, strings.Repeat(HORIZONTAL_DEVIDER, v))
}
sep := strings.Repeat(HORIZONTAL_DEVIDER, pad) + VERTICAL_DEVIDER + strings.Repeat(HORIZONTAL_DEVIDER, pad)
leftside := VERTICAL_DEVIDER + strings.Repeat("-", pad)
rightside := strings.Repeat("-", pad) + VERTICAL_DEVIDER
return leftside + strings.Join(dividers, sep) + rightside
}
func concateWithSep(records [][]string, pad int) []string {
var rows []string
sep := strings.Repeat(" ", pad) + VERTICAL_DEVIDER + strings.Repeat(" ", pad)
leftside := VERTICAL_DEVIDER + strings.Repeat(" ", pad)
rightside := strings.Repeat(" ", pad) + VERTICAL_DEVIDER
for _, row := range records {
rows = append(rows, leftside+strings.Join(row, sep)+rightside)
}
return rows
}