package main // The two filters: in process for the forge's pages, as programs for cgit. import ( "bytes" "fmt" "html/template" "io" "log" "os" "os/exec" "path" "github.com/yuin/goldmark" ) // Raw HTML is left unrendered, goldmark's default, which is what makes user // text safe to hand it. var markdown = goldmark.New() func renderMarkdown(source string) template.HTML { var buf bytes.Buffer if err := markdown.Convert([]byte(source), &buf); err != nil { log.Printf("markdown: %v", err) return template.HTML(template.HTMLEscapeString(source)) } return template.HTML(buf.String()) } // runMarkdown is the about-filter: markdown on stdin, HTML on stdout. func runMarkdown() int { source, err := io.ReadAll(os.Stdin) if err != nil { fmt.Fprintln(os.Stderr, "md:", err) return 1 } if err := markdown.Convert(source, os.Stdout); err != nil { // A readable page beats an empty one. fmt.Fprintln(os.Stderr, "md:", err) template.HTMLEscape(os.Stdout, source) return 1 } return 0 } // runHighlight is the source-filter: cgit's bundled one issues a command line // the installed highlight refuses, silently. func runHighlight(args []string) int { source, err := io.ReadAll(os.Stdin) if err != nil { fmt.Fprintln(os.Stderr, "highlight:", err) return 1 } name := "source" if len(args) > 0 && args[0] != "" { name = path.Base(args[0]) } // --force: an unknown syntax comes back as escaped text, not as nothing. cmd := exec.Command("highlight", "--fragment", "--force", "--out-format=html", "--syntax-by-name="+name) cmd.Stdin = bytes.NewReader(source) cmd.Stderr = os.Stderr out, err := cmd.Output() if err != nil || len(bytes.TrimSpace(out)) == 0 { if err != nil { fmt.Fprintln(os.Stderr, "highlight:", err) } template.HTMLEscape(os.Stdout, source) return 0 } os.Stdout.Write(out) return 0 }