func (p *Policy) sanitize(r io.Reader) *bytes.Buffer {
	p.init()
	var (
		buff                     bytes.Buffer
		skipElementContent       bool
		skippingElementsCount    int64
		skipClosingTag           bool
		closingTagToSkipStack    []string
		mostRecentlyStartedToken string
	)
	tokenizer := html.NewTokenizer(r)
	for {
		if tokenizer.Next() == html.ErrorToken {
			err := tokenizer.Err()
			if err == io.EOF {
				return &buff
			}
			return &bytes.Buffer{}
		}
		token := tokenizer.Token()
		switch token.Type {
		case html.DoctypeToken:
		case html.CommentToken:
		case html.StartTagToken:
			mostRecentlyStartedToken = token.Data
			aps, ok := p.elsAndAttrs[token.Data]
			if !ok {
				if _, ok := p.setOfElementsToSkipContent[token.Data]; ok {
					skipElementContent = true
					skippingElementsCount++
				}
				if p.addSpaces {
					buff.WriteString(" ")
				}
				break
			}
			if len(token.Attr) != 0 {
				token.Attr = p.sanitizeAttrs(token.Data, token.Attr, aps)
			}
			if len(token.Attr) == 0 {
				if !p.allowNoAttrs(token.Data) {
					skipClosingTag = true
					closingTagToSkipStack = append(closingTagToSkipStack, token.Data)
					if p.addSpaces {
						buff.WriteString(" ")
					}
					break
				}
			}
			if !skipElementContent {
				buff.WriteString(token.String())
			}
		case html.EndTagToken:
			if mostRecentlyStartedToken == token.Data {
				mostRecentlyStartedToken = ""
			}
			if skipClosingTag && closingTagToSkipStack[len(closingTagToSkipStack)-1] == token.Data {
				closingTagToSkipStack = closingTagToSkipStack[:len(closingTagToSkipStack)-1]
				if len(closingTagToSkipStack) == 0 {
					skipClosingTag = false
				}
				if p.addSpaces {
					buff.WriteString(" ")
				}
				break
			}
			if _, ok := p.elsAndAttrs[token.Data]; !ok {
				if _, ok := p.setOfElementsToSkipContent[token.Data]; ok {
					skippingElementsCount--
					if skippingElementsCount == 0 {
						skipElementContent = false
					}
				}
				if p.addSpaces {
					buff.WriteString(" ")
				}
				break
			}
			if !skipElementContent {
				buff.WriteString(token.String())
			}
		case html.SelfClosingTagToken:
			aps, ok := p.elsAndAttrs[token.Data]
			if !ok {
				if p.addSpaces {
					buff.WriteString(" ")
				}
				break
			}
			if len(token.Attr) != 0 {
				token.Attr = p.sanitizeAttrs(token.Data, token.Attr, aps)
			}
			if len(token.Attr) == 0 && !p.allowNoAttrs(token.Data) {
				if p.addSpaces {
					buff.WriteString(" ")
				}
				break
			}
			if !skipElementContent {
				buff.WriteString(token.String())
			}
		case html.TextToken:
			if !skipElementContent {
				switch mostRecentlyStartedToken {
				case "script":
					buff.WriteString(token.Data)
				case "style":
					buff.WriteString(token.Data)
				default:
					buff.WriteString(token.String())
				}
			}
		default:
			return &bytes.Buffer{}
		}
	}
}
Performs the actual sanitization process.
package bluemonday
import (
	"bytes"
	"io"
	"net/url"
	"regexp"
	"strings"
	"golang.org/x/net/html"
)
var (
	dataAttribute             = regexp.MustCompile("^data-.+")
	dataAttributeXMLPrefix    = regexp.MustCompile("^xml.+")
	dataAttributeInvalidChars = regexp.MustCompile("[A-Z;]+")
)
func (p *Policy) Sanitize(s string) string {
	if strings.TrimSpace(s) == "" {
		return s
	}
	return p.sanitize(strings.NewReader(s)).String()
}
func (p *Policy) SanitizeBytes(b []byte) []byte {
	if len(bytes.TrimSpace(b)) == 0 {
		return b
	}
	return p.sanitize(bytes.NewReader(b)).Bytes()
}
func (p *Policy) SanitizeReader(r io.Reader) *bytes.Buffer {
	return p.sanitize(r)
}