func attributeEscape(w strWriter, s string, escapeEntities, quoted bool) error {
	if quoted {
		if escapeEntities {
			return htmlEscape(w, s)
		}
		return htmlNoEntitiesEscape(w, s)
	}
	last := 0
	for i := 0; i < len(s); i++ {
		var esc string
		switch s[i] {
		case '<':
			esc = "&lt;"
		case '>':
			esc = "&gt;"
		case '&':
			if escapeEntities {
				esc = "&amp;"
			}
		case '\t':
			esc = "&#09;"
		case '\n':
			esc = "&#10;"
		case '\r':
			esc = "&#13;"
		case '\x0C':
			esc = "&#12;"
		case ' ':
			esc = "&#32;"
		case '"':
			esc = "&#34;"
		case '\'':
			esc = "&#39;"
		case '=':
			esc = "&#61;"
		case '`':
			esc = "&#96;"
		}
		if esc == "" {
			continue
		}
		if last != i {
			_, err := w.WriteString(s[last:i])
			if err != nil {
				return err
			}
		}
		_, err := w.WriteString(esc)
		if err != nil {
			return err
		}
		last = i + 1
	}
	if last != len(s) {
		_, err := w.WriteString(s[last:])
		return err
	}
	return nil
}
attributeEscape escapes the string s, so it can be placed inside an HTML
attribute value, and write it to w. If escapeEntities is true it escapes
also the HTML entities. quoted reports whether the attribute is quoted.
package runtime
import (
	"encoding/base64"
	"errors"
	"strings"
)
const hexchars = "0123456789abcdef"
type strWriter interface {
	Write(b []byte) (int, error)
	WriteString(s string) (int, error)
}
func htmlEscape(w strWriter, s string) error {
	last := 0
	for i := 0; i < len(s); i++ {
		var esc string
		switch s[i] {
		case '"':
			esc = "&#34;"
		case '\'':
			esc = "&#39;"
		case '&':
			esc = "&amp;"
		case '<':
			esc = "&lt;"
		case '>':
			esc = "&gt;"
		default:
			continue
		}
		if last != i {
			_, err := w.WriteString(s[last:i])
			if err != nil {
				return err
			}
		}
		_, err := w.WriteString(esc)
		if err != nil {
			return err
		}
		last = i + 1
	}
	if last != len(s) {
		_, err := w.WriteString(s[last:])
		return err
	}
	return nil
}
func htmlNoEntitiesEscape(w strWriter, s string) error {
	last := 0
	for i := 0; i < len(s); i++ {
		var esc string
		switch s[i] {
		case '"':
			esc = "&#34;"
		case '\'':
			esc = "&#39;"
		case '<':
			esc = "&lt;"
		case '>':
			esc = "&gt;"
		default:
			continue
		}
		if last != i {
			_, err := w.WriteString(s[last:i])
			if err != nil {
				return err
			}
		}
		_, err := w.WriteString(esc)
		if err != nil {
			return err
		}
		last = i + 1
	}
	if last != len(s) {
		_, err := w.WriteString(s[last:])
		return err
	}
	return nil
}