1
0
mirror of https://github.com/anthonyaxenov/csv2md.git synced 2024-11-26 07:04:57 +00:00

Compare commits

..

No commits in common. "c7fd26e7b4954ea192bbf483accccf11d35528e9" and "d7ffa94db5cc253006e0bf468097f5c551c46bc1" have entirely different histories.

5 changed files with 59 additions and 176 deletions

1
.gitignore vendored
View File

@ -1,5 +1,4 @@
/bin
# /.vscode
*.csv
*.md
!example.csv

28
.vscode/launch.json vendored
View File

@ -2,17 +2,19 @@
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Debug csv2md",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "main.go"
// "args": [
// "example.csv",
// ]
}
]
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch Package",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${fileBasename}",
"args": [
"example.csv",
]
}
]
}
}

View File

@ -4,35 +4,20 @@ Stupidly simple tool to convert csv-file to [markdown](https://spec-md.com/) tab
Outputs result in stdout.
## Usage
Building:
```shell
csv2md (-h|-help|--help|help) # to get this help
csv2md example.csv # convert data from file and write result in stdout
csv2md < example.csv # convert data from stdin and write result in stdout
cat example.csv | csv2md # convert data from stdin and write result in stdout
csv2md example.csv > example.md # convert data from file and write result in new file
csv2md example.csv | less # convert data from file and write result in stdout using pager
csv2md # paste or type data to stdin by hands
# press Ctrl+D to view result in stdout
csv2md > example.md # paste or type data to stdin by hands
# press Ctrl+D to write result in new file
make help
```
Usage:
```shell
csv2md example.csv > example.md # makes new file
csv2md example.csv | less # view result using *pager*
...anything is possible with redirection and piping
```
> **IMPORTANT:**
> * input must be valid csv
> * whitespaces allowed only between double-quotes
> **IMPORTANT:** input must be valid csv and whitespaces are allowed only between double-quotes.
Examples can be found here: https://people.sc.fsu.edu/~jburkardt/data/csv/csv.html
## Compilation
1) [Install go](https://go.dev/learn/).
2) Download this repo via zip or `git clone`.
3) Run `make help` to get help or `go run . <csv_path>` to build and run temporary binary.
## License
[MIT](LICENSE)

View File

@ -1,50 +1,14 @@
"Name","Team","Position","Height(inches)","Weight(lbs)","Age"
"Adam Donachie","BAL","Catcher",74,180,22.99
"Paul Bako","BAL","Catcher",74,215,34.69
"Ramon Hernandez","BAL","Catcher",72,210,30.78
"Kevin Millar","BAL","First Baseman",72,210,35.43
"Chris Gomez","BAL","First Baseman",73,188,35.71
"Brian Roberts","BAL","Second Baseman",69,176,29.39
"Miguel Tejada","BAL","Shortstop",69,209,30.77
"Melvin Mora","BAL","Third Baseman",71,200,35.07
"Aubrey Huff","BAL","Third Baseman",76,231,30.19
"Adam Stern","BAL","Outfielder",71,180,27.05
"Jeff Fiorentino","BAL","Outfielder",73,188,23.88
"Freddie Bynum","BAL","Outfielder",73,180,26.96
"Nick Markakis","BAL","Outfielder",74,185,23.29
"Brandon Fahey","BAL","Outfielder",74,160,26.11
"Corey Patterson","BAL","Outfielder",69,180,27.55
"Jay Payton","BAL","Outfielder",70,185,34.27
"Jay Gibbons","BAL","Designated Hitter",72,197,30
"Erik Bedard","BAL","Starting Pitcher",73,189,27.99
"Hayden Penn","BAL","Starting Pitcher",75,185,22.38
"Adam Loewen","BAL","Starting Pitcher",78,219,22.89
"Daniel Cabrera","BAL","Starting Pitcher",79,230,25.76
"Steve Trachsel","BAL","Starting Pitcher",76,205,36.33
"Jaret Wright","BAL","Starting Pitcher",74,230,31.17
"Kris Benson","BAL","Starting Pitcher",76,195,32.31
"Scott Williamson","BAL","Relief Pitcher",72,180,31.03
"John Parrish","BAL","Relief Pitcher",71,192,29.26
"Danys Baez","BAL","Relief Pitcher",75,225,29.47
"Chad Bradford","BAL","Relief Pitcher",77,203,32.46
"Jamie Walker","BAL","Relief Pitcher",74,195,35.67
"Brian Burres","BAL","Relief Pitcher",73,182,25.89
"Kurt Birkins","BAL","Relief Pitcher",74,188,26.55
"James Hoey","BAL","Relief Pitcher",78,200,24.17
"Sendy Rleal","BAL","Relief Pitcher",73,180,26.69
"Chris Ray","BAL","Relief Pitcher",75,200,25.13
"Jeremy Guthrie","BAL","Relief Pitcher",73,200,27.9
"A.J. Pierzynski","CWS","Catcher",75,245,30.17
"Toby Hall","CWS","Catcher",75,240,31.36
"Paul Konerko","CWS","First Baseman",74,215,30.99
"Tadahito Iguchi","CWS","Second Baseman",69,185,32.24
"Juan Uribe","CWS","Shortstop",71,175,27.61
"Alex Cintron","CWS","Shortstop",74,199,28.2
"Joe Crede","CWS","Third Baseman",73,200,28.85
"Josh Fields","CWS","Third Baseman",73,215,24.21
"Ryan Sweeney","CWS","Outfielder",76,200,22.02
"Brian N. Anderson","CWS","Outfielder",74,205,24.97
"Luis Terrero","CWS","Outfielder",74,206,26.78
"Pablo Ozuna","CWS","Outfielder",70,186,32.51
"Scott Podsednik","CWS","Outfielder",72,188,30.95
"Jermaine Dye","CWS","Outfielder",77,220,33.09
"Month","1958","1959","1960"
"JAN",340,360,417
"FEB",318,342,391
"MAR",362,406,419
"APR",348,396,461
"MAY",363,420,472
"JUN",435,472,535
"JUL",491,548,622
"AUG",505,559,606
"SEP",404,463,508
"OCT",359,407,461
"NOV",310,362,390
"DEC",337,405,432

1 Name Month Team 1958 Position 1959 Height(inches) 1960 Weight(lbs) Age
2 Adam Donachie JAN BAL 340 Catcher 360 74 417 180 22.99
3 Paul Bako FEB BAL 318 Catcher 342 74 391 215 34.69
4 Ramon Hernandez MAR BAL 362 Catcher 406 72 419 210 30.78
5 Kevin Millar APR BAL 348 First Baseman 396 72 461 210 35.43
6 Chris Gomez MAY BAL 363 First Baseman 420 73 472 188 35.71
7 Brian Roberts JUN BAL 435 Second Baseman 472 69 535 176 29.39
8 Miguel Tejada JUL BAL 491 Shortstop 548 69 622 209 30.77
9 Melvin Mora AUG BAL 505 Third Baseman 559 71 606 200 35.07
10 Aubrey Huff SEP BAL 404 Third Baseman 463 76 508 231 30.19
11 Adam Stern OCT BAL 359 Outfielder 407 71 461 180 27.05
12 Jeff Fiorentino NOV BAL 310 Outfielder 362 73 390 188 23.88
13 Freddie Bynum DEC BAL 337 Outfielder 405 73 432 180 26.96
14 Nick Markakis BAL Outfielder 74 185 23.29
Brandon Fahey BAL Outfielder 74 160 26.11
Corey Patterson BAL Outfielder 69 180 27.55
Jay Payton BAL Outfielder 70 185 34.27
Jay Gibbons BAL Designated Hitter 72 197 30
Erik Bedard BAL Starting Pitcher 73 189 27.99
Hayden Penn BAL Starting Pitcher 75 185 22.38
Adam Loewen BAL Starting Pitcher 78 219 22.89
Daniel Cabrera BAL Starting Pitcher 79 230 25.76
Steve Trachsel BAL Starting Pitcher 76 205 36.33
Jaret Wright BAL Starting Pitcher 74 230 31.17
Kris Benson BAL Starting Pitcher 76 195 32.31
Scott Williamson BAL Relief Pitcher 72 180 31.03
John Parrish BAL Relief Pitcher 71 192 29.26
Danys Baez BAL Relief Pitcher 75 225 29.47
Chad Bradford BAL Relief Pitcher 77 203 32.46
Jamie Walker BAL Relief Pitcher 74 195 35.67
Brian Burres BAL Relief Pitcher 73 182 25.89
Kurt Birkins BAL Relief Pitcher 74 188 26.55
James Hoey BAL Relief Pitcher 78 200 24.17
Sendy Rleal BAL Relief Pitcher 73 180 26.69
Chris Ray BAL Relief Pitcher 75 200 25.13
Jeremy Guthrie BAL Relief Pitcher 73 200 27.9
A.J. Pierzynski CWS Catcher 75 245 30.17
Toby Hall CWS Catcher 75 240 31.36
Paul Konerko CWS First Baseman 74 215 30.99
Tadahito Iguchi CWS Second Baseman 69 185 32.24
Juan Uribe CWS Shortstop 71 175 27.61
Alex Cintron CWS Shortstop 74 199 28.2
Joe Crede CWS Third Baseman 73 200 28.85
Josh Fields CWS Third Baseman 73 215 24.21
Ryan Sweeney CWS Outfielder 76 200 22.02
Brian N. Anderson CWS Outfielder 74 205 24.97
Luis Terrero CWS Outfielder 74 206 26.78
Pablo Ozuna CWS Outfielder 70 186 32.51
Scott Podsednik CWS Outfielder 72 188 30.95
Jermaine Dye CWS Outfielder 77 220 33.09

109
main.go
View File

@ -2,8 +2,6 @@ package main
import (
"encoding/csv"
"errors"
"flag"
"fmt"
"log"
"os"
@ -11,62 +9,33 @@ import (
"strings"
)
const VERSION = "1.1.0"
const VERSION = "1.0.0"
func main() {
log.SetFlags(0)
switch len(os.Args) {
case 1: // first we read data from stdin and then convert it
data, err := readRawCsv()
if err != nil {
log.Fatal(err)
}
print(data)
case 2: // but if 2nd arg is present
// probably user wants to get help
help1 := flag.Bool("h", false, "Get help")
help2 := flag.Bool("help", false, "Get help")
flag.Parse()
if os.Args[1] == "help" || *help1 || *help2 {
usage(os.Stdout)
os.Exit(0)
}
// ...or to convert data from file
src, err := ExpandPath(os.Args[1])
if err != nil {
log.Fatal(err)
}
if _, err := os.Stat(src); err != nil {
log.Fatal(err)
}
data, err := readCsvFile(src)
if err != nil {
log.Fatal(err)
}
print(data)
// otherwise let's show usage help and exit (probably inaccessible code, but anyway)
default:
usage(os.Stdout)
os.Exit(0)
if len(os.Args) < 2 {
usage()
os.Exit(1)
}
}
// print write converted data to stdout
func print(data [][]string) {
if len(data) == 0 {
usage(os.Stderr)
src, err := ExpandPath(os.Args[1])
if err != nil {
panic(err)
}
result := convert(data)
if _, err := os.Stat(src); err != nil {
panic(err)
}
result := convert(readCsv(src))
for _, row := range result {
fmt.Println(row)
}
}
// ExpandPath return absolute path to file replacing ~ to user's home folder
func usage() {
fmt.Fprintln(os.Stderr, "csv2md v" + VERSION)
fmt.Fprintln(os.Stderr, "Usage: csv2md data.csv > data.md")
}
func ExpandPath(path string) (string, error) {
homepath, err := os.UserHomeDir()
if err != nil {
@ -76,34 +45,22 @@ func ExpandPath(path string) (string, error) {
return newpath, err
}
// readRawCsv read data from file
func readCsvFile(filePath string) ([][]string, error) {
func readCsv(filePath string) [][]string {
f, err := os.Open(filePath)
if err != nil {
return nil, errors.New("Failed to open file '" + filePath + "': " + err.Error())
log.Fatal("Unable to read input file " + filePath, err)
}
defer f.Close()
csvReader := csv.NewReader(f)
records, err := csvReader.ReadAll()
if err != nil {
return nil, errors.New("Failed to parse CSV from file '" + filePath + "': " + err.Error())
log.Fatal("Unable to parse file as CSV for " + filePath, err)
}
return records, nil
return records
}
// readRawCsv read data from stdin
func readRawCsv() ([][]string, error) {
csvReader := csv.NewReader(os.Stdin)
records, err := csvReader.ReadAll()
if err != nil {
return nil, errors.New("Failed to parse CSV from stdin: " + err.Error())
}
return records, nil
}
// convert format data from file or stdin as markdown
func convert(records [][]string) []string {
var result []string
for idx, row := range records {
@ -122,27 +79,3 @@ func convert(records [][]string) []string {
}
return result
}
// usage print help into writer
func usage(writer *os.File) {
usage := []string{
"csv2md v" + VERSION,
"Anthony Axenov (c) 2022, MIT license",
"https://github.com/anthonyaxenov/csv2md",
"",
"Usage:",
"\tcsv2md (-h|-help|--help|help) # to get this help",
"\tcsv2md example.csv # convert data from file and write result in stdout",
"\tcsv2md < example.csv # convert data from stdin and write result in stdout",
"\tcat example.csv | csv2md # convert data from stdin and write result in stdout",
"\tcsv2md example.csv > example.md # convert data from file and write result in new file",
"\tcsv2md example.csv | less # convert data from file and write result in stdout using pager",
"\tcsv2md # paste or type data to stdin by hands",
"\t # press Ctrl+D to view result in stdout",
"\tcsv2md > example.md # paste or type data to stdin by hands",
"\t # press Ctrl+D to write result in new file",
}
for _, str := range usage {
fmt.Fprintln(writer, str)
}
}