cmd/bibel.go (view raw)
1package main
2
3import (
4 "fmt"
5 "os"
6 "time"
7
8 "github.com/alexflint/go-arg"
9 "golang.org/x/term"
10 "maxwelljensen/bibel/internal"
11 "maxwelljensen/bibel/internal/tui"
12)
13
14// Args defines the command line arguments
15type Args struct {
16 Reading string `arg:"-r,--reading" help:"reading mode: evangelion (Gospels), new_testament, old_testament, bible (default: evangelion)"`
17 Plain bool `arg:"-p,--plain" help:"output plain text without formatting or TUI"`
18 Formatted bool `arg:"-f,--formatted" help:"output formatted text with ANSI colours (no TUI)"`
19 ConfigPath string `arg:"-c,--config" help:"path to configuration file (default: $XDG_CONFIG_HOME/bibel/config.toml)"`
20 Numbered bool `arg:"-n,--numbered" help:"print each verse on a numbered line with verse number"`
21 Paragraphs bool `arg:"-g,--paragraphs" help:"render pilcrows (ΒΆ) as blank lines instead of ignoring them"`
22 Latin bool `arg:"-l,--latin" help:"show time until Roman Catholic Easter"`
23 GenerateConfig bool `arg:"--generate-config" help:"generate a default configuration file and exit"`
24 Verbose bool `arg:"-v,--verbose" help:"print additional runtime information to STDOUT"`
25}
26
27// Description returns a description of the program
28func (Args) Description() string {
29 return "Display today's Bible reading based on selected reading mode.\n" +
30 "Reads 12 verses per day based on the current date.\n" +
31 "Reading modes: evangelion (four Gospels), new_testament, old_testament, bible\n" +
32 "Configuration file: $XDG_CONFIG_HOME/bibel/config.toml"
33}
34
35func main() {
36 var args Args
37 arg.MustParse(&args)
38
39 // Handle config generation
40 if args.GenerateConfig {
41 if err := bible.GenerateDefaultConfig(); err != nil {
42 fmt.Fprintf(os.Stderr, "Error generating config: %v\n", err)
43 os.Exit(1)
44 }
45 fmt.Printf("Default configuration generated at: %s\n", bible.GetConfigPath())
46 return
47 }
48
49 // Load configuration
50 config, err := bible.LoadConfig(args.ConfigPath, args.Verbose)
51 if err != nil {
52 fmt.Fprintf(os.Stderr, "Error loading config: %v\n", err)
53 os.Exit(1)
54 }
55
56 // Override Easter type from command line flag if specified
57 if args.Latin {
58 config.EasterType = "latin"
59 }
60
61 // Override reading mode from command line if specified
62 if args.Reading != "" {
63 config.ReadingMode = args.Reading
64
65 // Validate reading mode after command line override
66 validReadingModes := map[string]bool{
67 "evangelion": true,
68 "new_testament": true,
69 "old_testament": true,
70 "bible": true,
71 }
72 if config.ReadingMode != "" && !validReadingModes[config.ReadingMode] {
73 fmt.Fprintf(os.Stderr, "Error: invalid reading mode: %s, must be one of: evangelion, new_testament, old_testament, bible\n", config.ReadingMode)
74 os.Exit(1)
75 }
76 }
77
78 // Load Bible data
79 bibleData, err := bible.LoadBible(config.BiblePath, args.Verbose)
80 if err != nil {
81 fmt.Fprintf(os.Stderr, "Error loading Bible data: %v\n", err)
82 os.Exit(1)
83 }
84
85 // Create date progression calculator
86 // We need to convert reading mode string to ReadingMode type
87 // Based on verse.go, ReadingMode is a string type with constants
88 // Create date progression calculator with reading mode from config
89 dateProg := bible.NewDateProgressionWithReadingMode(bibleData, config.DateProgression.VersesPerDay, bible.ReadingMode(config.ReadingMode))
90
91 // Get today's bookmark
92 bookmark, err := dateProg.GetPositionForDate(time.Now())
93 if err != nil {
94 fmt.Fprintf(os.Stderr, "Error calculating today's reading position: %v\n", err)
95 os.Exit(1)
96 }
97
98 // Determine output mode: plain, formatted, or TUI
99 // Plain mode forces no colours, formatted respects config
100 usePlain := args.Plain
101 useFormatted := args.Formatted
102
103 // If no explicit mode but numbered/paragraphs flags are set, use formatted mode
104 if !usePlain && !useFormatted && (args.Numbered || args.Paragraphs) {
105 useFormatted = true
106 }
107
108 // If we're outputting text (plain or formatted)
109 if usePlain || useFormatted {
110 // Determine colours: plain mode = false, formatted mode = from config
111 useColours := false
112 if useFormatted {
113 useColours = config.Formatter.UseColours
114 }
115
116 // Create formatter with appropriate settings
117 formatter := bible.NewFormatterWithFullConfig(bibleData, useColours, config.Formatter.HeaderFormat, args.Numbered, args.Paragraphs)
118 header := formatter.FormatHeader(bookmark)
119 content := formatter.ExtractAndFormat(bibleData, bookmark)
120 fmt.Println(header)
121 fmt.Println(content)
122 return
123 }
124
125 // Default: TUI mode (no plain or formatted flags)
126 // Check if we're in a terminal
127 if !term.IsTerminal(int(os.Stdin.Fd())) {
128 fmt.Fprintln(os.Stderr, "Error: Standard input is not a terminal. Use --plain or --formatted for non-interactive output.")
129 os.Exit(1)
130 }
131
132 // Create and run TUI program
133 program := tui.CreateTUIProgram(bibleData, bookmark, config)
134 if _, err := program.Run(); err != nil {
135 fmt.Fprintf(os.Stderr, "Error running TUI: %v\n", err)
136 os.Exit(1)
137 }
138}
139