github.com/coveo/gotemplate@v2.7.7+incompatible/template/extra_utils.go (about)

     1  package template
     2  
     3  import (
     4  	"fmt"
     5  	"regexp"
     6  	"strconv"
     7  	"strings"
     8  
     9  	"github.com/coveo/gotemplate/collections"
    10  	"github.com/coveo/gotemplate/utils"
    11  )
    12  
    13  const (
    14  	utilsBase = "Other utilities"
    15  )
    16  
    17  var utilsFuncs = dictionary{
    18  	"center":     center,
    19  	"color":      utils.SprintColor,
    20  	"concat":     collections.Concat,
    21  	"formatList": utils.FormatList,
    22  	"id":         id,
    23  	"iif":        collections.IIf,
    24  	"joinLines":  collections.JoinLines,
    25  	"lorem":      lorem,
    26  	"mergeList":  utils.MergeLists,
    27  	"repeat":     repeat,
    28  	"indent":     indent,
    29  	"nIndent":    nIndent,
    30  	"sIndent":    sIndent,
    31  	"splitLines": collections.SplitLines,
    32  	"wrap":       wrap,
    33  }
    34  
    35  var utilsFuncsArgs = arguments{
    36  	"center":     {"width"},
    37  	"formatList": {"format", "list"},
    38  	"id":         {"identifier", "replaceChar"},
    39  	"iif":        {"testValue", "valueTrue", "valueFalse"},
    40  	"joinLines":  {"format"},
    41  	"lorem":      {"loremType", "params"},
    42  	"mergeList":  {"lists"},
    43  	"repeat":     {"n", "element"},
    44  	"indent":     {"nbSpace"},
    45  	"nIndent":    {"nbSpace"},
    46  	"sIndent":    {"spacer"},
    47  	"splitLines": {"content"},
    48  	"wrap":       {"width"},
    49  }
    50  
    51  var utilsFuncsAliases = aliases{
    52  	"center":     {"centered"},
    53  	"color":      {"colored", "enhanced"},
    54  	"id":         {"identifier"},
    55  	"iif":        {"ternary"},
    56  	"lorem":      {"loremIpsum"},
    57  	"nIndent":    {"nindent"},
    58  	"formatList": {"autoWrap", "aWrap", "awrap"},
    59  	"sIndent":    {"sindent", "spaceIndent", "autoIndent", "aindent", "aIndent"},
    60  	"wrap":       {"wrapped"},
    61  }
    62  
    63  var utilsFuncsHelp = descriptions{
    64  	"center": "Returns the concatenation of supplied arguments centered within width.",
    65  	"color": strings.TrimSpace(collections.UnIndent(`
    66  		Colors the rendered string.
    67  
    68  		The first arguments are interpretated as color attributes until the first non color attribute. Attributes are case insensitive.
    69  
    70  		Valid attributes are:
    71  		    Reset, Bold, Faint, Italic, Underline, BlinkSlow, BlinkRapid, ReverseVideo, Concealed, CrossedOut
    72  
    73  		Valid color are:
    74  		    Black, Red, Green, Yellow, Blue, Magenta, Cyan, White
    75  
    76  		Color can be prefixed by:
    77  		    Fg:   Meaning foreground (Fg is assumed if not specified)
    78  		    FgHi: Meaning high intensity forground
    79  		    Bg:   Meaning background"
    80  		    BgHi: Meaning high intensity background
    81  	`)),
    82  	"concat": "Returns the concatenation (without separator) of the string representation of objects.",
    83  	"formatList": strings.TrimSpace(collections.UnIndent(`
    84  		Return a list of strings by applying the format to each element of the supplied list.
    85  
    86  		You can also use autoWrap as Razor expression if you don't want to specify the format.
    87  		The format is then automatically induced by the context around the declaration).
    88  		Valid aliases for autoWrap are: aWrap, awrap.
    89  
    90  		Ex:
    91  		    Hello @<autoWrap(to(10)) World!
    92  	`)),
    93  	"id":        "Returns a valid go identifier from the supplied string (replacing any non compliant character by replacement, default _ ).",
    94  	"iif":       "If testValue is empty, returns falseValue, otherwise returns trueValue.\n    WARNING: All arguments are evaluated and must by valid.",
    95  	"indent":    "Indents every line in a given string to the specified indent width. This is useful when aligning multi-line strings.",
    96  	"joinLines": "Merge the supplied objects into a newline separated string.",
    97  	"lorem":     "Returns a random string. Valid types are be word, words, sentence, para, paragraph, host, email, url.",
    98  	"mergeList": "Return a single list containing all elements from the lists supplied.",
    99  	"nindent":   "Work as indent but add a newline before.",
   100  	"repeat":    "Returns an array with the item repeated n times.",
   101  	"sIndent": strings.TrimSpace(collections.UnIndent(`
   102  		Indents the elements using the provided spacer.
   103  		
   104  		You can also use autoIndent as Razor expression if you don't want to specify the spacer.
   105  		Spacer will then be auto determined by the spaces that precede the expression.
   106  		Valid aliases for autoIndent are: aIndent, aindent.
   107  	`)),
   108  	"splitLines": "Returns a list of strings from the supplied object with newline as the separator.",
   109  	"wrap":       "Wraps the rendered arguments within width.",
   110  }
   111  
   112  func (t *Template) addUtilsFuncs() {
   113  	t.AddFunctions(utilsFuncs, utilsBase, FuncOptions{
   114  		FuncHelp:    utilsFuncsHelp,
   115  		FuncArgs:    utilsFuncsArgs,
   116  		FuncAliases: utilsFuncsAliases,
   117  	})
   118  }
   119  
   120  func lorem(funcName interface{}, params ...int) (result string, err error) {
   121  	kind, err := utils.GetLoremKind(fmt.Sprint(funcName))
   122  	if err == nil {
   123  		result, err = utils.Lorem(kind, params...)
   124  	}
   125  	return
   126  }
   127  
   128  func center(width interface{}, args ...interface{}) (string, error) {
   129  	w, err := strconv.Atoi(fmt.Sprintf("%v", width))
   130  	if err != nil {
   131  		return "", fmt.Errorf("width must be integer")
   132  	}
   133  	return collections.CenterString(utils.FormatMessage(args...), w), nil
   134  }
   135  
   136  func wrap(width interface{}, args ...interface{}) (string, error) {
   137  	w, err := strconv.Atoi(fmt.Sprintf("%v", width))
   138  	if err != nil {
   139  		return "", fmt.Errorf("width must be integer")
   140  	}
   141  	return collections.WrapString(utils.FormatMessage(args...), w), nil
   142  }
   143  
   144  func indent(space int, args ...interface{}) string {
   145  	args = convertArgs(nil, args...).AsArray()
   146  	return collections.Indent(strings.Join(toStrings(args), "\n"), strings.Repeat(" ", space))
   147  }
   148  
   149  func nIndent(space int, args ...interface{}) string {
   150  	return "\n" + indent(space, args...)
   151  }
   152  
   153  func sIndent(spacer string, args ...interface{}) string {
   154  	args = convertArgs(nil, args...).AsArray()
   155  	return collections.Indent(strings.Join(toStrings(args), "\n"), spacer)
   156  }
   157  
   158  func id(id string, replace ...interface{}) string {
   159  	// By default, replacement char for invalid chars would be _
   160  	// but it is possible to specify an alternative string to act as the replacement
   161  	replacement := fmt.Sprint(replace...)
   162  	if replacement == "" {
   163  		replacement = "_"
   164  	}
   165  
   166  	dup := duplicateUnderscore
   167  	if replacement != "_" {
   168  		// If the replacement string is not the default one, we generate a special substituter to remove duplicates
   169  		// taking into account regex special chars such as +, ?, etc.
   170  		dup = regexp.MustCompile(fmt.Sprintf(`(?:%s)+`, regexSpecial.ReplaceAllString(replacement, `\$0`)))
   171  	}
   172  
   173  	return dup.ReplaceAllString(validChars.ReplaceAllString(id, replacement), replacement)
   174  }
   175  
   176  var validChars = regexp.MustCompile(`[^\p{L}\d_]`)
   177  var duplicateUnderscore = regexp.MustCompile(`_+`)
   178  var regexSpecial = regexp.MustCompile(`[\+\.\?\(\)\[\]\{\}\\]`)
   179  
   180  func repeat(n int, a interface{}) (result collections.IGenericList, err error) {
   181  	if n < 0 {
   182  		err = fmt.Errorf("n must be greater or equal than 0")
   183  		return
   184  	}
   185  	result = collections.CreateList(n)
   186  	for i := 0; i < n; i++ {
   187  		result.Set(i, a)
   188  	}
   189  	return
   190  }