PageRenderTime 49ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/src/DotLiquid/StandardFilters.cs

https://github.com/debackerl/dotliquid
C# | 412 lines | 225 code | 47 blank | 140 comment | 41 complexity | 9830813c26cb781c39ec8d562d46fffc MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Globalization;
  5. using System.Linq;
  6. using System.Linq.Expressions;
  7. using System.Text.RegularExpressions;
  8. using System.Web;
  9. using DotLiquid.Util;
  10. namespace DotLiquid
  11. {
  12. public static class StandardFilters
  13. {
  14. /// <summary>
  15. /// Return the size of an array or of an string
  16. /// </summary>
  17. /// <param name="input"></param>
  18. /// <returns></returns>
  19. public static int Size(object input)
  20. {
  21. if (input is string)
  22. return ((string)input).Length;
  23. if (input is IEnumerable)
  24. return ((IEnumerable)input).Cast<object>().Count();
  25. return 0;
  26. }
  27. /// <summary>
  28. /// convert a input string to DOWNCASE
  29. /// </summary>
  30. /// <param name="input"></param>
  31. /// <returns></returns>
  32. public static string Downcase(string input)
  33. {
  34. return input == null ? input : input.ToLower();
  35. }
  36. /// <summary>
  37. /// convert a input string to UPCASE
  38. /// </summary>
  39. /// <param name="input"></param>
  40. /// <returns></returns>
  41. public static string Upcase(string input)
  42. {
  43. return input == null
  44. ? input
  45. : input.ToUpper();
  46. }
  47. /// <summary>
  48. /// capitalize words in the input sentence
  49. /// </summary>
  50. /// <param name="input"></param>
  51. /// <returns></returns>
  52. public static string Capitalize(string input)
  53. {
  54. if (string.IsNullOrWhiteSpace(input))
  55. return input;
  56. return string.IsNullOrEmpty(input)
  57. ? input
  58. : CultureInfo.CurrentCulture.TextInfo.ToTitleCase(input);
  59. }
  60. public static string Escape(string input)
  61. {
  62. if (string.IsNullOrEmpty(input))
  63. return input;
  64. try
  65. {
  66. return HttpUtility.HtmlEncode(input);
  67. }
  68. catch
  69. {
  70. return input;
  71. }
  72. }
  73. public static string H(string input)
  74. {
  75. return Escape(input);
  76. }
  77. /// <summary>
  78. /// Truncates a string down to x characters
  79. /// </summary>
  80. /// <param name="input"></param>
  81. /// <param name="length"></param>
  82. /// <param name="truncateString"></param>
  83. /// <returns></returns>
  84. public static string Truncate(string input, int length = 50, string truncateString = "...")
  85. {
  86. if (string.IsNullOrEmpty(input))
  87. return input;
  88. int l = length - truncateString.Length;
  89. return input.Length > length
  90. ? input.Substring(0, l < 0 ? 0 : l) + truncateString
  91. : input;
  92. }
  93. public static string TruncateWords(string input, int words = 15, string truncateString = "...")
  94. {
  95. if (string.IsNullOrEmpty(input))
  96. return input;
  97. string[] wordList = input.Split(' ');
  98. int l = words < 0 ? 0 : words;
  99. return wordList.Length > l
  100. ? string.Join(" ", wordList.Take(l)) + truncateString
  101. : input;
  102. }
  103. public static string StripHtml(string input)
  104. {
  105. return string.IsNullOrWhiteSpace(input)
  106. ? input
  107. : Regex.Replace(input, @"<.*?>", string.Empty);
  108. }
  109. /// <summary>
  110. /// Remove all newlines from the string
  111. /// </summary>
  112. /// <param name="input"></param>
  113. /// <returns></returns>
  114. public static string StripNewlines(string input)
  115. {
  116. return string.IsNullOrWhiteSpace(input)
  117. ? input
  118. : Regex.Replace(input, Environment.NewLine, string.Empty);
  119. }
  120. /// <summary>
  121. /// Join elements of the array with a certain character between them
  122. /// </summary>
  123. /// <param name="input"></param>
  124. /// <param name="glue"></param>
  125. /// <returns></returns>
  126. public static string Join(IEnumerable input, string glue = " ")
  127. {
  128. if (input == null)
  129. return null;
  130. IEnumerable<object> castInput = input.Cast<object>();
  131. return string.Join(glue, castInput);
  132. }
  133. /// <summary>
  134. /// Sort elements of the array
  135. /// provide optional property with which to sort an array of hashes or drops
  136. /// </summary>
  137. /// <param name="input"></param>
  138. /// <param name="property"></param>
  139. /// <returns></returns>
  140. public static IEnumerable Sort(object input, string property = null)
  141. {
  142. List<object> ary;
  143. if (input is IEnumerable)
  144. ary = ((IEnumerable)input).Flatten().Cast<object>().ToList();
  145. else
  146. ary = new List<object>(new[] { input });
  147. if (!ary.Any())
  148. return ary;
  149. if (string.IsNullOrEmpty(property))
  150. ary.Sort();
  151. else if ((ary.All(o => o is IDictionary)) && ((IDictionary)ary.First()).Contains(property))
  152. ary.Sort((a, b) => Comparer.Default.Compare(((IDictionary)a)[property], ((IDictionary)b)[property]));
  153. else if (ary.All(o => o.RespondTo(property)))
  154. ary.Sort((a, b) => Comparer.Default.Compare(a.Send(property), b.Send(property)));
  155. return ary;
  156. }
  157. /// <summary>
  158. /// Map/collect on a given property
  159. /// </summary>
  160. /// <param name="input"></param>
  161. /// <param name="property"></param>
  162. /// <returns></returns>
  163. public static IEnumerable Map(IEnumerable input, string property)
  164. {
  165. List<object> ary = input.Cast<object>().ToList();
  166. if (!ary.Any())
  167. return ary;
  168. if ((ary.All(o => o is IDictionary)) && ((IDictionary)ary.First()).Contains(property))
  169. return ary.Select(e => ((IDictionary)e)[property]);
  170. if (ary.All(o => o.RespondTo(property)))
  171. return ary.Select(e => e.Send(property));
  172. return ary;
  173. }
  174. /// <summary>
  175. /// Replace occurrences of a string with another
  176. /// </summary>
  177. /// <param name="input"></param>
  178. /// <param name="string"></param>
  179. /// <param name="replacement"></param>
  180. /// <returns></returns>
  181. public static string Replace(string input, string @string, string replacement = "")
  182. {
  183. if (string.IsNullOrEmpty(input) || string.IsNullOrEmpty(@string))
  184. return input;
  185. return string.IsNullOrEmpty(input)
  186. ? input
  187. : Regex.Replace(input, @string, replacement);
  188. }
  189. /// <summary>
  190. /// Replace the first occurence of a string with another
  191. /// </summary>
  192. /// <param name="input"></param>
  193. /// <param name="string"></param>
  194. /// <param name="replacement"></param>
  195. /// <returns></returns>
  196. public static string ReplaceFirst(string input, string @string, string replacement = "")
  197. {
  198. if (string.IsNullOrEmpty(input) || string.IsNullOrEmpty(@string))
  199. return input;
  200. bool doneReplacement = false;
  201. return Regex.Replace(input, @string, m =>
  202. {
  203. if (doneReplacement)
  204. return m.Value;
  205. doneReplacement = true;
  206. return replacement;
  207. });
  208. }
  209. /// <summary>
  210. /// Remove a substring
  211. /// </summary>
  212. /// <param name="input"></param>
  213. /// <param name="string"></param>
  214. /// <returns></returns>
  215. public static string Remove(string input, string @string)
  216. {
  217. return string.IsNullOrWhiteSpace(input)
  218. ? input
  219. : input.Replace(@string, string.Empty);
  220. }
  221. /// <summary>
  222. /// Remove the first occurrence of a substring
  223. /// </summary>
  224. /// <param name="input"></param>
  225. /// <param name="string"></param>
  226. /// <returns></returns>
  227. public static string RemoveFirst(string input, string @string)
  228. {
  229. return string.IsNullOrWhiteSpace(input)
  230. ? input
  231. : ReplaceFirst(input, @string, string.Empty);
  232. }
  233. /// <summary>
  234. /// Add one string to another
  235. /// </summary>
  236. /// <param name="input"></param>
  237. /// <param name="string"></param>
  238. /// <returns></returns>
  239. public static string Append(string input, string @string)
  240. {
  241. return input == null
  242. ? input
  243. : input + @string;
  244. }
  245. /// <summary>
  246. /// Prepend a string to another
  247. /// </summary>
  248. /// <param name="input"></param>
  249. /// <param name="string"></param>
  250. /// <returns></returns>
  251. public static string Prepend(string input, string @string)
  252. {
  253. return input == null
  254. ? input
  255. : @string + input;
  256. }
  257. /// <summary>
  258. /// Add <br /> tags in front of all newlines in input string
  259. /// </summary>
  260. /// <param name="input"></param>
  261. /// <returns></returns>
  262. public static string NewlineToBr(string input)
  263. {
  264. return string.IsNullOrWhiteSpace(input)
  265. ? input
  266. : Regex.Replace(input, Environment.NewLine, "<br />" + Environment.NewLine);
  267. }
  268. /// <summary>
  269. /// Formats a date using a .NET date format string
  270. /// </summary>
  271. /// <param name="input"></param>
  272. /// <param name="format"></param>
  273. /// <returns></returns>
  274. public static string Date(object input, string format)
  275. {
  276. if (input == null)
  277. return null;
  278. if (format == null)
  279. return input.ToString();
  280. DateTime date;
  281. return DateTime.TryParse(input.ToString(), out date)
  282. ? date.ToString(format)
  283. : input.ToString();
  284. }
  285. /// <summary>
  286. /// Get the first element of the passed in array
  287. ///
  288. /// Example:
  289. /// {{ product.images | first | to_img }}
  290. /// </summary>
  291. /// <param name="array"></param>
  292. /// <returns></returns>
  293. public static object First(IEnumerable array)
  294. {
  295. if (array == null)
  296. return null;
  297. return array.Cast<object>().FirstOrDefault();
  298. }
  299. /// <summary>
  300. /// Get the last element of the passed in array
  301. ///
  302. /// Example:
  303. /// {{ product.images | last | to_img }}
  304. /// </summary>
  305. /// <param name="array"></param>
  306. /// <returns></returns>
  307. public static object Last(IEnumerable array)
  308. {
  309. if (array == null)
  310. return null;
  311. return array.Cast<object>().LastOrDefault();
  312. }
  313. /// <summary>
  314. /// Addition
  315. /// </summary>
  316. /// <param name="input"></param>
  317. /// <param name="operand"></param>
  318. /// <returns></returns>
  319. public static object Plus(object input, object operand)
  320. {
  321. return input is string
  322. ? string.Concat(input, operand)
  323. : DoMathsOperation(input, operand, Expression.Add);
  324. }
  325. /// <summary>
  326. /// Subtraction
  327. /// </summary>
  328. /// <param name="input"></param>
  329. /// <param name="operand"></param>
  330. /// <returns></returns>
  331. public static object Minus(object input, object operand)
  332. {
  333. return DoMathsOperation(input, operand, Expression.Subtract);
  334. }
  335. /// <summary>
  336. /// Multiplication
  337. /// </summary>
  338. /// <param name="input"></param>
  339. /// <param name="operand"></param>
  340. /// <returns></returns>
  341. public static object Times(object input, object operand)
  342. {
  343. return input is string && operand is int
  344. ? Enumerable.Repeat((string)input, (int)operand)
  345. : DoMathsOperation(input, operand, Expression.Multiply);
  346. }
  347. /// <summary>
  348. /// Division
  349. /// </summary>
  350. /// <param name="input"></param>
  351. /// <param name="operand"></param>
  352. /// <returns></returns>
  353. public static object DividedBy(object input, object operand)
  354. {
  355. return DoMathsOperation(input, operand, Expression.Divide);
  356. }
  357. private static object DoMathsOperation(object input, object operand, Func<Expression, Expression, BinaryExpression> operation)
  358. {
  359. return input == null || operand == null
  360. ? null
  361. : ExpressionUtility.CreateExpression(operation, input.GetType(), operand.GetType(), input.GetType(), true)
  362. .DynamicInvoke(input, operand);
  363. }
  364. }
  365. }