Skip to content

Commit

Permalink
handling malformed line and adding option in web app
Browse files Browse the repository at this point in the history
  • Loading branch information
rougepied committed May 12, 2014
1 parent c7ee3d4 commit 9a118b6
Showing 1 changed file with 125 additions and 8 deletions.
133 changes: 125 additions & 8 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,135 @@ import (
"bufio"
"flag"
"fmt"
"html/template"
"io"
"log"
"net/http"
"os"
"strconv"
"strings"
)

//var templates = template.Must(template.ParseFiles("casus_table.html"))
var html = `<html>
<style type="text/css">
.err { color: red; }
</style>
<body>
<h1>Casus Table</h1>
{{if .Err}}
<p class="err">{{.Err}}</p>
{{end}}
<form action="." method="POST">
<ul>
<li>Separator:
<input type="radio" name="sep" value="semico" {{if eq .Sep "semico"}}checked{{end}} ><label for="sep">semicolon</label>
<input type="radio" name="sep" value="tabula" {{if eq .Sep "tabula"}}checked{{end}} ><label for="sep">tab</label>
</li>
<li>Style:
<input type="radio" name="style" value="grid" {{if eq .Style "grid"}}checked{{end}} ><label for="sep">Grid table</label>
<input type="radio" name="style" value="simp" {{if eq .Style "simp"}}checked{{end}} ><label for="sep">Simple table</label>
</li>
</ul>
<textarea name="input" rows="20" cols="80">{{printf "%s" .Input}}</textarea>
<input type="submit" value="Convert">
<textarea name="output" rows="20" cols="80">{{printf "%s" .Output}}</textarea>
</form>
</body>
</html>`

func main() {
// Parsing command line args
path := flag.String("file", "", "path to file")
sep := flag.String("sep", ";", "column separator")
port := flag.String("port", ":8080", "port (if running as a web app)")
flag.Parse()

// Input file
if *path != "" {

// Input file
file, err := os.Open("input.csv")
if err != nil {
log.Fatal(err)
}
defer file.Close()
table, size := measure(file, sep)
table, size, _ := measure(file, *sep)
table2 := formatTable(table, size)
fmt.Println(rst2Table(table2, size))
fmt.Println(rst2TableSimple(table2, size))
} else {
// run as a server
log.Println("Running as server")
http.HandleFunc("/", handler)
http.ListenAndServe(*port, nil)
}
}

func handler(w http.ResponseWriter, r *http.Request) {
p := make(map[string]interface{})

// processing
input := r.FormValue("input")
var sep string
switch r.FormValue("sep") {
default:
sep = ";"
p["Sep"] = "semico"
case "semico":
sep = ";"
p["Sep"] = "semico"
case "tabula":
sep = "\t"
p["Sep"] = "tabula"
}
var style string
switch r.FormValue("style") {
default:
style = "simp"
p["Style"] = "simp"
case "simp":
style = "simp"
p["Style"] = "simp"
case "grid":
style = "grid"
p["Style"] = "grid"
}
table, size, err := measure(strings.NewReader(input), sep)
table2 := formatTable(table, size)
var output string
switch style {
case "simp":
output = rst2TableSimple(table2, size)
case "grid":
output = rst2TableGrid(table2, size)
}
// responsing
p["Input"] = input
p["Output"] = output

if err != nil {
p["Err"] = err
}

t, err := template.New("casus_table").Parse(html)
err = t.Execute(w, p)
// err := templates.Execute(w, p)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}

func rst2Table(table [][]string, size []int) (r string) {
func rst2TableGrid(table [][]string, size []int) (r string) {
separator := rstSeparator(size)
for idx, line := range table {
if idx == 0 {
r += separator + "\n"
}
r += "|" + strings.Join(line, "|") + "|\n"
r += separator + "\n"
}
return
}

func rst2TableSimple(table [][]string, size []int) (r string) {
nbline := len(table)
separator := rstSeparator2(size)
for idx, line := range table {
Expand All @@ -57,6 +158,17 @@ func formatTable(table [][]string, size []int) (r [][]string) {
return
}

func rstSeparator(cols []int) string {
t := make([]string, len(cols))
for idx, val := range cols {
for j := 0; j < val; j++ {
t[idx] += "-"
}
}

return "+" + strings.Join(t, "+") + "+"
}

func rstSeparator2(cols []int) string {
t := make([]string, len(cols))
for idx, val := range cols {
Expand All @@ -69,20 +181,25 @@ func rstSeparator2(cols []int) string {
}

// measure measures the width of columns.
func measure(input io.Reader, sep *string) ([][]string, []int) {
func measure(input io.Reader, sep string) ([][]string, []int, error) {
var r []int
var t [][]string

scanr := bufio.NewScanner(input)
for scanr.Scan() {
line := scanr.Text()
tab := strings.Split(line, *sep)
tab := strings.Split(line, sep)
t = append(t, tab)
if len(r) == 0 {
r = make([]int, len(tab))
}

rline := make([]int, len(tab))

if len(rline) > len(r) {
return nil, nil, fmt.Errorf("Error: the line “%s” is too long", line)
}

for idx, val := range tab {
rline[idx] = len(val)
r[idx] = max(r[idx], len(val))
Expand All @@ -92,7 +209,7 @@ func measure(input io.Reader, sep *string) ([][]string, []int) {
if err := scanr.Err(); err != nil {
log.Fatal(err)
}
return t, r
return t, r, nil
}

// max return the maximum value between 2 int
Expand Down

0 comments on commit 9a118b6

Please sign in to comment.