github.com/MontFerret/ferret@v0.18.0/pkg/drivers/common/styles.go (about)

     1  package common
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"strconv"
     7  	"strings"
     8  
     9  	"github.com/gorilla/css/scanner"
    10  
    11  	"github.com/MontFerret/ferret/pkg/runtime/core"
    12  	"github.com/MontFerret/ferret/pkg/runtime/values"
    13  )
    14  
    15  func DeserializeStyles(input values.String) (*values.Object, error) {
    16  	styles := values.NewObject()
    17  
    18  	if input == values.EmptyString {
    19  		return styles, nil
    20  	}
    21  
    22  	s := scanner.New(input.String())
    23  
    24  	var name string
    25  	var value bytes.Buffer
    26  	var setValue = func() {
    27  		styles.Set(values.NewString(strings.TrimSpace(name)), values.NewString(strings.TrimSpace(value.String())))
    28  		name = ""
    29  		value.Reset()
    30  	}
    31  
    32  	for {
    33  		token := s.Next()
    34  
    35  		if token == nil {
    36  			break
    37  		}
    38  
    39  		if token.Type == scanner.TokenEOF {
    40  			break
    41  		}
    42  
    43  		if name == "" && token.Type == scanner.TokenIdent {
    44  			name = token.Value
    45  
    46  			// skip : and white spaces
    47  			for {
    48  				token = s.Next()
    49  
    50  				if token.Value != ":" && token.Type != scanner.TokenS {
    51  					break
    52  				}
    53  			}
    54  		}
    55  
    56  		switch token.Type {
    57  		case scanner.TokenChar:
    58  			// end of style declaration
    59  			if token.Value == ";" {
    60  				if name != "" {
    61  					setValue()
    62  				}
    63  			} else {
    64  				value.WriteString(token.Value)
    65  			}
    66  		case scanner.TokenNumber:
    67  			num, err := strconv.ParseFloat(token.Value, 64)
    68  
    69  			if err == nil {
    70  				styles.Set(values.NewString(name), values.NewFloat(num))
    71  				// reset prop
    72  				name = ""
    73  				value.Reset()
    74  			}
    75  		default:
    76  			value.WriteString(token.Value)
    77  		}
    78  	}
    79  
    80  	if name != "" && value.Len() > 0 {
    81  		setValue()
    82  	}
    83  
    84  	return styles, nil
    85  }
    86  
    87  func SerializeStyles(_ context.Context, styles *values.Object) values.String {
    88  	if styles == nil {
    89  		return values.EmptyString
    90  	}
    91  
    92  	var b bytes.Buffer
    93  
    94  	styles.ForEach(func(value core.Value, key string) bool {
    95  		b.WriteString(key)
    96  		b.WriteString(": ")
    97  		b.WriteString(value.String())
    98  		b.WriteString("; ")
    99  
   100  		return true
   101  	})
   102  
   103  	return values.NewString(b.String())
   104  }