package main

import (
	"Study/src/study/day7Function/HtmlTools"
	"fmt"
	"golang.org/x/net/html"
	"strings"
)

// 在go中 函数也是一类值，类似于int，具体的数值就是int的值
// 和其他值一样，函数也拥有类型，可以赋值给某一个相同类型的变量。
// 也可以作为函数的参数 和返回值被传递。

func Add(x *int)   { *x++ }
func Minus(x *int) { *x-- }

func main() {
	A := Add
	B := Minus
	num := 1
	fmt.Println(num) // 1
	A(&num)
	fmt.Println(num) // 2
	B(&num)
	fmt.Println(num) // 1

	// strings.Map对字符串中的每个字符调用add1函数，
	// 并将每个add1函数的返回值组成一个新的字符串返回给调用者。
	var add1 = func(r rune) rune { return r + 1 }
	fmt.Println(strings.Map(add1, "HAL-9000")) // "IBM.:111"
	fmt.Println(strings.Map(add1, "VMS"))      // "WNT"
	fmt.Println(strings.Map(add1, "Admix"))    // "Benjy"

	// forEachNode针对每个结点x，都会调用pre(x)和post(x)。
	// pre和post都是可选的。
	// 遍历孩子结点之前，pre被调用
	// 遍历孩子结点之后，post被调用
	var forEachNode func(n *html.Node, pre, post func(n *html.Node))
	forEachNode = func(n *html.Node, pre, post func(n *html.Node)) {
		if pre != nil {
			pre(n)
		}
		for c := n.FirstChild; c != nil; c = c.NextSibling {
			forEachNode(c, pre, post)
		}
		if post != nil {
			post(n)
		}
	}

	var depth int
	startElement := func(n *html.Node) {
		if n.Type == html.ElementNode {
			fmt.Printf("%*s<%s>\n", depth*2, "", n.Data)
			depth++
		}
	}
	endElement := func(n *html.Node) {
		if n.Type == html.ElementNode {
			depth--
			fmt.Printf("%*s</%s>\n", depth*2, "", n.Data)
		}
	}
	forEachNode(HtmlTools.GetHtml(), startElement, endElement)

}
