|
| 1 | +package procedures |
| 2 | + |
| 3 | +import ( |
| 4 | + "fmt" |
| 5 | + "strings" |
| 6 | +) |
| 7 | + |
| 8 | +// OutputOptions controls what information is displayed in the output. |
| 9 | +type OutputOptions struct { |
| 10 | + ListAll bool // List all variations with their selection/tabid values |
| 11 | + ListSummary bool // List procedures grouped by heading without selection details |
| 12 | + Implementation bool // Show how each procedure is implemented |
| 13 | + SubProcedures bool // Indicate if procedures contain nested sub-procedures |
| 14 | + StepCount bool // Show step count for each procedure |
| 15 | +} |
| 16 | + |
| 17 | +// PrintReport prints the analysis report to stdout based on the output options. |
| 18 | +func PrintReport(report *AnalysisReport, options OutputOptions) { |
| 19 | + // If no special options are set, just print the count |
| 20 | + if !options.ListAll && !options.ListSummary && !options.Implementation && !options.SubProcedures && !options.StepCount { |
| 21 | + printSummary(report) |
| 22 | + return |
| 23 | + } |
| 24 | + |
| 25 | + // Print detailed report |
| 26 | + printDetailedReport(report, options) |
| 27 | +} |
| 28 | + |
| 29 | +// groupProceduresByHeading groups procedures by their heading and returns the groups and order. |
| 30 | +func groupProceduresByHeading(procedures []ProcedureAnalysis) (map[string][]ProcedureAnalysis, []string) { |
| 31 | + headingGroups := make(map[string][]ProcedureAnalysis) |
| 32 | + headingOrder := []string{} |
| 33 | + |
| 34 | + for _, analysis := range procedures { |
| 35 | + heading := analysis.Procedure.Title |
| 36 | + if heading == "" { |
| 37 | + heading = "(Untitled)" |
| 38 | + } |
| 39 | + |
| 40 | + if _, exists := headingGroups[heading]; !exists { |
| 41 | + headingOrder = append(headingOrder, heading) |
| 42 | + } |
| 43 | + headingGroups[heading] = append(headingGroups[heading], analysis) |
| 44 | + } |
| 45 | + |
| 46 | + return headingGroups, headingOrder |
| 47 | +} |
| 48 | + |
| 49 | +// calculateTotals calculates total unique procedures and appearances from grouped data. |
| 50 | +func calculateTotals(headingGroups map[string][]ProcedureAnalysis) (int, int) { |
| 51 | + totalUniqueProcedures := 0 |
| 52 | + totalAppearances := 0 |
| 53 | + |
| 54 | + for _, procedures := range headingGroups { |
| 55 | + totalUniqueProcedures += len(procedures) |
| 56 | + for _, proc := range procedures { |
| 57 | + totalAppearances += proc.VariationCount |
| 58 | + } |
| 59 | + } |
| 60 | + |
| 61 | + return totalUniqueProcedures, totalAppearances |
| 62 | +} |
| 63 | + |
| 64 | +// printSummary prints a summary of the analysis. |
| 65 | +func printSummary(report *AnalysisReport) { |
| 66 | + fmt.Printf("File: %s\n", report.FilePath) |
| 67 | + fmt.Printf("Total unique procedures: %d\n", len(report.Procedures)) |
| 68 | + fmt.Printf("Total procedure appearances: %d\n", report.TotalVariations) |
| 69 | +} |
| 70 | + |
| 71 | +// printDetailedReport prints a detailed analysis report. |
| 72 | +func printDetailedReport(report *AnalysisReport, options OutputOptions) { |
| 73 | + fmt.Printf("Procedure Analysis for: %s\n", report.FilePath) |
| 74 | + fmt.Println(strings.Repeat("=", 80)) |
| 75 | + |
| 76 | + // Group procedures by heading first to get accurate counts |
| 77 | + headingGroups, headingOrder := groupProceduresByHeading(report.Procedures) |
| 78 | + totalUniqueProcedures, totalAppearances := calculateTotals(headingGroups) |
| 79 | + |
| 80 | + fmt.Printf("\nTotal unique procedures: %d\n", totalUniqueProcedures) |
| 81 | + fmt.Printf("Total procedure appearances: %d\n\n", totalAppearances) |
| 82 | + |
| 83 | + // Print implementation type summary if requested |
| 84 | + if options.Implementation { |
| 85 | + fmt.Println("Procedures by implementation type:") |
| 86 | + for implType, count := range report.ProceduresByType { |
| 87 | + fmt.Printf(" - %s: %d\n", implType, count) |
| 88 | + } |
| 89 | + fmt.Println() |
| 90 | + } |
| 91 | + |
| 92 | + // Print details grouped by heading (headingGroups already created above) |
| 93 | + fmt.Println("Procedures by Heading:") |
| 94 | + fmt.Println(strings.Repeat("-", 80)) |
| 95 | + |
| 96 | + headingNum := 1 |
| 97 | + for _, heading := range headingOrder { |
| 98 | + procedures := headingGroups[heading] |
| 99 | + |
| 100 | + fmt.Printf("\n%d. %s\n", headingNum, heading) |
| 101 | + fmt.Printf(" Unique procedures: %d\n", len(procedures)) |
| 102 | + |
| 103 | + // Calculate total appearances for this heading |
| 104 | + totalAppearances := 0 |
| 105 | + for _, proc := range procedures { |
| 106 | + totalAppearances += proc.VariationCount |
| 107 | + } |
| 108 | + fmt.Printf(" Total appearances: %d\n", totalAppearances) |
| 109 | + |
| 110 | + // If only showing summary, skip the individual procedure details |
| 111 | + if options.ListSummary && !options.ListAll { |
| 112 | + headingNum++ |
| 113 | + continue |
| 114 | + } |
| 115 | + |
| 116 | + // Determine if we need sub-numbering (only when there are multiple unique procedures) |
| 117 | + useSubNumbering := len(procedures) > 1 |
| 118 | + |
| 119 | + // Show each unique procedure under this heading |
| 120 | + for i, analysis := range procedures { |
| 121 | + fmt.Printf("\n ") |
| 122 | + |
| 123 | + // Only show sub-numbering if there are multiple unique procedures |
| 124 | + if useSubNumbering { |
| 125 | + fmt.Printf("%d.%d. ", headingNum, i+1) |
| 126 | + } |
| 127 | + |
| 128 | + // Show the first step to distinguish procedures (only if there are multiple) |
| 129 | + if useSubNumbering { |
| 130 | + if len(analysis.Procedure.Steps) > 0 && analysis.Procedure.Steps[0].Title != "" { |
| 131 | + fmt.Printf("%s\n", analysis.Procedure.Steps[0].Title) |
| 132 | + } else if len(analysis.Procedure.Steps) > 0 { |
| 133 | + fmt.Printf("(Untitled first step)\n") |
| 134 | + } else { |
| 135 | + fmt.Printf("(No steps)\n") |
| 136 | + } |
| 137 | + } else { |
| 138 | + // For single procedures, just show the step count |
| 139 | + fmt.Printf("Steps: %d\n", len(analysis.Procedure.Steps)) |
| 140 | + } |
| 141 | + |
| 142 | + // Indent based on whether we're using sub-numbering |
| 143 | + indent := " " |
| 144 | + if !useSubNumbering { |
| 145 | + indent = " " |
| 146 | + } |
| 147 | + |
| 148 | + // Only show step count if we already showed the first step title |
| 149 | + if useSubNumbering { |
| 150 | + fmt.Printf("%sSteps: %d\n", indent, len(analysis.Procedure.Steps)) |
| 151 | + } |
| 152 | + |
| 153 | + // Print implementation type if requested |
| 154 | + if options.Implementation { |
| 155 | + fmt.Printf("%sImplementation: %s\n", indent, analysis.Implementation) |
| 156 | + } |
| 157 | + |
| 158 | + // Print sub-procedures flag if requested |
| 159 | + if options.SubProcedures { |
| 160 | + if analysis.HasSubSteps { |
| 161 | + fmt.Printf("%sContains sub-procedures: yes\n", indent) |
| 162 | + } else { |
| 163 | + fmt.Printf("%sContains sub-procedures: no\n", indent) |
| 164 | + } |
| 165 | + } |
| 166 | + |
| 167 | + // Print selections if requested |
| 168 | + if options.ListAll { |
| 169 | + if analysis.VariationCount == 1 { |
| 170 | + fmt.Printf("%sAppears in 1 selection:\n", indent) |
| 171 | + } else { |
| 172 | + fmt.Printf("%sAppears in %d selections:\n", indent, analysis.VariationCount) |
| 173 | + } |
| 174 | + |
| 175 | + if len(analysis.Variations) > 0 && analysis.Variations[0] != "(no variations)" { |
| 176 | + for _, variation := range analysis.Variations { |
| 177 | + fmt.Printf("%s - %s\n", indent, variation) |
| 178 | + } |
| 179 | + } else { |
| 180 | + fmt.Printf("%s (single variation, no tabs or selections)\n", indent) |
| 181 | + } |
| 182 | + } else if options.ListSummary { |
| 183 | + // For summary, just show the count without listing all selections |
| 184 | + if analysis.VariationCount == 1 { |
| 185 | + fmt.Printf("%sAppears in 1 selection\n", indent) |
| 186 | + } else { |
| 187 | + fmt.Printf("%sAppears in %d selections\n", indent, analysis.VariationCount) |
| 188 | + } |
| 189 | + } |
| 190 | + } |
| 191 | + |
| 192 | + headingNum++ |
| 193 | + } |
| 194 | + |
| 195 | + fmt.Println() |
| 196 | +} |
| 197 | + |
0 commit comments