diff --git a/src/award.go b/cmd/mothd/award.go similarity index 100% rename from src/award.go rename to cmd/mothd/award.go diff --git a/src/award_test.go b/cmd/mothd/award_test.go similarity index 100% rename from src/award_test.go rename to cmd/mothd/award_test.go diff --git a/src/handlers.go b/cmd/mothd/handlers.go similarity index 100% rename from src/handlers.go rename to cmd/mothd/handlers.go diff --git a/src/instance.go b/cmd/mothd/instance.go similarity index 100% rename from src/instance.go rename to cmd/mothd/instance.go diff --git a/src/instance_test.go b/cmd/mothd/instance_test.go similarity index 100% rename from src/instance_test.go rename to cmd/mothd/instance_test.go diff --git a/src/maintenance.go b/cmd/mothd/maintenance.go similarity index 100% rename from src/maintenance.go rename to cmd/mothd/maintenance.go diff --git a/src/mothd.go b/cmd/mothd/mothd.go similarity index 100% rename from src/mothd.go rename to cmd/mothd/mothd.go diff --git a/src/zipfs.go b/cmd/mothd/zipfs.go similarity index 100% rename from src/zipfs.go rename to cmd/mothd/zipfs.go diff --git a/src/zipfs_test.go b/cmd/mothd/zipfs_test.go similarity index 100% rename from src/zipfs_test.go rename to cmd/mothd/zipfs_test.go diff --git a/cmd/transpile/main.go b/cmd/transpile/main.go new file mode 100644 index 0000000..3f8b4ea --- /dev/null +++ b/cmd/transpile/main.go @@ -0,0 +1,136 @@ +package main + +import ( + "gopkg.in/russross/blackfriday.v2" + "gopkg.in/yaml.v2" + "bufio" + "bytes" + "flag" + "fmt" + "log" + "io" + "os" + "net/mail" + "strings" +) + +type Header struct { + Pre struct { + Authors []string + } + Answers []string + Post struct { + Objective string + } + Debug struct { + Log []string + Error string + } +} + +type HeaderParser func([]byte) (*Header, error) + +func YamlParser(input []byte) (*Header, error) { + header := new(Header) + + err := yaml.Unmarshal(input, header) + if err != nil { + return nil, err + } + return header, nil +} + +func Rfc822Parser(input []byte) (*Header, error) { + msgBytes := append(input, '\n') + r := bytes.NewReader(msgBytes) + m, err := mail.ReadMessage(r) + if err != nil { + return nil, err + } + + header := new(Header) + for key, val := range m.Header { + key = strings.ToLower(key) + switch key { + case "author": + header.Pre.Authors = val + case "answer": + header.Answers = val + default: + return nil, fmt.Errorf("Unknown header field: %s", key) + } + } + + return header, nil +} + + +func parse(r io.Reader) (error) { + headerEnd := "" + headerBuf := new(bytes.Buffer) + headerParser := Rfc822Parser + + scanner := bufio.NewScanner(r) + lineNo := 0 + for scanner.Scan() { + line := scanner.Text() + lineNo += 1 + if lineNo == 1 { + if line == "---" { + headerParser = YamlParser + headerEnd = "---" + continue + } else { + headerParser = Rfc822Parser + } + } + if line == headerEnd { + break + } + headerBuf.WriteString(line) + headerBuf.WriteRune('\n') + } + + bodyBuf := new(bytes.Buffer) + for scanner.Scan() { + line := scanner.Text() + lineNo += 1 + bodyBuf.WriteString(line) + bodyBuf.WriteRune('\n') + } + + header, err := headerParser(headerBuf.Bytes()) + if err != nil { + return err + } + + headerB, _ := yaml.Marshal(header) + bodyB := blackfriday.Run(bodyBuf.Bytes()) + fmt.Println(string(headerB)) + fmt.Println("") + fmt.Println(string(bodyB)) + + return nil +} + +func main() { + flag.Parse() + + if flag.NArg() < 1 { + fmt.Fprintf(flag.CommandLine.Output(), "Error: no files to parse\n\n") + flag.PrintDefaults() + os.Exit(1) + } + + for _,filename := range flag.Args() { + f, err := os.Open(filename) + if err != nil { + log.Fatal(err) + } + defer f.Close() + + if err := parse(f); err != nil { + log.Fatal(err) + } + } +}