123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- package xvdoc
- import (
- "fmt"
- "strings"
- )
- func constructorFormula(m JSONMap) (res Cell, err error) {
- if method := m.StringVal("method", ""); len(method) > 0 {
- var args []CellArg
- if ai := m.Array("args"); len(ai) > 0 {
- var arg CellArg
- args = make([]CellArg, len(ai))
- for i, v := range ai {
- if arg, err = argFromIface(v); err == nil {
- args[i] = arg
- } else {
- return
- }
- }
- }
- res = &CellFormula{
- method: method,
- args: args,
- style: m.StringVal("style", ""),
- styles: m.StringArray("styles"),
- }
- } else {
- err = fmt.Errorf("Formula constructor error: empty method")
- }
- return
- }
- // CellFormula is cell of formula for excel or other types with formula support
- type CellFormula struct {
- method string
- args []CellArg
- styles []string
- style string
- }
- // Val is method of getter formula string (Cell interface)
- func (s *CellFormula) Val() interface{} {
- return s.method
- }
- // Type method is value type getter (formula)
- func (s *CellFormula) Type() string {
- return "formula"
- }
- func (s *CellFormula) String() string {
- return fmt.Sprintf("{ formula :: %v, args: [ %v ]}", s.method, s.args)
- }
- // ReplaceArgs is replace variable templates ($1, $2, etc) to valus from incoming array
- func (s *CellFormula) ReplaceArgs(args []string) (res string) {
- res = s.method
- for i, arg := range args {
- res = strings.ReplaceAll(res, fmt.Sprintf("$%v", i+1), arg)
- }
- return res
- }
- // Style is getter of cell style
- func (s *CellFormula) Styles() (res []string) {
- if len(s.styles) > 0 {
- res = s.styles
- } else if len(s.style) > 0 {
- res = []string{s.style}
- }
- return
- }
- ////////////////////////////////////////////
- type argType uint8
- const (
- argTypeValue argType = iota
- argTypeRow
- argTypeCell
- )
- func (s argType) String() string {
- switch s {
- case argTypeRow:
- return "row"
- case argTypeCell:
- return "cell"
- default:
- return "value"
- }
- }
- func argFromIface(i interface{}) (arg CellArg, err error) {
- if _, check := i.(map[string]interface{}); !check {
- err = fmt.Errorf("Cell argument parse Error :: object expected")
- } else {
- m := JSONMap(i.(map[string]interface{}))
- switch m.StringVal("type", "") {
- case "cell":
- arg.aType = argTypeCell
- case "row":
- arg.aType = argTypeRow
- default:
- if m.KeyExists("value") {
- arg.aType = argTypeValue
- } else {
- err = fmt.Errorf("Unexpected argument type (type or value field expected)")
- }
- }
- delete(m, "type")
- arg.data = m
- }
- return
- }
- // CellArg is argument object of cell
- type CellArg struct {
- aType argType
- data JSONMap
- }
- func (s CellArg) String() string {
- return fmt.Sprintf("{ %v, data: %v }", s.aType, s.data)
- }
- // Value is getter of argument value
- func (s CellArg) Value() interface{} {
- return s.data["value"]
- }
- // Coords calculate real argument coords by current args
- func (s CellArg) Coords(x, y int) (dx, dy int) {
- dx, dy = x, y
- if s.data.KeyExists("x") {
- dx = int(s.data.Int("x", 0))
- } else if s.data.KeyExists("ox") {
- dx += int(s.data.Int("ox", 0))
- }
- if s.data.KeyExists("y") {
- dy = int(s.data.Int("y", 0))
- } else if s.data.KeyExists("oy") {
- dy += int(s.data.Int("oy", 0))
- }
- return
- }
|