<commit_before>package hck

import (
	"io"

	"golang.org/x/net/html"
)

// index retrieves the index of the first matching node.
// It returns -1 if no match is found.
func index(ns []*Node, m Matcher) int {
	for i := range ns {
		if m.Match(ns[i]) {
			return i
		}
	}
	return -1
}

// splice copies ns, modifies it and retrieves the copy.
// Starting at i, del nodes are replaced with n.
func splice(ns []*Node, i, del int, n ...*Node) []*Node {
	if del < 0 {
		return nil
	}
	dest := make([]*Node, len(ns)+len(n)-del)
	si := i
	di := copy(dest[:si], ns[:si])
	di += del - copy(dest[di:], n)
	di += copy(dest[di:], ns[si:])
	return dest
}

type Siblings []*Node

// Index retrieves the index of the first matching node.
// It returns -1 if no match is found.
func (s Siblings) Index(m Matcher) int {
	return index([]*Node(s), m)
}

// convert nodes to /x/net/html.Node siblings.
// Nils are skipped.
func (s Siblings) convert(parent *html.Node) (first, last *html.Node) {
	var prev *html.Node
	for _, sib := range s {
		if sib == nil {
			continue
		}
		h := sib.convert()
		h.Parent = parent
		h.PrevSibling = prev
		if prev != nil {
			prev.NextSibling = h
		} else {
			first = h
		}
		prev = h
	}
	return first, prev
}

// Render nodes to a writer.
// nil nodes are skipped.
func (s Siblings) Render(w io.Writer) error {
	doc := &html.Node{
		Type: html.DocumentNode,
	}
	first, last := s.convert(doc)
	doc.FirstChild = first
	doc.LastChild = last
	return html.Render(w, doc)
}

func (s Siblings) SplitAfter(n *Node) (Siblings, Siblings) {
	i := s.Index(n) + 1
	return s[:i:i], s[i:]
}

// Node is an alternative to golang.org/x/net/html.Node intended for dom mutation.
// It stores a minimal amount of references that have to be updated on transformations.
type Node struct {
	Children  Siblings
	Namespace string
	Data      string
	Attributes
	Type html.NodeType
}

// Parse a tree from r.
func Parse(r io.Reader) (*Node, error) {
	dom, err := html.Parse(r)
	if err != nil {
		return nil, err
	}
	return Convert(dom), nil
}<commit_msg>mooore api tweaking<commit_after>package hck

import (
	"io"

	"golang.org/x/net/html"
)

// index retrieves the index of the first matching node.
// It returns -1 if no match is found.
func index(ns []*Node, m Matcher) int {
	for i := range ns {
		if m.Match(ns[i]) {
			return i
		}
	}
	return -1
}

// splice copies ns, modifies it and retrieves the copy.
// Starting at i, del nodes are replaced with n.
func splice(ns []*Node, i, del int, n ...*Node) []*Node {
	if del < 0 {
		return nil
	}
	dest := make([]*Node, len(ns)+len(n)-del)
	si := i
	di := copy(dest[:si], ns[:si])
	di += del - copy(dest[di:], n)
	di += copy(dest[di:], ns[si:])
	return dest
}

type Siblings []*Node

// Index retrieves the index of the first matching node.
// It returns -1 if no match is found.
func (s Siblings) Index(m Matcher) int {
	return index([]*Node(s), m)
}

// convert nodes to /x/net/html.Node siblings.
// Nils are skipped.
func (s Siblings) convert(parent *html.Node) (first, last *html.Node) {
	var prev *html.Node
	for _, sib := range s {
		if sib == nil {
			continue
		}
		h := sib.convert()
		h.Parent = parent
		h.PrevSibling = prev
		if prev != nil {
			prev.NextSibling = h
		} else {
			first = h
		}
		prev = h
	}
	return first, prev
}

// Render nodes to a writer.
// nil nodes are skipped.
func (s Siblings) Render(w io.Writer) error {
	doc := &html.Node{
		Type: html.DocumentNode,
	}
	first, last := s.convert(doc)
	doc.FirstChild = first
	doc.LastChild = last
	return html.Render(w, doc)
}

func (s Siblings) SplitAfter(m Matcher) (Siblings, Siblings) {
	i := s.Index(n) + 1
	return s[:i:i], s[i:]
}

func (s Siblings) SplitBefore(m Matcher) (Siblings, Siblings) {
	i := s.Index(n)
	if i < 0 {
		return nil, s
	}
	return s[:i:i], s[i:]
}

// Node is an alternative to golang.org/x/net/html.Node intended for dom mutation.
// It stores a minimal amount of references that have to be updated on transformations.
type Node struct {
	Children  Siblings
	Namespace string
	Data      string
	Attributes
	Type html.NodeType
}

// Parse a tree from r.
func Parse(r io.Reader) (*Node, error) {
	dom, err := html.Parse(r)
	if err != nil {
		return nil, err
	}
	return Convert(dom), nil
}
{'fraction_non_alphanumeric': 0.14437618147448014, 'fraction_numerical': 0.0025992438563327033, 'mean_word_length': 3.04297994269341, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2153177', 'n_tokens_mistral': 1651, 'n_tokens_neox': 1583, 'n_words': 544}