package beer import ( "bytes" "errors" "text/template" ) const lyrics = `{{define "verse" -}} {{template "Plural" .N}} of beer on the wall, {{template "plural" .N}} of beer. {{if eq .N 0}}Go to the store and buy some more {{- else}}Take {{if eq .N 1}}it{{else}}one{{end}} down and pass it around {{- end}}, {{template "plural" .M}} of beer on the wall. {{end}} {{define "plural"}}{{if eq . 0}}no more{{else}}{{.}} {{- end}} bottle{{if ne . 1}}s{{end}}{{end}} {{define "Plural"}}{{if eq . 0}}No more{{else}}{{.}} {{- end}} bottle{{if ne . 1}}s{{end}}{{end}}` var tmpl = template.Must(template.New("song").Parse(lyrics)) type Bottles struct { N, M int } func Verse(n int) (string, error) { if n < 0 || n > 99 { return "", errors.New("Go home, you're drunk") } buf := &bytes.Buffer{} err := tmpl.ExecuteTemplate(buf, "verse", Bottles{n, (100 + n - 1) % 100}) return buf.String(), err } func Verses(from, to int) (string, error) { if from <= to { return "", errors.New("Wrong order") } var s string for i := from; i >= to; i-- { v, err := Verse(i) if err != nil { return "", err } s += v + "\n" } return s, nil } func Song() string { s, err := Verses(99, 0) if err != nil { panic(err) } return s }