package main import ( _ "embed" "flag" "fmt" "io" "io/ioutil" "os" "regexp" "strings" ) func _main(o opts) error { t, err := ioutil.ReadAll(o.In) if err != nil { return fmt.Errorf("could not read from stdin: %w", err) } // TODO replace imgs linkRE := regexp.MustCompile(`\(LINK ([^ ]+?) (.+?)\)`) linkMatches := linkRE.FindAllSubmatch(t, -1) imgRE := regexp.MustCompile(`\(IMG ([^ ]+?) (.+?)\)`) imgMatches := imgRE.FindAllSubmatch(t, -1) if linkMatches == nil && imgMatches == nil { fmt.Fprintf(o.Out, string(t)) return nil } output := string(t) footer := "" linkIx := 0 for ix, lm := range linkMatches { linkIx = ix rawLink := string(lm[0]) link := string(lm[1]) title := string(lm[2]) switch o.Mode { case "html": output = strings.ReplaceAll(output, rawLink, fmt.Sprintf("%s", link, title)) case "gopher": output = strings.ReplaceAll(output, rawLink, fmt.Sprintf("%s[%d]", title, ix)) linkType := "i" if strings.HasPrefix(link, "http") { linkType = "h" } footer += fmt.Sprintf("%s[%d]: %s %s\n", linkType, ix, title, link) case "gemini": output = strings.ReplaceAll(output, rawLink, fmt.Sprintf("%s[%d]", title, ix)) footer += fmt.Sprintf("=> %s [%d]: %s\n", link, ix, title) } } for ix, im := range imgMatches { linkIx += ix rawImg := string(im[0]) src := string(im[1]) alt := string(im[2]) switch o.Mode { case "html": output = strings.ReplaceAll(output, rawImg, fmt.Sprintf("\"%s\"/", src, alt)) case "gopher": output = strings.ReplaceAll(output, rawImg, fmt.Sprintf("%s[%d]", alt, linkIx)) linkType := "p" footer += fmt.Sprintf("%s[%d]: %s %s\n", linkType, linkIx, alt, src) case "gemini": output = strings.ReplaceAll(output, rawImg, fmt.Sprintf("%s[%d]", alt, linkIx)) footer += fmt.Sprintf("=> %s [%d]: %s\n", src, linkIx, alt) } } if footer != "" { output = output + "\n\n" + footer } fmt.Fprintf(o.Out, output) return nil } type opts struct { In io.Reader Out io.Writer Mode string } func main() { var modeFlag = flag.String("mode", "", "one of html, gopher, gemini.") flag.Parse() if *modeFlag == "" || (*modeFlag != "html" && *modeFlag != "gopher" && *modeFlag != "gemini") { fmt.Fprintln(os.Stderr, "--mode must be specified and one of: html, gopher, gemini") os.Exit(1) } o := opts{ In: os.Stdin, Out: os.Stdout, Mode: *modeFlag, } if err := _main(o); err != nil { fmt.Fprintln(os.Stderr, err.Error()) os.Exit(2) } }