1# CSS [![API reference](https://img.shields.io/badge/godoc-reference-5272B4)](https://pkg.go.dev/github.com/tdewolff/parse/v2/css?tab=doc)
  2
  3This package is a CSS3 lexer and parser written in [Go][1]. Both follow the specification at [CSS Syntax Module Level 3](http://www.w3.org/TR/css-syntax-3/). The lexer takes an io.Reader and converts it into tokens until the EOF. The parser returns a parse tree of the full io.Reader input stream, but the low-level `Next` function can be used for stream parsing to returns grammar units until the EOF.
  4
  5## Installation
  6Run the following command
  7
  8	go get -u github.com/tdewolff/parse/v2/css
  9
 10or add the following import and run project with `go get`
 11
 12	import "github.com/tdewolff/parse/v2/css"
 13
 14## Lexer
 15### Usage
 16The following initializes a new Lexer with io.Reader `r`:
 17``` go
 18l := css.NewLexer(parse.NewInput(r))
 19```
 20
 21To tokenize until EOF an error, use:
 22``` go
 23for {
 24	tt, text := l.Next()
 25	switch tt {
 26	case css.ErrorToken:
 27		// error or EOF set in l.Err()
 28		return
 29	// ...
 30	}
 31}
 32```
 33
 34All tokens (see [CSS Syntax Module Level 3](http://www.w3.org/TR/css3-syntax/)):
 35``` go
 36ErrorToken			// non-official token, returned when errors occur
 37IdentToken
 38FunctionToken		// rgb( rgba( ...
 39AtKeywordToken		// @abc
 40HashToken			// #abc
 41StringToken
 42BadStringToken
 43URLToken			// url(
 44BadURLToken
 45DelimToken			// any unmatched character
 46NumberToken			// 5
 47PercentageToken		// 5%
 48DimensionToken		// 5em
 49UnicodeRangeToken
 50IncludeMatchToken	// ~=
 51DashMatchToken		// |=
 52PrefixMatchToken	// ^=
 53SuffixMatchToken	// $=
 54SubstringMatchToken // *=
 55ColumnToken			// ||
 56WhitespaceToken
 57CDOToken 			// <!--
 58CDCToken 			// -->
 59ColonToken
 60SemicolonToken
 61CommaToken
 62BracketToken 		// ( ) [ ] { }, all bracket tokens use this, Data() can distinguish between the brackets
 63CommentToken		// non-official token
 64```
 65
 66### Examples
 67``` go
 68package main
 69
 70import (
 71	"os"
 72
 73	"github.com/tdewolff/parse/v2/css"
 74)
 75
 76// Tokenize CSS3 from stdin.
 77func main() {
 78	l := css.NewLexer(parse.NewInput(os.Stdin))
 79	for {
 80		tt, text := l.Next()
 81		switch tt {
 82		case css.ErrorToken:
 83			if l.Err() != io.EOF {
 84				fmt.Println("Error on line", l.Line(), ":", l.Err())
 85			}
 86			return
 87		case css.IdentToken:
 88			fmt.Println("Identifier", string(text))
 89		case css.NumberToken:
 90			fmt.Println("Number", string(text))
 91		// ...
 92		}
 93	}
 94}
 95```
 96
 97## Parser
 98### Usage
 99The following creates a new Parser.
100``` go
101// true because this is the content of an inline style attribute
102p := css.NewParser(parse.NewInput(bytes.NewBufferString("color: red;")), true)
103```
104
105To iterate over the stylesheet, use:
106``` go
107for {
108    gt, _, data := p.Next()
109    if gt == css.ErrorGrammar {
110        break
111    }
112    // ...
113}
114```
115
116All grammar units returned by `Next`:
117``` go
118ErrorGrammar
119AtRuleGrammar
120EndAtRuleGrammar
121RulesetGrammar
122EndRulesetGrammar
123DeclarationGrammar
124TokenGrammar
125```
126
127### Examples
128``` go
129package main
130
131import (
132	"bytes"
133	"fmt"
134
135	"github.com/tdewolff/parse/v2/css"
136)
137
138func main() {
139	// true because this is the content of an inline style attribute
140	p := css.NewParser(parse.NewInput(bytes.NewBufferString("color: red;")), true)
141	out := ""
142	for {
143		gt, _, data := p.Next()
144		if gt == css.ErrorGrammar {
145			break
146		} else if gt == css.AtRuleGrammar || gt == css.BeginAtRuleGrammar || gt == css.BeginRulesetGrammar || gt == css.DeclarationGrammar {
147			out += string(data)
148			if gt == css.DeclarationGrammar {
149				out += ":"
150			}
151			for _, val := range p.Values() {
152				out += string(val.Data)
153			}
154			if gt == css.BeginAtRuleGrammar || gt == css.BeginRulesetGrammar {
155				out += "{"
156			} else if gt == css.AtRuleGrammar || gt == css.DeclarationGrammar {
157				out += ";"
158			}
159		} else {
160			out += string(data)
161		}
162	}
163	fmt.Println(out)
164}
165```
166
167## License
168Released under the [MIT license](https://github.com/tdewolff/parse/blob/master/LICENSE.md).
169
170[1]: http://golang.org/ "Go Language"