Skip to content
yet another css selector library for go
Go Makefile
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
testdata
.gitignore
.travis.yml
LICENSE
Makefile
README.org
css.go
css_test.go
escape.go
escape_test.go
fuzz.go
lex.go
parse.go
selector.go
util.go

README.org

css selectors for go https://travis-ci.org/niklasfasching/css.svg?branch=master

Yet another package implementing a css selector compiler for go - see e.g. github.com/ericchiang/css and github.com/andybalholm/cascadia for prior art.

go get github.com/niklasfasching/css

Differentiating features:

  • Extensible (allows for user defined pseudo-classes/functions, matchers and combinators)
  • Conversion from compiled Selector back to Selector string
  • Small (~800 LOC), simple/modular (separation into lexing, parsing & selecting) and fast (benchmarks put it head to head with cascadia)
import (
	"log"
	"strings"

	"github.com/niklasfasching/css"
	"golang.org/x/net/html"
)

func main() {
	doc, _ := html.Parse(strings.NewReader(`
      <p>
      <span class="a">apple</span>
      <span class="b">banana</span>
      <span class="b">berry</span>
      <span class="c">pear</span>
      </p>
    `))

	selector := css.MustCompile("p > span.b")
	nodes := css.All(selector, doc)
	for _, n := range nodes {
		var s strings.Builder
		html.Render(&s, n)
		log.Println(s.String())
	}
	// <span class="b">banana</span>
	// <span class="b">berry</span>

	log.Printf("Converted back to string: %s", selector) // Converted back to string: p > span.b

	// easy to add your own custom pseudo classes, pseudo functions, matchers & combinators
	css.PseudoClasses["my-pseudo-p"] = func(n *html.Node) bool { return n.Data == "p" },
	selector = css.MustCompile(":my-pseudo-p")
	var s strings.Builder
	html.Render(&s, css.First(selector, doc))
	log.Println(s.String()) // <p>...</p>
}

but why?

for fun

  • It seemed easy enough to do
  • I’ve been really into writing parsers lately and this felt a belt more complicated than a lisp
  • I enjoy web scraping and wanted to learn more about underlying concepts
  • I wanted to learn more about profiling go - and this seemed like a good playground
  • The existing css libraries cannot be extended / customized

resources

You can’t perform that action at this time.