package lib import ( "encoding/json" "fmt" "os" "strings" ) type Paper struct { Title string `json:"title"` ArxivID string `json:"arxiv_id"` Abstract string `json:"abstract"` } type PaperDecision struct { Paper Paper `json:"paper"` Explanation string `json:"explanation"` } type DecisionData struct { Accepted []PaperDecision `json:"accepted"` Rejected []PaperDecision `json:"rejected"` } func ProcessJSONFile(inputPath string) (DecisionData, error) { var data DecisionData jsonFile, err := os.Open(inputPath) if err != nil { return data, fmt.Errorf("error opening input file: %w", err) } defer jsonFile.Close() // First try decoding as DecisionData format decoder := json.NewDecoder(jsonFile) if err := decoder.Decode(&data); err == nil { return data, nil } // Try alternative formats jsonData, err := os.ReadFile(inputPath) if err != nil { return data, fmt.Errorf("error reading input file: %w", err) } // Try array format with status field var papers []struct { Paper Paper `json:"paper"` Explanation string `json:"explanation"` Status string `json:"status"` } if err := json.Unmarshal(jsonData, &papers); err == nil { for _, p := range papers { switch p.Status { case "accepted": data.Accepted = append(data.Accepted, PaperDecision{p.Paper, p.Explanation}) case "rejected": data.Rejected = append(data.Rejected, PaperDecision{p.Paper, p.Explanation}) default: fmt.Printf("Warning: Paper '%s' has unknown status '%s'\n", p.Paper.Title, p.Status) } } return data, nil } // Try original object format var objData struct { Accepted []PaperDecision `json:"accepted"` Rejected []PaperDecision `json:"rejected"` } if err := json.Unmarshal(jsonData, &objData); err != nil { return data, fmt.Errorf("error decoding JSON: %w", err) } data.Accepted = objData.Accepted data.Rejected = objData.Rejected return data, nil } func GenerateMarkdown(data DecisionData, outputPath string) error { file, err := os.Create(outputPath) if err != nil { return fmt.Errorf("error creating output file: %w", err) } defer file.Close() // Accepted Papers section fmt.Fprintln(file, "# Accepted Papers\n") for _, paper := range data.Accepted { writePaperSection(file, paper, "accepted") } // Rejected Papers section fmt.Fprintln(file, "# Rejected Papers\n") for _, paper := range data.Rejected { writePaperSection(file, paper, "rejected") } return nil } func writePaperSection(file *os.File, paper PaperDecision, decisionType string) { // Escape special characters in title title := strings.ReplaceAll(paper.Paper.Title, "[", "\\[") title = strings.ReplaceAll(title, "]", "\\]") // Extract just the arXiv ID portion (remove any URL prefix) arxivID := strings.TrimPrefix(paper.Paper.ArxivID, "http://arxiv.org/abs/") arxivID = strings.TrimPrefix(arxivID, "https://arxiv.org/abs/") fmt.Fprintf(file, "## [%s](https://arxiv.org/abs/%s)\n", title, arxivID) fmt.Fprintf(file, "**arXiv ID:** %s\n\n", arxivID) fmt.Fprintln(file, "**Abstract:**") // Format abstract as blockquote, handling multiple paragraphs abstract := strings.TrimSpace(paper.Paper.Abstract) paragraphs := strings.Split(abstract, "\n\n") for i, p := range paragraphs { // Ensure each line starts with > lines := strings.Split(strings.TrimSpace(p), "\n") for _, line := range lines { fmt.Fprintf(file, "> %s\n", strings.TrimSpace(line)) } if i < len(paragraphs)-1 { fmt.Fprintln(file, ">") } } fmt.Fprintln(file) // Format explanation, ensuring it's properly escaped and formatted fmt.Fprintln(file, "**Decision Explanation:**") explanation := strings.TrimSpace(paper.Explanation) // If the explanation is already properly formatted (no raw JSON or code blocks), // write it directly fmt.Fprintf(file, "%s\n\n", explanation) fmt.Fprintln(file, "---\n") }