Introduce the office Bubble Tea browser (module tree, multi-select lists, markdown preview) alongside oo, with cmd/internal/bootstrap for shared auth, unit tests across preview/model/ui/fetch, CI build for both binaries, and GoReleaser archives for office. Co-authored-by: Cursor <cursoragent@cursor.com>
66 lines
1.7 KiB
Go
66 lines
1.7 KiB
Go
package preview
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/csv"
|
|
"encoding/json"
|
|
"fmt"
|
|
"strings"
|
|
|
|
xls "github.com/eslider/go-xls/v2"
|
|
)
|
|
|
|
// CSVToMarkdownTable parses CSV bytes into a GitHub pipe table markdown string.
|
|
func CSVToMarkdownTable(data []byte) (string, error) {
|
|
tab, err := parseCSV(data)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
var buf bytes.Buffer
|
|
if err := xls.WriteMarkdownTable(&buf, tab); err != nil {
|
|
return "", err
|
|
}
|
|
return strings.TrimSpace(buf.String()) + "\n", nil
|
|
}
|
|
|
|
func parseCSV(data []byte) (xls.Table, error) {
|
|
r := csv.NewReader(bytes.NewReader(data))
|
|
r.TrimLeadingSpace = true
|
|
records, err := r.ReadAll()
|
|
if err != nil {
|
|
return xls.Table{}, err
|
|
}
|
|
if len(records) == 0 {
|
|
return xls.Table{}, fmt.Errorf("preview: empty csv")
|
|
}
|
|
return xls.Table{Columns: records[0], Rows: records[1:]}, nil
|
|
}
|
|
|
|
// JSONToMarkdown wraps JSON in a fenced code block for preview.
|
|
func JSONToMarkdown(data []byte) (string, error) {
|
|
var v any
|
|
if err := json.Unmarshal(data, &v); err != nil {
|
|
return "", err
|
|
}
|
|
pretty, err := json.MarshalIndent(v, "", " ")
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return fmt.Sprintf("```json\n%s\n```\n", string(pretty)), nil
|
|
}
|
|
|
|
// FileBytesToMarkdown picks a preview format based on file extension.
|
|
func FileBytesToMarkdown(name string, data []byte) (string, error) {
|
|
ext := strings.ToLower(name)
|
|
switch {
|
|
case strings.HasSuffix(ext, ".csv"):
|
|
return CSVToMarkdownTable(data)
|
|
case strings.HasSuffix(ext, ".json"):
|
|
return JSONToMarkdown(data)
|
|
case strings.HasSuffix(ext, ".md"), strings.HasSuffix(ext, ".txt"):
|
|
return string(data), nil
|
|
default:
|
|
return fmt.Sprintf("```\n(binary or unsupported preview for %s, %d bytes)\n```\n", name, len(data)), nil
|
|
}
|
|
}
|