From 858ee3e70a4867d795711697015d36251861877b Mon Sep 17 00:00:00 2001 From: Thomas Miceli Date: Sun, 19 Mar 2023 03:18:56 +0100 Subject: [PATCH] Parse CSV files into HTML tables --- internal/git/output_parser.go | 33 +++++++++++++++++++++++ internal/web/run.go | 16 +++++++++++ public/main.js | 2 +- public/style.css | 20 ++++++++++++++ templates/pages/gist.html | 50 ++++++++++++++++++++++++++--------- 5 files changed, 108 insertions(+), 13 deletions(-) diff --git a/internal/git/output_parser.go b/internal/git/output_parser.go index 3b75cec..39e467c 100644 --- a/internal/git/output_parser.go +++ b/internal/git/output_parser.go @@ -3,8 +3,11 @@ package git import ( "bufio" "bytes" + "encoding/csv" + "fmt" "io" "regexp" + "strings" ) type File struct { @@ -16,6 +19,12 @@ type File struct { IsDeleted bool } +type CsvFile struct { + File + Header []string + Rows [][]string +} + type Commit struct { Hash string Author string @@ -152,3 +161,27 @@ func parseLog(out io.Reader) []*Commit { return commits } + +func ParseCsv(file *File) (*CsvFile, error) { + + reader := csv.NewReader(strings.NewReader(file.Content)) + records, err := reader.ReadAll() + if err != nil { + return nil, err + } + + header := records[0] + numColumns := len(header) + + for i := 1; i < len(records); i++ { + if len(records[i]) != numColumns { + return nil, fmt.Errorf("CSV file has invalid row at index %d", i) + } + } + + return &CsvFile{ + File: *file, + Header: header, + Rows: records[1:], + }, nil +} diff --git a/internal/web/run.go b/internal/web/run.go index 3342832..8ddbd44 100644 --- a/internal/web/run.go +++ b/internal/web/run.go @@ -11,6 +11,7 @@ import ( "io" "net/http" "opengist/internal/config" + "opengist/internal/git" "opengist/internal/models" "path/filepath" "regexp" @@ -77,6 +78,21 @@ func Start() { "isMarkdown": func(i string) bool { return ".md" == strings.ToLower(filepath.Ext(i)) }, + "isCsv": func(i string) bool { + return ".csv" == strings.ToLower(filepath.Ext(i)) + }, + "csvFile": func(file *git.File) *git.CsvFile { + if ".csv" != strings.ToLower(filepath.Ext(file.Filename)) { + return nil + } + + csvFile, err := git.ParseCsv(file) + if err != nil { + return nil + } + + return csvFile + }, "httpStatusText": http.StatusText, "loadedTime": func(startTime time.Time) string { return fmt.Sprint(time.Since(startTime).Nanoseconds()/1e6) + "ms" diff --git a/public/main.js b/public/main.js index 0ee3f65..c12b060 100644 --- a/public/main.js +++ b/public/main.js @@ -18,7 +18,7 @@ document.addEventListener('DOMContentLoaded', () => { let rev = document.querySelector('.revision-text') if (rev) { let fullRev = rev.innerHTML - let smallRev = fullRev.substring(0, 8) + let smallRev = fullRev.substring(0, 7) rev.innerHTML = smallRev rev.onmouseover = () => { diff --git a/public/style.css b/public/style.css index 1c0c2bb..ccb8532 100644 --- a/public/style.css +++ b/public/style.css @@ -110,4 +110,24 @@ pre { .line-num { @apply cursor-pointer text-slate-400 hover:text-white; +} + +table.csv-table { + @apply w-full whitespace-pre text-xs; +} + +table.csv-table thead { + text-align: left; +} + +table.csv-table thead tr { + @apply bg-slate-800; +} + +table.csv-table thead tr th { + @apply border py-2 px-1 border-slate-700; +} + +table.csv-table tbody td { + @apply border py-1.5 px-1 border-slate-800; } \ No newline at end of file diff --git a/templates/pages/gist.html b/templates/pages/gist.html index 3169896..1d077b2 100644 --- a/templates/pages/gist.html +++ b/templates/pages/gist.html @@ -3,6 +3,7 @@ {{ if .files }}
{{ range $file := .files }} + {{ $csv := csvFile $file }}
@@ -20,21 +21,46 @@ This file has been truncated. View the full file.
{{ end }} + {{ if and (not $csv) (isCsv $file.Filename) }} +
+ This file is not a valid CSV file. +
+ {{ end }}
-
- {{ if isMarkdown $file.Filename }} +
+ {{ if $csv }} + + + + {{ range $csv.Header }} + + {{ end }} + + + + {{ range $csv.Rows }} + + {{ range . }} + + {{ end }} + + {{ end }} +
{{ . }}
{{ . }}
+ {{ else if isMarkdown $file.Filename }}
{{ $file.Content }}
{{ else }} - {{ $fileslug := slug $file.Filename }} - {{ if ne $file.Content "" }} - - - {{ $ii := "1" }} - {{ $i := toInt $ii }} - {{ range $line := lines $file.Content }}{{ $i = inc $i }}{{ end }} - -
{{$i}}{{ $line }}
- {{ end }} +
+ {{ $fileslug := slug $file.Filename }} + {{ if ne $file.Content "" }} + + + {{ $ii := "1" }} + {{ $i := toInt $ii }} + {{ range $line := lines $file.Content }}{{ $i = inc $i }}{{ end }} + +
{{$i}}{{ $line }}
+ {{ end }} +
{{ end }}