cascadia

package module
v1.3.3 Latest Latest
Warning

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

Go to latest
Published: Feb 20, 2024 License: BSD-2-Clause Imports: 8 Imported by: 1

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

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

Filter returns the nodes that match m.

func Query

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

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

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

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

func Parse(sel string) (Sel, error)

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

func ParseWithPseudoElement

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

type SelectorGroup []Sel

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

func ParseGroup

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

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

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

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

func (SelectorGroup) String

func (c SelectorGroup) String() string

type Specificity

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

func (s Specificity) Add(other Specificity) Specificity

func (Specificity) Less

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