diff --git a/cmd/merge.go b/cmd/merge.go index 905a3fa..766e88e 100644 --- a/cmd/merge.go +++ b/cmd/merge.go @@ -6,6 +6,8 @@ import ( "path/filepath" "strings" + "github.com/liamgallear/md_split/internal/style" + "github.com/schollz/progressbar/v3" "github.com/spf13/cobra" ) @@ -55,7 +57,9 @@ func mergeMarkdown(cmd *cobra.Command, args []string) error { } // Merge the content + fmt.Println(style.Info("Merging split files...")) var mergedContent strings.Builder + bar := progressbar.Default(int64(len(sortedFiles))) for i, file := range sortedFiles { content, err := os.ReadFile(file) @@ -71,7 +75,8 @@ func mergeMarkdown(cmd *cobra.Command, args []string) error { mergedContent.WriteString("\n\n") } - fmt.Printf("Merged: %s\n", filepath.Base(file)) + fmt.Println(style.FileMerged(filepath.Base(file))) + bar.Add(1) } // Write the merged content to output file @@ -79,6 +84,6 @@ func mergeMarkdown(cmd *cobra.Command, args []string) error { return fmt.Errorf("error writing output file %s: %v", outputFile, err) } - fmt.Printf("Successfully merged %d files into %s\n", len(sortedFiles), outputFile) + fmt.Printf("\n%s\n", style.Summary(fmt.Sprintf("Successfully merged %d files into %s", len(sortedFiles), outputFile))) return nil } \ No newline at end of file diff --git a/cmd/root.go b/cmd/root.go index adbb6a8..4621fb2 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -4,6 +4,7 @@ import ( "fmt" "os" + "github.com/liamgallear/md_split/internal/style" "github.com/spf13/cobra" ) @@ -20,7 +21,7 @@ Available commands: func Execute() { if err := rootCmd.Execute(); err != nil { - fmt.Println(err) + fmt.Fprintln(os.Stderr, style.Error(err.Error())) os.Exit(1) } } diff --git a/cmd/split.go b/cmd/split.go index 010eb03..2c6b8d4 100644 --- a/cmd/split.go +++ b/cmd/split.go @@ -7,6 +7,8 @@ import ( "regexp" "strings" + "github.com/liamgallear/md_split/internal/style" + "github.com/schollz/progressbar/v3" "github.com/spf13/cobra" ) @@ -52,6 +54,9 @@ func splitMarkdown(cmd *cobra.Command, args []string) error { } // Write each section to a separate file + fmt.Println(style.Info("Writing split files...")) + bar := progressbar.Default(int64(len(sections))) + for i, section := range sections { filename := fmt.Sprintf("%02d-%s.md", i+1, sanitizeFilename(section.title)) filepath := filepath.Join(splitsDir, filename) @@ -60,10 +65,11 @@ func splitMarkdown(cmd *cobra.Command, args []string) error { return fmt.Errorf("error writing file %s: %v", filename, err) } - fmt.Printf("Created: %s\n", filename) + fmt.Println(style.FileCreated(filename)) + bar.Add(1) } - fmt.Printf("Successfully split markdown into %d files in %s\n", len(sections), splitsDir) + fmt.Printf("\n%s\n", style.Summary(fmt.Sprintf("Successfully split markdown into %d files in %s", len(sections), splitsDir))) return nil } diff --git a/go.mod b/go.mod index 48d0245..4b757a0 100644 --- a/go.mod +++ b/go.mod @@ -2,9 +2,27 @@ module github.com/liamgallear/md_split go 1.24.7 -require github.com/spf13/cobra v1.10.1 +require ( + github.com/charmbracelet/lipgloss v1.1.0 + github.com/schollz/progressbar/v3 v3.18.0 + github.com/spf13/cobra v1.10.1 +) require ( + github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect + github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect + github.com/charmbracelet/x/ansi v0.8.0 // indirect + github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect + github.com/charmbracelet/x/term v0.2.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/lucasb-eyer/go-colorful v1.2.0 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect + github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect + github.com/muesli/termenv v0.16.0 // indirect + github.com/rivo/uniseg v0.4.7 // indirect github.com/spf13/pflag v1.0.9 // indirect + github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect + golang.org/x/sys v0.30.0 // indirect + golang.org/x/term v0.28.0 // indirect ) diff --git a/go.sum b/go.sum index e613680..592cbeb 100644 --- a/go.sum +++ b/go.sum @@ -1,10 +1,55 @@ +github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= +github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= +github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs= +github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk= +github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY= +github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30= +github.com/charmbracelet/x/ansi v0.8.0 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2llXn7xE= +github.com/charmbracelet/x/ansi v0.8.0/go.mod h1:wdYl/ONOLHLIVmQaxbIYEC/cRKOQyjTkowiI4blgS9Q= +github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8= +github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs= +github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ= +github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg= +github.com/chengxilo/virtualterm v1.0.4 h1:Z6IpERbRVlfB8WkOmtbHiDbBANU7cimRIof7mk9/PwM= +github.com/chengxilo/virtualterm v1.0.4/go.mod h1:DyxxBZz/x1iqJjFxTFcr6/x+jSpqN0iwWCOK1q10rlY= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= +github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= +github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc= +github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/schollz/progressbar/v3 v3.18.0 h1:uXdoHABRFmNIjUfte/Ex7WtuyVslrw2wVPQmCN62HpA= +github.com/schollz/progressbar/v3 v3.18.0/go.mod h1:IsO3lpbaGuzh8zIMzgY3+J8l4C8GjO0Y9S69eFvNsec= github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= +golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E= +golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= +golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/style/style.go b/internal/style/style.go new file mode 100644 index 0000000..2d8015b --- /dev/null +++ b/internal/style/style.go @@ -0,0 +1,111 @@ +package style + +import ( + "github.com/charmbracelet/lipgloss" +) + +// Color definitions +var ( + // Primary colors + PrimaryColor = lipgloss.Color("#00A86B") // Green + SecondaryColor = lipgloss.Color("#0066CC") // Blue + + // Status colors + SuccessColor = lipgloss.Color("#00C851") // Success green + ErrorColor = lipgloss.Color("#FF4444") // Error red + WarningColor = lipgloss.Color("#FFBB33") // Warning amber + InfoColor = lipgloss.Color("#33B5E5") // Info blue + + // Neutral colors + MutedColor = lipgloss.Color("#999999") // Muted gray +) + +// Style definitions +var ( + // Header styles + TitleStyle = lipgloss.NewStyle(). + Foreground(PrimaryColor). + Bold(true). + Margin(1, 0) + + SubtitleStyle = lipgloss.NewStyle(). + Foreground(SecondaryColor). + Bold(true) + + // Message styles + SuccessStyle = lipgloss.NewStyle(). + Foreground(SuccessColor). + Bold(true) + + ErrorStyle = lipgloss.NewStyle(). + Foreground(ErrorColor). + Bold(true) + + WarningStyle = lipgloss.NewStyle(). + Foreground(WarningColor). + Bold(true) + + InfoStyle = lipgloss.NewStyle(). + Foreground(InfoColor) + + // File operation styles + FileCreatedStyle = lipgloss.NewStyle(). + Foreground(SuccessColor) + + FileMergedStyle = lipgloss.NewStyle(). + Foreground(InfoColor) + + // Summary styles + SummaryStyle = lipgloss.NewStyle(). + Foreground(PrimaryColor). + Bold(true). + Margin(1, 0). + Padding(0, 1). + Border(lipgloss.RoundedBorder()). + BorderForeground(PrimaryColor) + + // Helper text styles + MutedStyle = lipgloss.NewStyle(). + Foreground(MutedColor) +) + +// Helper functions for common operations +func Success(text string) string { + return SuccessStyle.Render("✓ " + text) +} + +func Error(text string) string { + return ErrorStyle.Render("✗ " + text) +} + +func Warning(text string) string { + return WarningStyle.Render("⚠ " + text) +} + +func Info(text string) string { + return InfoStyle.Render("ℹ " + text) +} + +func FileCreated(filename string) string { + return FileCreatedStyle.Render("✓ Created: " + filename) +} + +func FileMerged(filename string) string { + return FileMergedStyle.Render("📄 Merged: " + filename) +} + +func Summary(text string) string { + return SummaryStyle.Render(text) +} + +func Muted(text string) string { + return MutedStyle.Render(text) +} + +func Title(text string) string { + return TitleStyle.Render(text) +} + +func Subtitle(text string) string { + return SubtitleStyle.Render(text) +} \ No newline at end of file