// processNodes generates code from the parsed haml nodes // htmlArray is a string array of the raw html parts. // src is the go source that calls html array, and then user defined code. // usually looks like this: // fmt.Fprint(w, HtmlArray[0]) // fmt.Fprint(w, "Custom string: ", data) // fmt.Fprint(w, HtmlArray[1]) ... func (w *ViewWriter) processNodes() (htmlArray string, src string, patterns string) { htmlBuffer := bytes.NewBuffer(make([]byte, 0)) srcBuffer := bytes.NewBuffer(make([]byte, 0)) patternBuffer := bytes.NewBuffer(make([]byte, 0)) w.processNodes2(formatting.NewIndentingWriter(htmlBuffer), formatting.NewIndentingWriter(srcBuffer), formatting.NewIndentingWriter(patternBuffer)) htmlArray = htmlBuffer.String() src = srcBuffer.String() patterns = patternBuffer.String() return }
func (w *ViewWriter) WriteView() { src := formatting.NewIndentingWriter(w.writer) htmlArr, srcOut := w.processNodes() src.Printf("package %s\n", w.context.pkg) src.Println("") src.Println("// THIS IS A GENERATED FILE, EDITS WILL BE OVERWRITTEN") src.Println("// EDIT THE .haml FILE INSTEAD") src.Println("") src.Println("import (") src.IncrIndent() src.Println("\"fmt\"") src.Println("\"net/http\"") for _, imp := range w.context.imports { src.Printf("%q\n", imp) } src.DecrIndent() src.Println(")") src.Println("") src.Printf("func New%sWriter(data %s) (*%sWriter) {\n", w.destinationName, w.context.dataType, w.destinationName) src.IncrIndent() src.Printf("wr := &%sWriter {\n", w.destinationName) src.IncrIndent() src.Printf("data: data,\n") src.DecrIndent() src.Println("}") src.Println("") src.Println("return wr") src.DecrIndent() src.Println("}") src.Println("") src.Printf("type %sWriter struct {\n", w.destinationName) src.IncrIndent() src.Printf("data %s\n", w.context.dataType) src.DecrIndent() src.Println("}") src.Println("") src.Printf("var %sHtml = [...]string{\n", w.destinationName) src.Println(htmlArr) src.Println("}") src.Println("") src.Printf("func (wr %sWriter) Execute(w http.ResponseWriter, r *http.Request) {\n", w.destinationName) src.IncrIndent() src.Println("wr.ExecuteData(w, r, wr.data)") src.DecrIndent() src.Println("}") src.Println("") src.Printf("func (wr *%sWriter) ExecuteData(w http.ResponseWriter, r *http.Request, data %s) {\n", w.destinationName, w.context.dataType) // output from processNodes // This is calls to htmlArray and code generated Prints src.Print(srcOut) src.Println("}") }
func testFormatStr(s string, expected string, t *testing.T) { vw := NewViewWriter(nil, nil, nil, "") buffer := bytes.NewBuffer(make([]byte, 0)) ind := formatting.NewIndentingWriter(buffer) vw.writeLongText(s, ind) result := buffer.String() if result != expected { t.Error("result not as expected") t.Log(fmt.Sprintf("Expected: [%s]", strings.Replace(expected, " ", "+", -1))) t.Log(fmt.Sprintf("Output: [%s]", strings.Replace(result, " ", "+", -1))) } }
// processNodes generates code from the parsed haml nodes // htmlArray is a string array of the raw html parts. // src is the go source that calls html array, and then user defined code. // usually looks like this: // fmt.Fprint(w, HtmlArray[0]) // fmt.Fprint(w, "Custom string: ", data) // fmt.Fprint(w, HtmlArray[1]) ... func (w *ViewWriter) processNodes() (htmlArray string, src string) { htmlBuffer := bytes.NewBuffer(make([]byte, 0)) htmlWriter := formatting.NewIndentingWriter(htmlBuffer) srcBuffer := bytes.NewBuffer(make([]byte, 0)) srcWriter := formatting.NewIndentingWriter(srcBuffer) // initialise opening quote for htlmArray htmlWriter.Print("`") // initialise starting indent for src srcWriter.IncrIndent() currentHtmlIndex := 0 for n := w.rootNode.children.Front(); n != nil; n = n.Next() { currentHtmlIndex = w.writeNode(n.Value.(*Node), htmlWriter, srcWriter, currentHtmlIndex) } // close quote for html Array htmlWriter.Print("`,") htmlArray = htmlBuffer.String() src = srcBuffer.String() return }
func (w *ViewWriter) WriteView() { src := formatting.NewIndentingWriter(w.writer) htmlArr, srcOut, patterns := w.processNodes() src.Printf("package %s\n", w.context.pkg) src.Println("") src.Println("// THIS IS A GENERATED FILE, EDITS WILL BE OVERWRITTEN") src.Println("// EDIT THE .haml FILE INSTEAD") src.Println("") src.Println("import (") src.IncrIndent() src.Println("\"fmt\"") src.Println("\"html/template\"") src.Println("\"io\"") src.Println("\"os\"") for _, imp := range w.context.imports { src.Printf("%q\n", imp) } src.DecrIndent() src.Println(")") src.Println("") src.Printf("func New%sWriter() (*%sWriter) {\n", w.properViewName, w.properViewName) src.IncrIndent() src.Printf("wr := &%sWriter{\n", w.properViewName) src.Printf(" templates: make([]*template.Template, 0, len(%sTemplatePatterns)),\n", w.viewName) src.Println("}") src.Println("") src.Printf("for idx, pattern := range %sTemplatePatterns {\n", w.viewName) src.IncrIndent() src.Printf("tmpl, err := template.New(\"%sTemplates\" + string(idx)).Parse(pattern)\n", w.viewName) src.Println("if err != nil {") src.IncrIndent() src.Println("fmt.Errorf(\"Could not parse template: %d\", idx)") src.Println("panic(err)") src.DecrIndent() src.Println("}") src.Println("wr.templates = append(wr.templates, tmpl)") src.DecrIndent() src.Println("}") src.Println("return wr") src.DecrIndent() src.Println("}") src.Println("") src.Printf("type %sWriter struct {\n", w.properViewName) src.IncrIndent() src.Println("templates []*template.Template") src.DecrIndent() src.Println("}") src.Println("") src.Printf("var %sHtml = [...]string{\n", w.viewName) src.Println(htmlArr) src.Println("}") src.Println("") src.Printf("var %sTemplatePatterns = []string{\n", w.viewName) src.Print(patterns) src.Println("}") src.Println("") src.Printf("func (wr *%sWriter) Execute(w io.Writer", w.properViewName) for _, name := range w.context.data { typ := w.context.types[name] src.Printf(",\n\t\t\t%s %s", name, typ) } src.Println(") {") src.IncrIndent() src.Printf("var err error = nil\n") // output from processNodes // This is calls to htmlArray and code generated Prints src.Print(srcOut) src.DecrIndent() src.Println("") src.IncrIndent() src.Printf("if err != nil {\n") src.IncrIndent() src.Printf("err = nil\n") src.DecrIndent() src.Println("}") src.DecrIndent() src.Println("}") src.Println("") src.Printf("func handle%sError(err error) {\n", w.properViewName) src.IncrIndent() src.Printf("if err != nil {\n") src.IncrIndent() src.Printf("fmt.Fprintln(os.Stderr, err)\n") src.DecrIndent() src.Println("}") src.DecrIndent() src.Println("}") }