func (d *defineVariable) String() string {
	typeOfVar := "local"
	if d.global {
		typeOfVar = "global"
	}
	return fmt.Sprintf("[Define Variable] %v %v to '%v'", typeOfVar, d.name, d.expression)
}
String returns a text description fo the instruction
package tal
import (
	"fmt"
	"golang.org/x/net/html"
	"io"
	"strings"
)
type RenderConfig func(t *Template, rc *renderContext)
func RenderDebugLogging(logger func(fmt string, args ...interface{})) RenderConfig {
	return func(t *Template, rc *renderContext) {
		rc.talesContext.debug = logger
		rc.debug = logger
	}
}
type attributesList []html.Attribute
func (a *attributesList) Remove(name string) bool {
	curList := *a
	for i, att := range curList {
		if att.Key == name {
			res := append(curList[:i], curList[i+1:]...)
			*a = res
			return true
		}
	}
	return false
}
func (a *attributesList) Set(name string, value string) bool {
	curList := *a
	for i, att := range curList {
		if att.Key == name {
			curList[i].Val = value
			return true
		}
	}
	res := append(curList, html.Attribute{Key: name, Val: value})
	*a = res
	return false
}
func (a *attributesList) Get(name string) interface{} {
	curList := *a
	for _, att := range curList {
		if att.Key == name {
			return att.Val
		}
	}
	return notFound
}
type templateInstruction interface {
	render(*renderContext) error
}
type defineSlot struct {
	name string
	endTagOffset int
}
func (d *defineSlot) render(rc *renderContext) error {
	slotFilling, ok := rc.slots.GetValue(d.name)
	if ok {
		slotFillingTemplate := slotFilling.(*Template)
		err := slotFillingTemplate.renderAsSubtemplate(rc.talesContext, rc.out, rc.slots, rc.config...)
		rc.instructionPointer += d.endTagOffset
		return err
	}
	return nil
}
func (d *defineSlot) String() string {
	return fmt.Sprintf("[Define Slot] %v (end offset %v)", d.name, d.endTagOffset)
}
type useMacro struct {
	expression string
	originalAttributes attributesList
	endTagOffset int
	filledSlots map[string]*Template
}
func (u *useMacro) render(rc *renderContext) error {
	contextValue := rc.talesContext.evaluate(u.expression, u.originalAttributes)
	if contextValue == Default {
		return nil
	}
	if contextValue == nil {
		rc.instructionPointer += u.endTagOffset
		return nil
	}
	mv, ok := contextValue.(*Template)
	if ok {
		rc.slots.SaveAll()
		for k, v := range u.filledSlots {
			rc.slots.SetValue(k, v)
		}
		err := mv.renderAsSubtemplate(rc.talesContext, rc.out, rc.slots, rc.config...)
		rc.slots.RestoreAll()
		rc.instructionPointer += u.endTagOffset
		return err
	}
	return nil
}
func (u *useMacro) String() string {
	return fmt.Sprintf("[Use Macro] %v", u.expression)
}
type renderEndTag struct {
	tagName []byte
	checkOmitTagFlag bool
}
func (d *renderEndTag) render(rc *renderContext) error {
	render := true
	if d.checkOmitTagFlag {
		rc.debug("Checking omit tag flag\n")
		render = !rc.getOmitTagFlag()
	}
	if render {
		rc.debug("End Tag will be rendered\n")
		rc.buffer.reset()
		rc.buffer.appendString("</")
		rc.buffer.append(d.tagName)
		rc.buffer.appendString(">")
		rc.out.Write(rc.buffer)
	} else {
		rc.debug("Rendering of end tag suppressed.\n")
	}
	return nil
}
func (d *renderEndTag) String() string {
	return fmt.Sprintf("[End Tag] %v (check omit flag: %v)", string(d.tagName), d.checkOmitTagFlag)
}
type defineVariable struct {
	name string
	global bool
	expression string
	originalAttributes attributesList
}
func (d *defineVariable) render(rc *renderContext) error {
	contextValue := rc.talesContext.evaluate(d.expression, d.originalAttributes)
	if d.global {
		rc.talesContext.globalVariables.SetValue(d.name, contextValue)
	} else {
		rc.talesContext.localVariables.AddValue(d.name, contextValue)
	}
	return nil
}