paper-system/json2md/lib/lib.go

137 lines
3.6 KiB
Go
Raw Permalink Normal View History

2025-01-24 15:26:47 +00:00
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, "]", "\\]")
fmt.Fprintf(file, "## [%s](https://arxiv.org/abs/%s)\n", title, paper.Paper.ArxivID)
fmt.Fprintf(file, "**arXiv ID:** %s\n\n", paper.Paper.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")
}