value.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. package css
  2. import (
  3. "strings"
  4. "github.com/gorilla/css/scanner"
  5. )
  6. type CSSValue struct {
  7. Tokens []*scanner.Token
  8. }
  9. func NewCSSValue(csstext string) *CSSValue {
  10. sc := scanner.New(csstext)
  11. val := CSSValue{Tokens: make([]*scanner.Token, 0)}
  12. Loop:
  13. for {
  14. token := sc.Next()
  15. switch token.Type {
  16. case scanner.TokenError, scanner.TokenEOF:
  17. break Loop
  18. default:
  19. val.Tokens = append(val.Tokens, token)
  20. }
  21. }
  22. return &val
  23. }
  24. func NewCSSValueString(data string) *CSSValue {
  25. data = strings.ReplaceAll(data, `\`, `\\`)
  26. data = strings.ReplaceAll(data, `"`, `\"`)
  27. data = `"` + data + `"`
  28. token := scanner.Token{scanner.TokenString, data, 0, 0}
  29. return &CSSValue{Tokens: []*scanner.Token{&token}}
  30. }
  31. func (v *CSSValue) SplitOnToken(split *scanner.Token) []*CSSValue {
  32. res := make([]*CSSValue, 0)
  33. current := make([]*scanner.Token, 0)
  34. for _, tok := range v.Tokens {
  35. if tok.Type == split.Type && tok.Value == split.Value {
  36. res = append(res, &CSSValue{Tokens: current})
  37. current = make([]*scanner.Token, 0)
  38. } else {
  39. current = append(current, tok)
  40. }
  41. }
  42. res = append(res, &CSSValue{Tokens: current})
  43. return res
  44. }
  45. func (v *CSSValue) Text() string {
  46. var b strings.Builder
  47. for _, t := range v.Tokens {
  48. b.WriteString(t.Value)
  49. }
  50. return strings.TrimSpace(b.String())
  51. }
  52. func (v *CSSValue) ParsedText() string {
  53. var b strings.Builder
  54. for _, t := range v.Tokens {
  55. switch t.Type {
  56. case scanner.TokenString:
  57. val := t.Value[1 : len(t.Value)-1] // remove trailing / leading quotes
  58. val = strings.ReplaceAll(val, `\"`, `"`)
  59. val = strings.ReplaceAll(val, `\'`, `'`)
  60. val = strings.ReplaceAll(val, `\\`, `\`)
  61. // \A9 should be replaced by the corresponding rune
  62. b.WriteString(val)
  63. default:
  64. b.WriteString(t.Value)
  65. }
  66. }
  67. return strings.TrimSpace(b.String())
  68. }