output/main.go
output/main.go
c49c91f08e0175c574cb0d141813b19c529acc06
Init
package output
import (
"encoding/csv"
"encoding/json"
"fmt"
"logc/parser"
"os"
"regexp"
"sort"
"strings"
)
func limitLines(lines []string, length int) []string {
var result []string
for _, line := range lines {
for len(line) > length {
// Find the last space within the allowed length
cut := length
for i := length; i > 0; i-- {
if line[i] == ' ' {
cut = i
break
}
}
// If there's no space within the limit, break at the exact length
if cut == length {
result = append(result, line[:cut])
line = line[cut:]
} else {
// Otherwise, break at the last space and remove it
result = append(result, line[:cut])
line = line[cut+1:] // Skip the space
}
}
// Append any remaining text
if len(line) > 0 {
result = append(result, line)
}
}
for i, v := range result {
result[i] = strings.TrimSpace(v)
}
return result
}
// Group the comments by their tags and format the output with colors
func FormatText(comments []parser.Comment, lineLength int) string {
grouped := make(map[string][]parser.Comment)
// Group comments by tag
for _, comment := range comments {
grouped[comment.Headers[0]] = append(grouped[comment.Headers[0]], comment)
}
groupedSorted := []string{}
for h := range grouped {
groupedSorted = append(groupedSorted, h)
}
sort.Strings(groupedSorted)
// Format the grouped comments for display
var output strings.Builder
for _, tag := range groupedSorted {
tagComments := grouped[tag]
output.WriteString(fmt.Sprintf("%s\n", tag)) // Tag with customizable color
output.WriteString(strings.Repeat("-", len(tag)+5) + "\n")
for _, comment := range tagComments {
output.WriteString(fmt.Sprintf("\tFile: %s:%d\n", comment.File, comment.Line)) // File path with customizable color
output.WriteString(fmt.Sprintf("\t\t%s\n", strings.Join(limitLines(strings.Split(comment.Data[0], "\n"), lineLength-2), "\n\t\t")))
// !MAN: This is a test
for i := 1; i < len(comment.Headers); i++ {
output.WriteString(fmt.Sprintf("\t\t%s\n", comment.Headers[i])) // File path with customizable color
output.WriteString(fmt.Sprintf("\t\t\t%s\n\n", strings.Join(limitLines(strings.Split(comment.Data[i], "\n"), lineLength-3), "\n\t\t")))
}
output.WriteString("\n")
// output.WriteString(fmt.Sprintf("\t%s\n", comment.Capture))
}
}
return output.String()
}
// !ISSUE: Remove []
func GetHeaders(comments []parser.Comment) []string {
headerMap := map[string]int{}
for _, v := range comments {
for _, h := range v.Headers {
if h[0] == '[' {
tags := strings.Split(h[1:strings.Index(h, "]")], ",")
for _, t := range tags {
if t[0] == '!' {
headerMap[t[1:]] = 0
} else {
headerMap[t] = 0
}
}
} else {
headerMap[h] = 0
}
}
}
headers := []string{}
for k := range headerMap {
headers = append(headers, k)
}
return headers
}
// Output function for text
func Text(comments []parser.Comment) {
fmt.Println(FormatText(comments, 90))
}
// Output function for JSON
func JSON(comments []parser.Comment) {
data, err := json.MarshalIndent(comments, "", " ")
if err != nil {
fmt.Println("Error generating JSON:", err)
return
}
fmt.Println(string(data))
}
// !TODO: Add markdown Output
func HTML(comments []parser.Comment) string {
grouped := make(map[string][]parser.Comment)
// Group comments by tag
for _, comment := range comments {
grouped[comment.Headers[0]] = append(grouped[comment.Headers[0]], comment)
}
groupedSorted := []string{}
for h := range grouped {
groupedSorted = append(groupedSorted, h)
}
sort.Strings(groupedSorted)
// Format the grouped comments for display
var output strings.Builder
for _, tag := range groupedSorted {
tagComments := grouped[tag]
output.WriteString(fmt.Sprintf("%s
\n", tag))
for _, comment := range tagComments {
output.WriteString(fmt.Sprintf("File: %s:%d
\n", comment.File, comment.Line)) // File path with customizable color
output.WriteString(fmt.Sprintf("%s
\n", strings.ReplaceAll(comment.Data[0], "\n", "")))
// !MAN: This is a test
output.WriteString("")
for i := 1; i < len(comment.Headers); i++ {
output.WriteString(fmt.Sprintf("- \n%s\n", comment.Headers[i])) // File path with customizable color
output.WriteString(fmt.Sprintf("%s\n
\n\n", strings.ReplaceAll(comment.Data[i], "\n", "")))
}
output.WriteString("
\n")
}
}
return output.String()
}
func GroupByHeaders(comments []parser.Comment, headers string) map[string][]parser.Comment {
grouped := make(map[string][]parser.Comment)
headersSplit := strings.Split(headers, ",")
// Group comments by tag
for _, comment := range comments {
for _, header := range comment.Headers {
if len(headersSplit) > 1 {
for _, rqh := range headersSplit {
if rqh == header {
grouped[header] = append(grouped[header], comment)
}
}
} else {
grouped[header] = append(grouped[header], comment)
}
}
}
return grouped
}
// !OUTPUT: Used by the -format=csv flag to transform data into CSV
// + just some more text
// + Usage: Pass a slice of comments to output.CSV and it will write a formatted version to
// + the console
// + [!MAN]Def: [141:168](DEVMAN)
// + [DEVMAN]Note: Here the loop breaks early to prevent runaway
// + [DEVMAN,MAN]INFO: Just some more information
func CSV(comments []parser.Comment) {
writer := csv.NewWriter(os.Stdout)
defer writer.Flush()
// !DEVMAN: Text
headers := GetHeaders(comments)
// !ERROR: this will break the capture
writer.Write(headers)
for _, comment := range comments {
out := []string{}
for _, v := range headers {
index := -1
for i, h := range comment.Headers {
if h == v {
index = i
break
}
}
// add a line
if index == -1 {
out = append(out, "")
} else {
out = append(out, comment.Data[index])
}
}
writer.Write(out)
}
}
// ANSI color codes for different tab levels
var colors = []string{
"\033[0m", // Default
"\033[34m", // Blue
"\033[32m", // Green
"\033[33m", // Yellow
"\033[31m", // Red
"\033[35m", // Magenta
"\033[36m", // Cyan
}
func HighlightText(paragraph string) string {
lines := strings.Split(paragraph, "\n")
re := regexp.MustCompile(`^(\t*)`) // Regex to match leading tabs
var result strings.Builder
for _, line := range lines {
matches := re.FindString(line)
tabCount := len(matches)
// Apply color based on tab count, ensuring it doesn't exceed available colors
var color string
if tabCount < len(colors) {
color = colors[tabCount]
} else {
color = colors[len(colors)-1]
}
reset := "\033[0m"
// Apply color to the entire line
result.WriteString(color + line + reset + "\n")
}
return result.String()
}