template_functions.go 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. package main
  2. import (
  3. "fmt"
  4. "regexp"
  5. "strings"
  6. "text/template"
  7. "time"
  8. )
  9. func templateNewMap(args ...interface{}) (interface{}, error) {
  10. result := map[string]interface{}{}
  11. for i := 1; i < len(args); i += 2 {
  12. key, ok := args[i-1].(string)
  13. if !ok {
  14. return nil, fmt.Errorf("Map: key %v must be string.", key)
  15. }
  16. result[key] = args[i]
  17. }
  18. return result, nil
  19. }
  20. func templateNewList(args ...interface{}) interface{} {
  21. return args
  22. }
  23. func templateToString(v interface{}) string {
  24. return fmt.Sprintf("%s", v)
  25. }
  26. func templateCompileRegexp(reAny interface{}) (interface {}, error) {
  27. reStr, ok := reAny.(string)
  28. if !ok {
  29. return nil, fmt.Errorf("CompileRegexp: %v must be string.", reAny)
  30. }
  31. re, err := regexp.Compile(reStr)
  32. return re, err
  33. }
  34. /*
  35. func (re *Regexp) ExpandString(dst []byte, template string, src string, match []int) []byte
  36. ExpandString is like Expand but the template and source are strings. It
  37. appends to and returns a byte slice in order to give the calling code
  38. control over allocation.
  39. func (re *Regexp) FindAllString(s string, n int) []string
  40. FindAllString is the 'All' version of FindString; it returns a slice of all
  41. successive matches of the expression, as defined by the 'All' description in
  42. the package comment. A return value of nil indicates no match.
  43. func (re *Regexp) FindAllStringIndex(s string, n int) [][]int
  44. FindAllStringIndex is the 'All' version of FindStringIndex; it returns a
  45. slice of all successive matches of the expression, as defined by the 'All'
  46. description in the package comment. A return value of nil indicates no
  47. match.
  48. func (re *Regexp) FindAllStringSubmatch(s string, n int) [][]string
  49. FindAllStringSubmatch is the 'All' version of FindStringSubmatch; it returns
  50. a slice of all successive matches of the expression, as defined by the 'All'
  51. description in the package comment. A return value of nil indicates no
  52. match.
  53. func (re *Regexp) FindAllStringSubmatchIndex(s string, n int) [][]int
  54. FindAllStringSubmatchIndex is the 'All' version of FindStringSubmatchIndex;
  55. it returns a slice of all successive matches of the expression, as defined
  56. by the 'All' description in the package comment. A return value of nil
  57. indicates no match.
  58. func (re *Regexp) FindString(s string) string
  59. FindString returns a string holding the text of the leftmost match in s of
  60. the regular expression. If there is no match, the return value is an empty
  61. string, but it will also be empty if the regular expression successfully
  62. matches an empty string. Use FindStringIndex or FindStringSubmatch if it is
  63. necessary to distinguish these cases.
  64. func (re *Regexp) FindStringIndex(s string) (loc []int)
  65. FindStringIndex returns a two-element slice of integers defining the
  66. location of the leftmost match in s of the regular expression. The match
  67. itself is at s[loc[0]:loc[1]]. A return value of nil indicates no match.
  68. func (re *Regexp) FindStringSubmatch(s string) []string
  69. FindStringSubmatch returns a slice of strings holding the text of the
  70. leftmost match of the regular expression in s and the matches, if any, of
  71. its subexpressions, as defined by the 'Submatch' description in the package
  72. comment. A return value of nil indicates no match.
  73. func (re *Regexp) FindStringSubmatchIndex(s string) []int
  74. FindStringSubmatchIndex returns a slice holding the index pairs identifying
  75. the leftmost match of the regular expression in s and the matches, if any,
  76. of its subexpressions, as defined by the 'Submatch' and 'Index' descriptions
  77. in the package comment. A return value of nil indicates no match.
  78. func (re *Regexp) LiteralPrefix() (prefix string, complete bool)
  79. LiteralPrefix returns a literal string that must begin any match of the
  80. regular expression re. It returns the boolean true if the literal string
  81. comprises the entire regular expression.
  82. func (re *Regexp) MatchString(s string) bool
  83. MatchString reports whether the string s contains any match of the regular
  84. expression re.
  85. func (re *Regexp) FindString(s string) string
  86. FindString returns a string holding the text of the leftmost match in s of
  87. the regular expression. If there is no match, the return value is an empty
  88. string, but it will also be empty if the regular expression successfully
  89. matches an empty string. Use FindStringIndex or FindStringSubmatch if it is
  90. necessary to distinguish these cases.
  91. func (re *Regexp) FindStringIndex(s string) (loc []int)
  92. FindStringIndex returns a two-element slice of integers defining the
  93. location of the leftmost match in s of the regular expression. The match
  94. itself is at s[loc[0]:loc[1]]. A return value of nil indicates no match.
  95. func (re *Regexp) Split(s string, n int) []string
  96. Split slices s into substrings separated by the expression and returns a
  97. slice of the substrings between those expression matches.
  98. The slice returned by this method consists of all the substrings of s not
  99. contained in the slice returned by FindAllString. When called on an
  100. expression that contains no metacharacters, it is equivalent to
  101. strings.SplitN.
  102. Example:
  103. s := regexp.MustCompile("a*").Split("abaabaccadaaae", 5)
  104. // s: ["", "b", "b", "c", "cadaaae"]
  105. The count determines the number of substrings to return:
  106. n > 0: at most n substrings; the last substring will be the unsplit remainder.
  107. n == 0: the result is nil (zero substrings)
  108. n < 0: all substrings
  109. func (re *Regexp) String() string
  110. String returns the source text used to compile the regular expression.
  111. func (re *Regexp) SubexpNames() []string
  112. SubexpNames returns the names of the parenthesized subexpressions in this
  113. Regexp. The name for the first sub-expression is names[1], so that if m is a
  114. match slice, the name for m[i] is SubexpNames()[i]. Since the Regexp as a
  115. whole cannot be named, names[0] is always the empty string. The slice should
  116. not be modified.
  117. */
  118. func iadd(i1, i2 int) int {
  119. return i1 + i2
  120. }
  121. func isub(i1, i2 int) int {
  122. return i1 - i2
  123. }
  124. func imul(i1, i2 int) int {
  125. return i1 * i2
  126. }
  127. func idiv(i1, i2 int) int {
  128. return i1 / i2
  129. }
  130. func fadd(i1, i2 float64) float64 {
  131. return i1 + i2
  132. }
  133. func fsub(i1, i2 float64) float64 {
  134. return i1 - i2
  135. }
  136. func fmul(i1, i2 float64) float64 {
  137. return i1 * i2
  138. }
  139. func fdiv(i1, i2 float64) float64 {
  140. return i1 / i2
  141. }
  142. var templateFunctionMap template.FuncMap = template.FuncMap{
  143. "CompileRegexp": templateCompileRegexp,
  144. "Compare": strings.Compare,
  145. "Contains": strings.Contains,
  146. "ContainsAny": strings.ContainsAny,
  147. "ContainsRune": strings.ContainsRune,
  148. "Count": strings.Count,
  149. "EqualFold": strings.EqualFold,
  150. "Fields": strings.Fields,
  151. "FieldsFunc": strings.FieldsFunc,
  152. "HasPrefix": strings.HasPrefix,
  153. "HasSuffix": strings.HasSuffix,
  154. "Index": strings.Index,
  155. "IndexAny": strings.IndexAny,
  156. "IndexByte": strings.IndexByte,
  157. "IndexFunc": strings.IndexFunc,
  158. "IndexRune": strings.IndexRune,
  159. "IsEpsilon": IsEpsilon,
  160. "IsNonterminal": IsNonterminal,
  161. "Join": strings.Join,
  162. "LastIndex": strings.LastIndex,
  163. "LastIndexAny": strings.LastIndexAny,
  164. "LastIndexByte": strings.LastIndexByte,
  165. "LastIndexFunc": strings.LastIndexFunc,
  166. "Map": strings.Map,
  167. "MatchString": regexp.MatchString,
  168. "NewMap": templateNewMap,
  169. "NewList": templateNewList,
  170. "Now": time.Now,
  171. "Repeat": strings.Repeat,
  172. "Replace": strings.Replace,
  173. "ReplaceAll": strings.ReplaceAll,
  174. "Split": strings.Split,
  175. "SplitAfter": strings.SplitAfter,
  176. "SplitAfterN": strings.SplitAfterN,
  177. "SplitN": strings.SplitN,
  178. "Title": strings.Title,
  179. "ToLower": strings.ToLower,
  180. "ToLowerSpecial": strings.ToLowerSpecial,
  181. "ToString": templateToString,
  182. "ToTitle": strings.ToTitle,
  183. "ToTitleSpecial": strings.ToTitleSpecial,
  184. "ToUpper": strings.ToUpper,
  185. "ToUpperSpecial": strings.ToUpperSpecial,
  186. "Trim": strings.Trim,
  187. "TrimFunc": strings.TrimFunc,
  188. "TrimLeft": strings.TrimLeft,
  189. "TrimLeftFunc": strings.TrimLeftFunc,
  190. "TrimPrefix": strings.TrimPrefix,
  191. "TrimRight": strings.TrimRight,
  192. "TrimRightFunc": strings.TrimRightFunc,
  193. "TrimSpace": strings.TrimSpace,
  194. "TrimSuffix": strings.TrimSuffix,
  195. "iadd": iadd,
  196. "isub": isub,
  197. "imul": imul,
  198. "idiv": idiv,
  199. "fadd": fadd,
  200. "fsub": fsub,
  201. "fmul": fmul,
  202. "fdiv": fdiv,
  203. }