cascadia

package module
v1.3.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 18, 2023 License: BSD-2-Clause Imports: 8 Imported by: 389

README

cascadia

The Cascadia package implements CSS selectors for use with the parse trees produced by the html package.

To test CSS selectors without writing Go code, check out cascadia the command line tool, a thin wrapper around this package.

Refer to godoc here.

Example

The following is an example of how you can use Cascadia.

package main

import (
	"fmt"
	"log"
	"strings"

	"github.com/andybalholm/cascadia"
	"golang.org/x/net/html"
)

var pricingHtml string = `
<div class="card mb-4 box-shadow">
	<div class="card-header">
		<h4 class="my-0 font-weight-normal">Free</h4>
	</div>
	<div class="card-body">
		<h1 class="card-title pricing-card-title">$0/mo</h1>
		<ul class="list-unstyled mt-3 mb-4">
			<li>10 users included</li>
			<li>2 GB of storage</li>
			<li><a href="https://example.com">See more</a></li>
		</ul>
	</div>
</div>

<div class="card mb-4 box-shadow">
	<div class="card-header">
		<h4 class="my-0 font-weight-normal">Pro</h4>
	</div>
	<div class="card-body">
		<h1 class="card-title pricing-card-title">$15/mo</h1>
		<ul class="list-unstyled mt-3 mb-4">
			<li>20 users included</li>
			<li>10 GB of storage</li>
			<li><a href="https://example.com">See more</a></li>
		</ul>
	</div>
</div>

<div class="card mb-4 box-shadow">
	<div class="card-header">
		<h4 class="my-0 font-weight-normal">Enterprise</h4>
	</div>
	<div class="card-body">
		<h1 class="card-title pricing-card-title">$29/mo</h1>
		<ul class="list-unstyled mt-3 mb-4">
			<li>30 users included</li>
			<li>15 GB of storage</li>
			<li><a>See more</a></li>
		</ul>
	</div>
</div>
`

func Query(n *html.Node, query string) *html.Node {
	sel, err := cascadia.Parse(query)
	if err != nil {
		return &html.Node{}
	}
	return cascadia.Query(n, sel)
}

func QueryAll(n *html.Node, query string) []*html.Node {
	sel, err := cascadia.Parse(query)
	if err != nil {
		return []*html.Node{}
	}
	return cascadia.QueryAll(n, sel)
}

func AttrOr(n *html.Node, attrName, or string) string {
	for _, a := range n.Attr {
		if a.Key == attrName {
			return a.Val
		}
	}
	return or
}

func main() {
	doc, err := html.Parse(strings.NewReader(pricingHtml))
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("List of pricing plans:\n\n")
	for i, p := range QueryAll(doc, "div.card.mb-4.box-shadow") {
		planName := Query(p, "h4").FirstChild.Data
		price := Query(p, ".pricing-card-title").FirstChild.Data
		usersIncluded := Query(p, "li:first-child").FirstChild.Data
		storage := Query(p, "li:nth-child(2)").FirstChild.Data
		detailsUrl := AttrOr(Query(p, "li:last-child a"), "href", "(No link available)")
		fmt.Printf(
			"Plan #%d\nName: %s\nPrice: %s\nUsers: %s\nStorage: %s\nDetails: %s\n\n",
			i+1,
			planName,
			price,
			usersIncluded,
			storage,
			detailsUrl,
		)
	}
}

The output is:

List of pricing plans:

Plan #1
Name: Free
Price: $0/mo
Users: 10 users included
Storage: 2 GB of storage
Details: https://example.com

Plan #2
Name: Pro
Price: $15/mo
Users: 20 users included
Storage: 10 GB of storage
Details: https://example.com

Plan #3
Name: Enterprise
Price: $29/mo
Users: 30 users included
Storage: 15 GB of storage
Details: (No link available)

Documentation

Overview

Package cascadia is an implementation of CSS selectors.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Filter added in v1.1.0

func Filter(nodes []*html.Node, m Matcher) (result []*html.Node)

Filter returns the nodes that match m.

func Query added in v1.1.0

func Query(n *html.Node, m Matcher) *html.Node

Query returns the first node that matches m, from the descendants of n. If none matches, it returns nil.

func QueryAll added in v1.1.0

func QueryAll(n *html.Node, m Matcher) []*html.Node

QueryAll returns a slice of all the nodes that match m, from the descendants of n.

Types

type Matcher added in v1.1.0

type Matcher interface {
	Match(n *html.Node) bool
}

Matcher is the interface for basic selector functionality. Match returns whether a selector matches n.

type Sel added in v1.1.0

type Sel interface {
	Matcher
	Specificity() Specificity

	// Returns a CSS input compiling to this selector.
	String() string

	// Returns a pseudo-element, or an empty string.
	PseudoElement() string
}

Sel is the interface for all the functionality provided by selectors.

func Parse added in v1.1.0

func Parse(sel string) (Sel, error)

Parse parses a selector. Use `ParseWithPseudoElement` if you need support for pseudo-elements.

func ParseWithPseudoElement added in v1.2.0

func ParseWithPseudoElement(sel string) (Sel, error)

ParseWithPseudoElement parses a single selector, with support for pseudo-element.

type Selector

type Selector func(*html.Node) bool

A Selector is a function which tells whether a node matches or not.

This type is maintained for compatibility; I recommend using the newer and more idiomatic interfaces Sel and Matcher.

func Compile

func Compile(sel string) (Selector, error)

Compile parses a selector and returns, if successful, a Selector object that can be used to match against html.Node objects.

func MustCompile

func MustCompile(sel string) Selector

MustCompile is like Compile, but panics instead of returning an error.

func (Selector) Filter

func (s Selector) Filter(nodes []*html.Node) (result []*html.Node)

Filter returns the nodes in nodes that match the selector.

func (Selector) Match

func (s Selector) Match(n *html.Node) bool

Match returns true if the node matches the selector.

func (Selector) MatchAll

func (s Selector) MatchAll(n *html.Node) []*html.Node

MatchAll returns a slice of the nodes that match the selector, from n and its children.

func (Selector) MatchFirst

func (s Selector) MatchFirst(n *html.Node) *html.Node

MatchFirst returns the first node that matches s, from n and its children.

type SelectorGroup added in v1.1.0

type SelectorGroup []Sel

A SelectorGroup is a list of selectors, which matches if any of the individual selectors matches.

func ParseGroup added in v1.1.0

func ParseGroup(sel string) (SelectorGroup, error)

ParseGroup parses a selector, or a group of selectors separated by commas. Use `ParseGroupWithPseudoElements` if you need support for pseudo-elements.

func ParseGroupWithPseudoElements added in v1.2.0

func ParseGroupWithPseudoElements(sel string) (SelectorGroup, error)

ParseGroupWithPseudoElements parses a selector, or a group of selectors separated by commas. It supports pseudo-elements.

func (SelectorGroup) Match added in v1.1.0

func (s SelectorGroup) Match(n *html.Node) bool

Match returns true if the node matches one of the single selectors.

func (SelectorGroup) String added in v1.2.0

func (c SelectorGroup) String() string

type Specificity added in v1.1.0

type Specificity [3]int

Specificity is the CSS specificity as defined in https://www.w3.org/TR/selectors/#specificity-rules with the convention Specificity = [A,B,C].

func (Specificity) Add added in v1.1.0

func (s Specificity) Add(other Specificity) Specificity

func (Specificity) Less added in v1.1.0

func (s Specificity) Less(other Specificity) bool

returns `true` if s < other (strictly), false otherwise

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL