func (e *Element) writeChildren(bf *bytes.Buffer, stringTemplates map[string]string) error {
	for _, child := range e.Children {
		err := child.Html(bf, stringTemplates)
		if err != nil {
			return err
		}
	}
	return nil
}
writeChildren writes the element's children's HTML.
package gold
import (
	"bytes"
	"errors"
	"fmt"
	"strings"
)
const (
	TypeTag               = "tag"
	TypeContent           = "content"
	TypeBlock             = "block"
	TypeExpression        = "expression"
	TypeLiteral           = "literal"
	TypeInclude           = "include"
	TypeOutputExpression  = "outputExpression"
	IncludeParaStartIndex = 2
)
var (
	doctypes = map[string]string{
		"html":         "<!DOCTYPE html>",
		"xml":          "<?xml version=\"1.0\" encoding=\"utf-8\" ?>",
		"transitional": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">",
		"strict":       "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">",
		"frameset":     "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">",
		"1.1":          "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">",
		"basic":        "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML Basic 1.1//EN\" \"http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd\">",
		"mobile":       "<!DOCTYPE html PUBLIC \"-//WAPFORUM//DTD XHTML Mobile 1.2//EN\" \"http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd\">",
	}
)
type Element struct {
	Text             string
	Tokens           []string
	LineNo           int
	Indent           int
	Parent           *Element
	Children         []*Element
	Tag              string
	Attributes       map[string]string
	SingleAttributes []string
	Id               string
	Classes          []string
	TextValues       []string
	Type             string
	Template         *Template
	Block            *Block
	RawContent       bool
}
func (e *Element) parse() error {
	if e.hasNoTokens() {
		return errors.New(fmt.Sprintf("The element has no tokens. (line no: %d)", e.LineNo))
	}
	switch {
	case e.Type == TypeContent || e.Type == TypeBlock || e.Type == TypeExpression || e.Type == TypeLiteral || e.Type == TypeInclude || e.Type == TypeOutputExpression || e.comment():
	default:
		for i, token := range e.Tokens {
			switch {
			case i == 0:
				if err := e.parseFirstToken(token); err != nil {
					return err
				}
			case e.hasTextValues():
				e.appendTextValue(token)
			case attribute(token):
				e.appendAttribute(token)
			case singleAttribute(token):
				e.appendSingleAttribute(token)
			default:
				e.appendTextValue(token)
			}
		}
	}
	return nil
}
func (e *Element) hasNoTokens() bool {
	return len(e.Tokens) == 0
}
func (e *Element) hasTextValues() bool {
	return len(e.TextValues) > 0
}
func (e *Element) parseFirstToken(token string) error {
	switch token {
	case "javascript:":
		e.setTag("script")
		e.appendAttribute("type=text/javascript")
	default:
		if err := e.setTag(token); err != nil {
			return err
		}
	}
	return nil
}
func (e *Element) setTag(token string) error {
	tag := strings.Split(strings.Split(token, "#")[0], ".")[0]
	if tag == "" {
		tag = "div"
	}
	e.Tag = tag
	err := e.setIdFromToken(token)
	if err != nil {
		return err
	}
	e.appendClassesFromToken(token)
	if e.Tag == "script" || e.Tag == "style" || strings.HasSuffix(token, ".") {
		e.RawContent = true
	}
	return nil
}
func (e *Element) setIdFromToken(token string) error {
	parts := strings.Split(token, "#")
	switch len(parts) {
	case 1:
	case 2:
		e.setId(strings.Split(parts[1], ".")[0])
	default:
		return e.multipleIdsError()
	}
	return nil
}
func (e *Element) setId(id string) error {
	if e.Id != "" {
		return e.multipleIdsError()
	}
	e.Id = id
	return nil
}
func (e *Element) multipleIdsError() error {
	return errors.New(fmt.Sprintf("The number of the element id has to be one. (line no: %d)", e.LineNo))
}
func (e *Element) appendClassesFromToken(token string) {
	for i, part := range strings.Split(token, ".") {
		if i == 0 {
			continue
		}
		e.appendClass(strings.Split(part, "#")[0])
	}
}
func (e *Element) appendClass(class string) {
	if class != "" {
		e.Classes = append(e.Classes, class)
	}
}
func (e *Element) appendTextValue(token string) {
	e.TextValues = append(e.TextValues, token)
}
func (e *Element) appendAttribute(token string) {
	kv := strings.Split(token, "=")
	if len(kv) < 2 {
		return
	}
	k := kv[0]
	v := parseValue(strings.Join(kv[1:], "="))
	switch k {
	case "id":
		e.setId(v)
	case "class":
		e.appendClass(v)
	default:
		e.Attributes[k] = v
	}
}
func (e *Element) appendSingleAttribute(token string) {
	e.SingleAttributes = append(e.SingleAttributes, strings.TrimSuffix(strings.TrimPrefix(token, "["), "]"))
}
func (e *Element) AppendChild(child *Element) {
	e.Children = append(e.Children, child)
}
func (e *Element) Html(bf *bytes.Buffer, stringTemplates map[string]string) error {
	switch {
	case e.comment():
	case e.Type == TypeContent || e.Type == TypeExpression || e.Type == TypeOutputExpression:
		g := e.getGenerator()
		if e.Type == TypeOutputExpression {
			bf.WriteString(g.delimLeft + strings.Join(e.Tokens[1:], " ") + g.delimRight)
		} else {
			e.writeText(bf)
		}
		for _, child := range e.Children {
			err := child.Html(bf, stringTemplates)
			if err != nil {
				return err
			}
		}
	case e.Type == TypeLiteral:
		e.writeLiteralValue(bf)
	case e.Type == TypeBlock:
		if len(e.Tokens) < 2 {
			return errors.New(fmt.Sprintf("The block element does not have a name. (line no: %d)", e.LineNo))
		}
		name := e.Tokens[1]
		sub := e.getTemplate().Sub
		if sub == nil {
			if err := e.writeChildren(bf, stringTemplates); err != nil {
				return err
			}
			return nil
		}
		block := sub.Blocks[name]
		if block == nil {
			if err := e.writeChildren(bf, stringTemplates); err != nil {
				return err
			}
			return nil
		}
		block.Html(bf, stringTemplates)
	case e.Type == TypeInclude:
		if len(e.Tokens) < 2 {
			return errors.New(fmt.Sprintf("The include element does not have a path. (line no: %d)", e.LineNo))
		}
		tpl := e.getTemplate()
		incTplPath := e.Tokens[1]
		g := tpl.Generator
		var incTpl *Template
		var err error
		if stringTemplates == nil {
			addBaseDir := true
			if g.baseDir != "" && CurrentDirectoryBasedPath(incTplPath) {
				incTplPath = tpl.Dir() + incTplPath
				addBaseDir = false
			}
			incTpl, err = g.parse(incTplPath+Extension, nil, addBaseDir)
		} else {
			incTpl, err = g.parse(incTplPath, stringTemplates, false)
		}
		if err != nil {
			return err
		}
		embedMap, err := NewEmbedMap(e.Tokens[IncludeParaStartIndex:])
		if err != nil {
			return err
		}
		incHtml, err := incTpl.Html(stringTemplates, embedMap)
		if err != nil {
			return err
		}
		bf.WriteString(incHtml)
	default:
		e.writeOpenTag(bf)
		if e.hasTextValues() {
			e.writeTextValue(bf)
		}
		if err := e.writeChildren(bf, stringTemplates); err != nil {
			return err
		}
		e.writeCloseTag(bf)
	}
	return nil
}