package main import ( "strings" "bytes" "os" "fmt" "bufio" "regexp" "flag" ) var outFile bytes.Buffer func errorExit(e error, msg string) { if e != nil { fmt.Print(msg) os.Exit(1) } } func buildComment(ln string, eof bool) string { var out strings.Builder if eof && ln == "" { return out.String() } out.Grow(20 + len(ln)) out.WriteString("i") out.WriteString(strings.TrimRight(ln, "\n\r")) out.WriteString("\tfalse\tnull.host\t1") if !eof { out.WriteString("\n") } return out.String() } func deconstructComment(ln string) string { text := strings.SplitN(ln, "\t", 2) comment := text[0] if len(comment) > 1 { return comment[1:] + "\n" } return "\n" } func readFile(path string, buildComments bool) { file, err := os.Open(path) errorExit(err, fmt.Sprintf("Unable to open file for reading: %s", path)) defer file.Close() re := regexp.MustCompile(`.+\t.*\t.*\t.*`) reader := bufio.NewReader(file) if buildComments { for { l, e := reader.ReadString('\n') eof := e != nil if exp := re.MatchString(l); exp { outFile.WriteString(l) } else { outFile.WriteString(buildComment(l, eof)) } if eof { break } } } else { for { l, e := reader.ReadString('\n') if exp := re.MatchString(l); exp && l[0] == 'i' { outFile.WriteString(deconstructComment(l)) } else { outFile.WriteString(l) } if e != nil { break } } } } func writeFile(path string) { file, err := os.OpenFile(path, os.O_WRONLY | os.O_CREATE | os.O_TRUNC, 0) errorExit(err, fmt.Sprintf("Unable to open file for writing: %s", path)) defer file.Close() file.Write(outFile.Bytes()) } func PrintHelp() { art := `gfu - gophermap formatting utility syntax: gfu [flags...] [filepath] example: gfu -d ~/gopher/phlog/gophermap default convert plain text lines to type 'i' ` fmt.Fprint(os.Stderr, art) flag.PrintDefaults() } func main() { deconstructCommentLinks := flag.Bool("d", false, "Deconstruct a gophermap's comments back to regular text") header := flag.String("head","","Path to a file containing header content") footer := flag.String("foot","","Path to a file containing footer content") flag.Usage = PrintHelp flag.Parse() args := flag.Args() if l := len(args); l != 1 { fmt.Printf("Incorrect number of arguments. Expected 1, got %d", l) os.Exit(1) } if *header != "" { fmt.Println("Header functionality is not built yet, proceeding with general gophermap conversion...") } if *footer != "" { fmt.Println("Footer functionality is not built yet, proceeding with general gophermap conversion...") } readFile(args[0], !*deconstructCommentLinks) writeFile(args[0]) os.Exit(0) }