github.com/mithrandie/csvq@v1.18.1/lib/syntax/element.go (about)

     1  package syntax
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"github.com/mithrandie/csvq/lib/option"
     8  
     9  	"github.com/mithrandie/go-text/color"
    10  )
    11  
    12  const (
    13  	NameEffect     = "syntax_name"
    14  	KeywordEffect  = "syntax_keyword"
    15  	LinkEffect     = "syntax_link"
    16  	VariableEffect = "syntax_variable"
    17  	FlagEffect     = "syntax_flag"
    18  	ItalicEffect   = "syntax_italic"
    19  	TypeEffect     = "syntax_type"
    20  )
    21  
    22  type Definition struct {
    23  	Name        Name
    24  	Group       []Grammar
    25  	Description Description
    26  }
    27  
    28  type Element interface {
    29  	Format(p *color.Palette) string
    30  }
    31  
    32  type Name string
    33  
    34  func (e Name) String() string {
    35  	return string(e)
    36  }
    37  
    38  func (e Name) Format(p *color.Palette) string {
    39  	s := string(e)
    40  	if p != nil {
    41  		s = p.Render(NameEffect, s)
    42  	}
    43  	return s
    44  }
    45  
    46  type Grammar []Element
    47  
    48  func (e Grammar) Format(p *color.Palette) string {
    49  	l := make([]string, 0, len(e))
    50  	for _, en := range e {
    51  		l = append(l, en.Format(p))
    52  	}
    53  	return strings.Join(l, " ")
    54  }
    55  
    56  type Description struct {
    57  	Template string
    58  	Values   []Element
    59  }
    60  
    61  func (e Description) Format(p *color.Palette) string {
    62  	var decorateRequired = func(e Element) bool {
    63  		switch e.(type) {
    64  		case String, Integer, Float, Boolean, Datetime, Identifier:
    65  			return true
    66  		case Ternary:
    67  			s := string(e.(Ternary))
    68  			if s == "TRUE" || s == "FALSE" || s == "UNKNOWN" {
    69  				return false
    70  			}
    71  			return true
    72  		case Null:
    73  			s := string(e.(Null))
    74  			if s == "NULL" {
    75  				return false
    76  			}
    77  			return true
    78  		}
    79  		return false
    80  	}
    81  
    82  	replaces := make([]interface{}, 0, len(e.Values))
    83  	for _, v := range e.Values {
    84  		if p == nil && decorateRequired(v) {
    85  			replaces = append(replaces, "_"+v.Format(p)+"_")
    86  		} else {
    87  			replaces = append(replaces, v.Format(p))
    88  		}
    89  	}
    90  	return fmt.Sprintf(e.Template, replaces...)
    91  }
    92  
    93  type Keyword string
    94  
    95  func (e Keyword) Format(p *color.Palette) string {
    96  	s := string(e)
    97  	if p != nil {
    98  		s = p.Render(KeywordEffect, s)
    99  	}
   100  	return s
   101  }
   102  
   103  type Link string
   104  
   105  func (e Link) Format(p *color.Palette) string {
   106  	s := "<" + string(e) + ">"
   107  	if p != nil {
   108  		s = p.Render(LinkEffect, s)
   109  	}
   110  	return s
   111  }
   112  
   113  type Option []Element
   114  
   115  func (e Option) Format(p *color.Palette) string {
   116  	l := make([]string, 0, len(e))
   117  	for _, v := range e {
   118  		l = append(l, v.Format(p))
   119  	}
   120  	return "[" + strings.Join(l, " ") + "]"
   121  }
   122  
   123  type FollowingContinuousOption []Element
   124  
   125  func (e FollowingContinuousOption) Format(p *color.Palette) string {
   126  	l := make([]string, 0, len(e))
   127  	for _, v := range e {
   128  		l = append(l, v.Format(p))
   129  	}
   130  	return " [, " + strings.Join(l, " ") + " ...]"
   131  }
   132  
   133  type ContinuousOption []Element
   134  
   135  func (e ContinuousOption) Format(p *color.Palette) string {
   136  	l := make([]string, 0, len(e))
   137  	for _, v := range e {
   138  		l = append(l, v.Format(p))
   139  	}
   140  	return strings.Join(l, " ") + " [, " + strings.Join(l, " ") + " ...]"
   141  }
   142  
   143  type AnyOne []Element
   144  
   145  func (e AnyOne) Format(p *color.Palette) string {
   146  	l := make([]string, 0, len(e))
   147  	for _, v := range e {
   148  		l = append(l, v.Format(p))
   149  	}
   150  	return "{" + strings.Join(l, "|") + "}"
   151  }
   152  
   153  type Parentheses []Element
   154  
   155  func (e Parentheses) Format(p *color.Palette) string {
   156  	l := make([]string, 0, len(e))
   157  	for _, v := range e {
   158  		l = append(l, v.Format(p))
   159  	}
   160  	return "(" + strings.Join(l, " ") + ")"
   161  }
   162  
   163  type PlainGroup []Element
   164  
   165  func (e PlainGroup) Format(p *color.Palette) string {
   166  	l := make([]string, 0, len(e))
   167  	for _, v := range e {
   168  		l = append(l, v.Format(p))
   169  	}
   170  	return strings.Join(l, " ")
   171  }
   172  
   173  type ConnectedGroup []Element
   174  
   175  func (e ConnectedGroup) Format(p *color.Palette) string {
   176  	l := make([]string, 0, len(e))
   177  	for _, v := range e {
   178  		l = append(l, v.Format(p))
   179  	}
   180  	return strings.Join(l, "")
   181  }
   182  
   183  type Function struct {
   184  	Name       string
   185  	Args       []Element
   186  	AfterArgs  []Element
   187  	CustomArgs []Element
   188  	Return     Element
   189  }
   190  
   191  func (e Function) Format(p *color.Palette) string {
   192  	name := e.Name
   193  	if p != nil {
   194  		name = p.Render(KeywordEffect, name)
   195  	}
   196  
   197  	var fnargs string
   198  	if 0 < len(e.CustomArgs) {
   199  		args := make([]string, 0, len(e.CustomArgs))
   200  		for _, v := range e.CustomArgs {
   201  			args = append(args, formatArg(v, p))
   202  		}
   203  		fnargs = strings.Join(args, " ")
   204  	} else {
   205  		args := make([]string, 0, len(e.Args))
   206  		var opstr string
   207  		var prevOpt string
   208  		for i, v := range e.Args {
   209  			if op, ok := v.(Option); ok {
   210  				if i == 0 {
   211  					prevOpt = formatArg(v, p) + " "
   212  				} else {
   213  					for i := len(op) - 1; i >= 0; i-- {
   214  						opstr = " [, " + formatArg(op[i], p) + opstr + "]"
   215  					}
   216  				}
   217  			} else {
   218  				args = append(args, formatArg(v, p))
   219  			}
   220  		}
   221  		fnargs = prevOpt + strings.Join(args, ", ") + opstr
   222  	}
   223  	s := name + "(" + fnargs + ")"
   224  
   225  	if e.AfterArgs != nil {
   226  		afterArgs := make([]string, 0, len(e.AfterArgs))
   227  		for _, arg := range e.AfterArgs {
   228  			afterArgs = append(afterArgs, arg.Format(p))
   229  		}
   230  		s = s + " " + strings.Join(afterArgs, " ")
   231  	}
   232  
   233  	if e.Return != nil {
   234  		s = s + e.Return.Format(p)
   235  	}
   236  	return s
   237  }
   238  
   239  func formatArg(arg Element, p *color.Palette) string {
   240  	s := arg.Format(p)
   241  
   242  	t := ""
   243  	switch arg.(type) {
   244  	case String:
   245  		t = "string"
   246  	case Integer:
   247  		t = "integer"
   248  	case Float:
   249  		t = "float"
   250  	case Boolean:
   251  		t = "boolean"
   252  	case Ternary:
   253  		t = "ternary"
   254  	case Datetime:
   255  		t = "datetime"
   256  	default:
   257  		return s
   258  	}
   259  	t = "::" + t
   260  	if p != nil {
   261  		t = p.Render(TypeEffect, t)
   262  	}
   263  	return s + t
   264  }
   265  
   266  type ArgWithDefValue struct {
   267  	Arg     Element
   268  	Default Element
   269  }
   270  
   271  func (e ArgWithDefValue) Format(p *color.Palette) string {
   272  	return formatArg(e.Arg, p) + " " + Keyword("DEFAULT").Format(p) + " " + e.Default.Format(p)
   273  }
   274  
   275  type String string
   276  
   277  func (e String) Format(p *color.Palette) string {
   278  	s := string(e)
   279  	if p != nil {
   280  		s = p.Render(ItalicEffect, p.Render(option.StringEffect, s))
   281  	}
   282  	return s
   283  }
   284  
   285  type Integer string
   286  
   287  func (e Integer) Format(p *color.Palette) string {
   288  	s := string(e)
   289  	if p != nil {
   290  		s = p.Render(ItalicEffect, p.Render(option.NumberEffect, s))
   291  	}
   292  	return s
   293  }
   294  
   295  type Float string
   296  
   297  func (e Float) Format(p *color.Palette) string {
   298  	s := string(e)
   299  	if p != nil {
   300  		s = p.Render(ItalicEffect, p.Render(option.NumberEffect, s))
   301  	}
   302  	return s
   303  }
   304  
   305  type Identifier string
   306  
   307  func (e Identifier) Format(p *color.Palette) string {
   308  	s := string(e)
   309  	if p != nil {
   310  		s = p.Render(option.IdentifierEffect, s)
   311  	}
   312  	return s
   313  }
   314  
   315  type Datetime string
   316  
   317  func (e Datetime) Format(p *color.Palette) string {
   318  	s := string(e)
   319  	if p != nil {
   320  		s = p.Render(ItalicEffect, p.Render(option.DatetimeEffect, s))
   321  	}
   322  	return s
   323  }
   324  
   325  type Boolean string
   326  
   327  func (e Boolean) Format(p *color.Palette) string {
   328  	s := string(e)
   329  	if p != nil {
   330  		s = p.Render(ItalicEffect, p.Render(option.BooleanEffect, s))
   331  	}
   332  	return s
   333  }
   334  
   335  type Ternary string
   336  
   337  func (e Ternary) Format(p *color.Palette) string {
   338  	s := string(e)
   339  	if p != nil {
   340  		s = p.Render(ItalicEffect, p.Render(option.TernaryEffect, s))
   341  	}
   342  	return s
   343  }
   344  
   345  type Null string
   346  
   347  func (e Null) Format(p *color.Palette) string {
   348  	s := string(e)
   349  	if p != nil {
   350  		s = p.Render(ItalicEffect, p.Render(option.NullEffect, s))
   351  	}
   352  	return s
   353  }
   354  
   355  type Variable string
   356  
   357  func (e Variable) Format(p *color.Palette) string {
   358  	s := string(e)
   359  	if p != nil {
   360  		s = p.Render(VariableEffect, s)
   361  	}
   362  	return s
   363  }
   364  
   365  type Flag string
   366  
   367  func (e Flag) Format(p *color.Palette) string {
   368  	s := string(e)
   369  	if p != nil {
   370  		s = p.Render(FlagEffect, s)
   371  	}
   372  	return s
   373  }
   374  
   375  type Token string
   376  
   377  func (e Token) Format(_ *color.Palette) string {
   378  	return string(e)
   379  }
   380  
   381  type Italic string
   382  
   383  func (e Italic) Format(p *color.Palette) string {
   384  	s := string(e)
   385  	if p != nil {
   386  		s = p.Render(ItalicEffect, s)
   387  	}
   388  	return s
   389  }
   390  
   391  type Return string
   392  
   393  func (e Return) Format(p *color.Palette) string {
   394  	s := "return::" + string(e)
   395  	if p != nil {
   396  		s = p.Render(TypeEffect, s)
   397  	}
   398  	return "  " + s
   399  }