diff --git a/cmd/find.go b/cmd/find.go index 00e9f60..cef1b27 100644 --- a/cmd/find.go +++ b/cmd/find.go @@ -2,6 +2,7 @@ package cmd import ( "fmt" + "log" "os" "strings" @@ -14,7 +15,9 @@ var findCmd = &cobra.Command{ Use: "find", Aliases: []string{"f", "s", "search"}, Short: "Print IDs and titles of zettels matching QUERY", - Long: `zet find QUERY`, + Long: `zet find QUERY + +If -j or --json is added, the results will be in JSON format.`, Run: func(cmd *cobra.Command, args []string) { if len(args) < 1 { fmt.Println("No query") @@ -26,6 +29,20 @@ var findCmd = &cobra.Command{ result := lib.ParseZetList(zets) - fmt.Println(strings.Join(result, "\n")) + if jsonOutput { + json, err := lib.AsJSON(result) + + if err != nil { + log.Fatal(err) + } + + fmt.Println(json) + } else { + fmt.Println(strings.Join(result, "\n")) + } }, } + +func init() { + findCmd.Flags().BoolVarP(&jsonOutput, "json", "j", false, "Output results in JSON format") +} diff --git a/cmd/root.go b/cmd/root.go index ce264fe..f1dd18c 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -6,6 +6,8 @@ import ( "github.com/spf13/cobra" ) +var jsonOutput bool + // rootCmd represents the base command when called without any subcommands var rootCmd = &cobra.Command{ Use: "zet", diff --git a/cmd/titles.go b/cmd/titles.go index e28f7ca..53a8964 100644 --- a/cmd/titles.go +++ b/cmd/titles.go @@ -2,6 +2,7 @@ package cmd import ( "fmt" + "log" "strings" "github.com/spf13/cobra" @@ -13,12 +14,28 @@ var titlesCmd = &cobra.Command{ Use: "titles", Aliases: []string{"t"}, Short: "Print IDs and titles of zettels", - Long: `Print the IDs and titles of all zettels.`, + Long: `Print the IDs and titles of all zettels. + +If -j or --json is added, the results will be in JSON format.`, Run: func(cmd *cobra.Command, args []string) { zets := lib.GetAllZets() result := lib.ParseZetList(zets) - fmt.Println(strings.Join(result, "\n")) + if jsonOutput { + json, err := lib.AsJSON(result) + + if err != nil { + log.Fatal(err) + } + + fmt.Println(json) + } else { + fmt.Println(strings.Join(result, "\n")) + } }, } + +func init() { + titlesCmd.Flags().BoolVarP(&jsonOutput, "json", "j", false, "Output results in JSON format") +} diff --git a/internal/lib/json.go b/internal/lib/json.go new file mode 100644 index 0000000..47f3381 --- /dev/null +++ b/internal/lib/json.go @@ -0,0 +1,48 @@ +package lib + +import ( + "encoding/json" + "fmt" + "regexp" + "strconv" + "strings" +) + +var ansiRegex = regexp.MustCompile(`\x1b\[[0-9;]*m`) + +type Item struct { + ID int `json:"id"` + Title string `json:"title"` +} + +func AsJSON(zets []string) (string, error) { + var items []Item + + for _, entry := range zets { + cleanEntry := stripANSI(entry) + parts := strings.SplitN(cleanEntry, " ", 2) + + id, _ := strconv.Atoi(parts[0]) + + item := Item{ + ID: id, + Title: parts[1], + } + + items = append(items, item) + } + + jsonData, err := json.MarshalIndent(items, "", " ") + + if err != nil { + fmt.Println("Error marshaling to JSON:", err) + + return "", err + } + + return string(jsonData), nil +} + +func stripANSI(s string) string { + return ansiRegex.ReplaceAllString(s, "") +}