123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- package style
- import "github.com/yhirose/go-peg"
- import "fmt"
- import "os"
- import "io/ioutil"
- import "errors"
- const CSS1PEG =
- `
- # CSS1 parser for a PEG parser generator.
- # and a user command parser
- # Doesn't support import statements.
- STYLESHEET ← (CDO / CDC)* (RULESET/DECLARATIONS/COMMENT/ATRULE)* (CDO / CDC)*
- RULESET ← SELECTORS "{" DECLARATIONS? "}"
- SELECTORS ← SELECTOR ("," SELECTOR)*
- SELECTOR ← ( "*" / NAME ID? CLASS? PSEUDO_CLASS? /
- ID CLASS? PSEUDO_CLASS? /
- CLASS PSEUDO_CLASS? /
- PSEUDO_CLASS )+ PSEUDO_ELEMENT* / PSEUDO_ELEMENT
- ATRULE ← ATID (STRING / URL) ";" / ATID "{" DECLARATIONS "}"
- NAME ← <IDENT>
- DECLARATIONS ← DECLARATION (';' DECLARATION)* ';'?
- DECLARATION ← NAME ":" EXPR PRIO? / COMMENT
- OPERATOR ← '/' / ','
- # UNARY_OPERATOR ← '-' / '+'
- PRIO ← IMPORTANT
- EXPR ← TERM (OPERATOR TERM)*
- TERM ← STRING / PERCENTAGE / LENGTH / HEXCOLOR / URL / RGB / NUM / IDENT
- ~COMMENT ← "/*" (!("*/").)* "*/"
- ATID ← < "@" [a-zA-Z][-_a-zA-Z0-9]+ >
- IMPORTANT ← < "!" WS "important" >
- IDENT ← < [-_a-zA-Z][-_a-zA-Z0-9]* >
- PERCENTAGE ← < NUM > "%"
- NUM ← < [+-]*[0-9]+ / [0-9]* "." [0-9]+ >
- LENGTH ← NUM UNIT
- UNIT ← <"pt" / "mm" / "pt" / "in" / "px" / "em" / "ex" >
- PSEUDO_ELEMENT ← <":first-letter" / ":first-line" >
- PSEUDO_CLASS ← <":hover" / ":link" / ":mark" / ":active" / ":visited" >
- HEXCOLOR ← "#" < ([0-9a-fA-F])+ >
- ID ← "#" < IDENT >
- CLASS ← "." < IDENT >
- # Raw string macro.
- RAWSM(O,C) ← O < (!(C).)* > C
- # Escaped string macro.
- ESCSM(O,C) ← O < (!(C)STRCHAR)* > C
- # String escapes
- STRESC1 ← "\\" [nrtfv\'\\"\[\]\\]
- STRESC2 ← "\\" [0-3] [0-7] [0-7]
- STRESC3 ← "\\" [0-7] [0-7]*
- STRESC4 ← "\\x" [0-9a-fA-F] [0-9a-fA-F]?
- STRESC5 ← "\\u" [0-9a-fA-F]+
- STRNOESC ← (!('\\\\').)
- STRCHAR ← STRESC1 / STRESC2 / STRESC3 / STRESC4 / STRESC5 / STRNOESC
- # Strings
- STRING ← ESCSM("\"", "\"") / ESCSM("'", "'")
- URL ← "url(" STRING ")"
- RGB ← < "rgb("[ \t]*[0-9]+[ \t]* "," [ \t]*[0-9]+[ \t]* "," [ \t]*[0-9]+[ \t]* ")" >
- ~WS ← [ \t\n\r]*
- CDO ← "<!--"
- CDC ← "-->"
- %whitespace ← [ \t\n\r]*
- `
- type CSS1Parser struct {
- *peg.Parser
- }
- type CSS1Result struct {
- * peg.Ast
- }
- func parserCheck(err error) {
- if perr, ok := err.(*peg.Error); ok {
- for _, d := range perr.Details {
- fmt.Println(d)
- }
- os.Exit(1)
- }
- }
- /** Creates a CS1 PEG parser. */
- func NewCSS1Parser() (*CSS1Parser, error) {
- result := &CSS1Parser{}
- var err error
- result.Parser, err = peg.NewParser(CSS1PEG)
- if err == nil {
- result.EnableAst()
- }
- return result, err
- }
- var defaultCSS1Parser * CSS1Parser
- func InitDefaultParser() error {
- var err error
- defaultCSS1Parser, err = NewCSS1Parser()
- return err
- }
- func wrapResult(wrapme peg.Any) *CSS1Result {
- result := &CSS1Result{};
- ast, ok := wrapme.(*peg.Ast)
- if ok {
- result.Ast = ast
- return result
- }
- return nil
- }
- func (parser CSS1Parser) Parse(source string) (*CSS1Result, error) {
- ast, err := parser.ParseAndGetValue(source, nil)
- return wrapResult(ast), err
- }
- func (parser CSS1Parser) ParseFile(filename string) (*CSS1Result, error) {
- source, err := ioutil.ReadFile(filename)
- if err == nil {
- return parser.Parse(string(source))
- } else {
- return nil, err
- }
- }
- func (css1 CSS1Result) InitializeTheme(theme * Theme) {
- }
- func parse(source string) (*CSS1Result, error) {
- if defaultCSS1Parser == nil {
- return nil, errors.New("Default parser not initialized!")
- }
- return defaultCSS1Parser.Parse(source)
- }
- func parseFile(filename string) (*CSS1Result, error) {
- if defaultCSS1Parser == nil {
- return nil, errors.New("Default parser not initialized!")
- }
- return defaultCSS1Parser.ParseFile(filename)
- }
|