package main import ( "bytes" "encoding/csv" "fmt" "io" "os" "strings" "text/template" ) func (ctx TemplateContext) render(tmpl string, output io.Writer) error { t, err := template.New("foo").Funcs(ctx.funcMap()).Parse(tmpl) if err != nil { return err } err = t.Execute(output, ctx) if err != nil { return err } return nil } func (ctx TemplateContext) funcMap() template.FuncMap { return template.FuncMap{ "sh": ctx.inline, "shell": ctx.codeBlock, "raw": ctx.raw, "csvToTable": csvToTable, } } func csvToTable(input string) string { r := csv.NewReader(strings.NewReader(input)) records, err := r.ReadAll() if err != nil { return fmt.Sprintf("> Failed to parse CSV: %s\n> Input: %s\n", err.Error(), input) } result := "" if len(records) == 0 { return fmt.Sprintf("Error: records is empty: %s\n", input) } result += "| " + strings.Join(records[0], " | ") + " |\n" result += "|" + strings.Repeat(" --- |", len(records[0])) + "\n" for _, row := range records[1:] { result += "| " + strings.Join(row, " | ") + " |\n" } return result } func (ctx TemplateContext) OutputFile(meta TemplateMeta) (output io.WriteCloser, err error) { if meta.Output == "" { return os.Stdout, nil } tmpl, err := template.New("output").Funcs(ctx.funcMap()).Parse(meta.Output) if err != nil { return nil, fmt.Errorf("Failed to parse output name: %w", err) } var buf bytes.Buffer err = tmpl.Execute(&buf, ctx) if err != nil { return nil, fmt.Errorf("Failed to execute output name: %w", err) } filename := buf.String() fmt.Printf("Saving result to %s\n", filename) file, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644) if err != nil { return nil, fmt.Errorf("Failed to open the file: %w", err) } return file, nil }