package asciidoc import ( "encoding/json" "fmt" "os/exec" "path/filepath" "strings" ) // Processor handles content processing using gc-parser type Processor struct { linkBaseURL string scriptPath string } // ProcessResult contains the processed HTML content and extracted table of contents type ProcessResult struct { Content string TableOfContents string HasLaTeX bool HasMusicalNotation bool } // gcParserResult matches the JSON output from gc-parser type gcParserResult struct { Content string `json:"content"` TableOfContents string `json:"tableOfContents"` HasLaTeX bool `json:"hasLaTeX"` HasMusicalNotation bool `json:"hasMusicalNotation"` NostrLinks []interface{} `json:"nostrLinks"` Wikilinks []interface{} `json:"wikilinks"` Hashtags []string `json:"hashtags"` Links []interface{} `json:"links"` Media []string `json:"media"` Error string `json:"error,omitempty"` } // NewProcessor creates a new content processor using gc-parser func NewProcessor(linkBaseURL string) *Processor { // Determine script path relative to the executable // In production, the script should be in the same directory as the binary scriptPath := filepath.Join("scripts", "process-content.js") return &Processor{ linkBaseURL: linkBaseURL, scriptPath: scriptPath, } } // Process converts content (AsciiDoc, Markdown, etc.) to HTML using gc-parser // Returns both the content HTML and the extracted table of contents func (p *Processor) Process(content string) (*ProcessResult, error) { // Check if node is available cmd := exec.Command("node", "--version") if err := cmd.Run(); err != nil { return nil, fmt.Errorf("node.js not found: %w", err) } // Run gc-parser script cmd = exec.Command("node", p.scriptPath, p.linkBaseURL) cmd.Stdin = strings.NewReader(content) var stdout, stderr strings.Builder cmd.Stdout = &stdout cmd.Stderr = &stderr if err := cmd.Run(); err != nil { return nil, fmt.Errorf("gc-parser failed: %w, stderr: %s", err, stderr.String()) } // Parse JSON output var result gcParserResult output := stdout.String() if err := json.Unmarshal([]byte(output), &result); err != nil { return nil, fmt.Errorf("failed to parse gc-parser output: %w, output: %s", err, output) } // Check for error in result if result.Error != "" { return nil, fmt.Errorf("gc-parser error: %s", result.Error) } return &ProcessResult{ Content: result.Content, TableOfContents: result.TableOfContents, HasLaTeX: result.HasLaTeX, HasMusicalNotation: result.HasMusicalNotation, }, nil }