mirror of
https://github.com/anthonyaxenov/csv2md.git
synced 2024-11-22 13:25:03 +00:00
Initial version 1.0.0
This commit is contained in:
commit
d7ffa94db5
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
/bin
|
||||||
|
# /.vscode
|
||||||
|
*.csv
|
||||||
|
!example.csv
|
20
.vscode/launch.json
vendored
Normal file
20
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
// 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": "Launch Package",
|
||||||
|
"type": "go",
|
||||||
|
"request": "launch",
|
||||||
|
"mode": "auto",
|
||||||
|
"program": "${fileBasename}",
|
||||||
|
"args": [
|
||||||
|
"example.csv",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2022 Антон Аксенов (aka Anthony Axenov)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
41
Makefile
Normal file
41
Makefile
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
# https://habr.com/ru/post/461467/
|
||||||
|
# https://tutorialedge.net/golang/makefiles-for-go-developers/
|
||||||
|
# https://earthly.dev/blog/golang-makefile/
|
||||||
|
BINARY_NAME=csv2md
|
||||||
|
ARCH=amd64
|
||||||
|
|
||||||
|
LINUX_PATH="bin/linux_${ARCH}"
|
||||||
|
WINDOWS_PATH="bin/windows_${ARCH}"
|
||||||
|
DARWIN_PATH="bin/darwin_${ARCH}"
|
||||||
|
|
||||||
|
LINUX_FILE="${LINUX_PATH}/${BINARY_NAME}"
|
||||||
|
WINDOWS_FILE="${WINDOWS_PATH}/${BINARY_NAME}.exe"
|
||||||
|
DARWIN_FILE="${DARWIN_PATH}/${BINARY_NAME}"
|
||||||
|
|
||||||
|
## clean: Removes all compiled binaries
|
||||||
|
clean:
|
||||||
|
@go clean
|
||||||
|
@rm -rf bin/
|
||||||
|
|
||||||
|
## linux: Builds new binaries for linux (x64)
|
||||||
|
linux:
|
||||||
|
@rm -rf ${LINUX_PATH}
|
||||||
|
@GOARCH=${ARCH} GOOS=linux go build -o ${LINUX_FILE} . && echo "Compiled: ${LINUX_FILE}"
|
||||||
|
|
||||||
|
## win: Builds new binaries for windows (x64)
|
||||||
|
win:
|
||||||
|
@rm -rf ${WINDOWS_PATH}
|
||||||
|
@GOARCH=${ARCH} GOOS=windows go build -o ${WINDOWS_FILE} . && echo "Compiled: ${WINDOWS_FILE}"
|
||||||
|
|
||||||
|
## darwin: Builds new binaries for darwin (x64)
|
||||||
|
darwin:
|
||||||
|
@rm -rf ${DARWIN_PATH}
|
||||||
|
@GOARCH=${ARCH} GOOS=darwin go build -o ${DARWIN_FILE} . && echo "Compiled: ${DARWIN_FILE}"
|
||||||
|
|
||||||
|
## build: Builds new binaries for linux, windows and darwin (x64)
|
||||||
|
all: clean linux win darwin
|
||||||
|
|
||||||
|
## compile: This message
|
||||||
|
help: Makefile
|
||||||
|
@echo "Choose a command run:"
|
||||||
|
@sed -n 's/^##//p' $< | column -t -s ':' | sed -e 's/^/ /'
|
23
README.md
Normal file
23
README.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# csv2md
|
||||||
|
|
||||||
|
Stupidly simple tool to convert csv-file to [markdown](https://spec-md.com/) table.
|
||||||
|
|
||||||
|
Outputs result in stdout.
|
||||||
|
|
||||||
|
Building:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
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 and whitespaces are allowed only between double-quotes.
|
||||||
|
|
||||||
|
Examples can be found here: https://people.sc.fsu.edu/~jburkardt/data/csv/csv.html
|
14
example.csv
Normal file
14
example.csv
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
"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
|
||||||
|
|
|
81
main.go
Normal file
81
main.go
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/csv"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const VERSION = "1.0.0"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if len(os.Args) < 2 {
|
||||||
|
usage()
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
src, err := ExpandPath(os.Args[1])
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if _, err := os.Stat(src); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
result := convert(readCsv(src))
|
||||||
|
for _, row := range result {
|
||||||
|
fmt.Println(row)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
newpath, err := filepath.Abs(strings.Replace(path, "~", homepath, 1))
|
||||||
|
return newpath, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func readCsv(filePath string) [][]string {
|
||||||
|
f, err := os.Open(filePath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Unable to read input file " + filePath, err)
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
csvReader := csv.NewReader(f)
|
||||||
|
records, err := csvReader.ReadAll()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Unable to parse file as CSV for " + filePath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return records
|
||||||
|
}
|
||||||
|
|
||||||
|
func convert(records [][]string) []string {
|
||||||
|
var result []string
|
||||||
|
for idx, row := range records {
|
||||||
|
str := "| "
|
||||||
|
for _, col := range row {
|
||||||
|
str += col + " | "
|
||||||
|
}
|
||||||
|
result = append(result, str)
|
||||||
|
if idx == 0 {
|
||||||
|
str := "| "
|
||||||
|
for range row {
|
||||||
|
str += "--- | "
|
||||||
|
}
|
||||||
|
result = append(result, str)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user