diff options
| author | Paul Buetow <paul@buetow.org> | 2025-07-20 22:18:57 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2025-07-20 22:18:57 +0300 |
| commit | e580fb57a29ec3c3f3e180b20cfa6ec28687689b (patch) | |
| tree | de74f04450b830268e4c1644a91acb9fd45c3802 /internal/batch | |
| parent | 9e3328a6aaefe4bd1aa0ec3e8bf6e93d6033180b (diff) | |
Refactor main.go into focused packages
- Reduced main.go from 961 lines to 89 lines (91% reduction)
- Created new packages for better separation of concerns:
- cli: Command-line interface setup and configuration
- processor: Core word processing logic and orchestration
- batch: Batch file processing functionality
- translation: Bulgarian to English translation services
- models: OpenAI model listing functionality
- phonetic: Phonetic information fetching
- Each package has clear documentation in doc.go files
- Improved testability and maintainability
- All existing functionality preserved
- All tests passing and build successful
Diffstat (limited to 'internal/batch')
| -rw-r--r-- | internal/batch/doc.go | 4 | ||||
| -rw-r--r-- | internal/batch/processor.go | 94 |
2 files changed, 98 insertions, 0 deletions
diff --git a/internal/batch/doc.go b/internal/batch/doc.go new file mode 100644 index 0000000..33f3b19 --- /dev/null +++ b/internal/batch/doc.go @@ -0,0 +1,4 @@ +// Package batch handles batch processing of Bulgarian words from files. +// It supports reading word lists with optional translations in the format: +// "bulgarian_word" or "bulgarian_word = english_translation" +package batch diff --git a/internal/batch/processor.go b/internal/batch/processor.go new file mode 100644 index 0000000..75a38aa --- /dev/null +++ b/internal/batch/processor.go @@ -0,0 +1,94 @@ +package batch + +import ( + "fmt" + "os" + "strings" +) + +// WordEntry represents a word with optional translation +type WordEntry struct { + Bulgarian string + Translation string +} + +// ReadBatchFile reads words from a file and returns WordEntry slice +// Supports formats: +// - Bulgarian word only: "ябълка" +// - With translation: "ябълка = apple" +func ReadBatchFile(filename string) ([]WordEntry, error) { + content, err := os.ReadFile(filename) + if err != nil { + return nil, fmt.Errorf("failed to read batch file: %w", err) + } + + var entries []WordEntry + lines := string(content) + + for _, line := range splitLines(lines) { + if line = trimSpace(line); line != "" { + // Check if line contains '=' for bulgarian = english format + if strings.Contains(line, "=") { + parts := strings.SplitN(line, "=", 2) + if len(parts) == 2 { + bulgarian := strings.TrimSpace(parts[0]) + english := strings.TrimSpace(parts[1]) + if bulgarian != "" { + entries = append(entries, WordEntry{ + Bulgarian: bulgarian, + Translation: english, + }) + } + } + } else { + // Just a bulgarian word + entries = append(entries, WordEntry{ + Bulgarian: line, + Translation: "", + }) + } + } + } + + return entries, nil +} + +// splitLines splits a string by newlines +func splitLines(s string) []string { + var lines []string + current := "" + for _, r := range s { + if r == '\n' { + lines = append(lines, current) + current = "" + } else if r != '\r' { + current += string(r) + } + } + if current != "" { + lines = append(lines, current) + } + return lines +} + +// trimSpace trims whitespace from string +func trimSpace(s string) string { + start := 0 + end := len(s) + + // Trim from start + for start < end && isSpace(rune(s[start])) { + start++ + } + + // Trim from end + for end > start && isSpace(rune(s[end-1])) { + end-- + } + + return s[start:end] +} + +func isSpace(r rune) bool { + return r == ' ' || r == '\t' || r == '\n' || r == '\r' +} |
