// Command generator generates or re-generates the tutorial chapters. You // should run this command like `go run ./generator`. package main import ( "bufio" "io" "log" "os" "path" "strings" ) // writeString writes a string on the given writer. If there // is a write error, this function will call log.Fatal. func writeString(w io.Writer, s string) { if _, err := io.WriteString(w, s); err != nil { log.Fatal(err) } } // gen1 generates a single file within a chapter. func gen1(destfile io.Writer, filepath string) { srcfile, err := os.Open(filepath) if err != nil { log.Fatal(err) } defer srcfile.Close() scanner := bufio.NewScanner(srcfile) var started bool for scanner.Scan() { line := scanner.Text() trimmed := strings.Trim(line, " \t\r\n") if trimmed == "// -=-=- StopHere -=-=-" { started = false continue } if trimmed == "// -=-=- StartHere -=-=-" { started = true continue } if !started { continue } if strings.HasPrefix(trimmed, "//") { if strings.HasPrefix(trimmed, "// ") { trimmed = trimmed[3:] } else { trimmed = trimmed[2:] } writeString(destfile, trimmed+"\n") continue } writeString(destfile, line+"\n") } if err := scanner.Err(); err != nil { log.Fatal(err) } } // gen generates or re-generates a chapter. The dirpath argument // is the path to the directory that contains a chapter. The files // arguments contains the source file names to process. We will process // files using the specified order. Note that files names are not // paths, just file names, e.g., // // gen("./experiment/torsf/chapter01", "main.go") func gen(dirpath string, files ...string) { readme := path.Join(dirpath, "README.md") destfile, err := os.Create(path.Join(readme)) if err != nil { log.Fatal(err) } defer func() { if err := destfile.Close(); err != nil { log.Fatal(err) } }() for _, file := range files { gen1(destfile, path.Join(dirpath, file)) } } // gentorsf generates the torsf chapters. func gentorsf() { prefix := path.Join(".", "experiment", "torsf") gen(path.Join(prefix, "chapter01"), "main.go") gen(path.Join(prefix, "chapter02"), "main.go", "torsf.go") gen(path.Join(prefix, "chapter03"), "torsf.go") gen(path.Join(prefix, "chapter04"), "torsf.go") } // gennetxlite generates the netxlite chapters. func gennetxlite() { prefix := path.Join(".", "netxlite") gen(path.Join(prefix, "chapter01"), "main.go") gen(path.Join(prefix, "chapter02"), "main.go") gen(path.Join(prefix, "chapter03"), "main.go") gen(path.Join(prefix, "chapter04"), "main.go") gen(path.Join(prefix, "chapter05"), "main.go") gen(path.Join(prefix, "chapter06"), "main.go") gen(path.Join(prefix, "chapter07"), "main.go") gen(path.Join(prefix, "chapter08"), "main.go") } func main() { gentorsf() gennetxlite() }