示例#1
0
        protected void Page_Load(object sender, EventArgs e)
        {
            NumberBoxLabel.Text = "Enter a number";

            if (IsPostBack)
            {
                int  NumberBoxNumber        = 0;
                bool NumberBoxNumberNumeric = int.TryParse(NumberBoxLabel.Text, out NumberBoxNumber);
                if (NumberBoxNumberNumeric)
                {
                    NumberBoxLabel.Text = NumberToWordsExtension.ToWords(NumberBoxNumber);
                }
            }
        }
        /// <summary>
        /// 1) Obtains a stream to the "SalarySlipTemplate.html" file from the "TemplateApp" application.
        /// 2) Replaces the pre-defined placeholders in the SalarySlipTemplate.html file with the employee details.
        /// 3) additionPayDetails list contains all the addition components except gross salary and netpay. Similarly, deductionPayDetails
        /// contains all the deduction components except the deduction total.
        /// 4) The additionTotal and the deductionTotal contain the values of the sum of all the addition components(gross salary) and the
        /// sum of all deduction components (deduction total) respectively.
        /// 5) The additionPayDetails and the deductionPayDetails are used first to contruct the html row and column structurehaving all
        /// the components except gross salary, total deduction and net pay. The three mentioned components are placed towards the end of
        /// the structure.
        /// 6)The net pay in words, the header and the footer values are also added to the structure towards the end.
        /// </summary>
        void CreateTemplate()
        {
            int           beginCounter    = -1;
            int           endCounter      = -1;
            int           largerListCount = 0;
            string        templateBody    = string.Empty;
            StringBuilder genericBuilder  = new StringBuilder();

            using (ITemplateProvider templateApplication = new TemplateProvider())
            {
                templateBody = templateApplication.SupplyTemplateStream().ReadToEnd();
            }

            templateBody = templateBody.Replace("$associateCode", _objInitialData.AssociateCode);
            templateBody = templateBody.Replace("$dateOfJoining", _objInitialData.DateOfJoining);
            templateBody = templateBody.Replace("$panNumber", _objInitialData.PanNumber);
            templateBody = templateBody.Replace("$name", _objInitialData.EmployeeName);
            templateBody = templateBody.Replace("$designation", _objInitialData.Designation);
            templateBody = templateBody.Replace("$accountNumber", _objInitialData.AccountNumber);
            templateBody = templateBody.Replace("$salary", _objInitialData.Salary);
            templateBody = templateBody.Replace("$month", _objInitialData.Month.ToUpper());
            templateBody = templateBody.Replace("$year", _objInitialData.Year);

            var additionPayDetails  = _objInitialData.ComputedRules.Where(a => (a.ComputationName == ComputationVariety.ADDITION) && (a.RuleName != Constants.netPay && a.RuleName != Constants.grossSalary)).ToArray();
            var deductionPayDetails = _objInitialData.ComputedRules.Where(a => (a.ComputationName == ComputationVariety.SUBTRACTION) && (a.RuleName != Constants.totalDeduction)).ToArray();
            var additionTotal       = _objInitialData.ComputedRules.Where(a => (a.ComputationName == ComputationVariety.ADDITION) && (a.RuleName == Constants.grossSalary)).ToArray();
            var deductionTotal      = _objInitialData.ComputedRules.Where(a => (a.ComputationName == ComputationVariety.SUBTRACTION) && (a.RuleName == Constants.totalDeduction)).ToArray();

            if ((additionPayDetails != null && additionPayDetails.Count() > 0) && (deductionPayDetails != null && deductionPayDetails.Count() > 0))
            {
                largerListCount = (additionPayDetails.Count() > deductionPayDetails.Count()) ? additionPayDetails.Count() : deductionPayDetails.Count();
            }

            for (int i = 0; i < largerListCount; i++)
            {
                if (beginCounter == -1)
                {
                    genericBuilder.Append("<tr class=\"alignment-style\">");
                    beginCounter++;
                }
                if ((beginCounter == 0))
                {
                    if (i < additionPayDetails.Count() && i < deductionPayDetails.Count())
                    {
                        if (additionPayDetails[i] != null && deductionPayDetails[i] != null)
                        {
                            genericBuilder.Append(string.Format("<td colspan = \"1\">{0}</td><td colspan = \"1\">{1}</td><td colspan = \"1\">{2}</td><td colspan = \"1\">{3}</td></tr>", additionPayDetails[i].RuleName, additionPayDetails[i].RuleValue, deductionPayDetails[i].RuleName, deductionPayDetails[i].RuleValue));

                            beginCounter = -1;
                            endCounter++;
                        }
                        else if (additionPayDetails[i] != null && deductionPayDetails[i] == null)
                        {
                            genericBuilder.Append(string.Format("<td colspan = \"1\">{0}</td><td colspan = \"1\">{1}</td><td colspan = \"1\">{2}</td><td colspan = \"1\">{2}</td></tr>", additionPayDetails[i].RuleName, additionPayDetails[i].RuleValue, string.Empty));
                            beginCounter = -1;
                            endCounter++;
                        }
                        else if (additionPayDetails[i] == null && deductionPayDetails[i] != null)
                        {
                            genericBuilder.Append(string.Format("<td colspan = \"1\">{0}</td><td colspan = \"1\">{0}</td><td colspan = \"2\">{1}</td><td colspan = \"1\">{2}</td></tr>", string.Empty, deductionPayDetails[i].RuleName, deductionPayDetails[i].RuleValue));
                            beginCounter = -1;
                            endCounter++;
                        }
                    }
                    else if (i < additionPayDetails.Count() && i >= deductionPayDetails.Count())
                    {
                        if (additionPayDetails[i] != null)
                        {
                            genericBuilder.Append(string.Format("<td colspan = \"1\">{0}</td><td colspan = \"1\">{1}</td><td colspan = \"1\">{2}</td><td colspan = \"1\">{2}</td></tr>", additionPayDetails[i].RuleName, additionPayDetails[i].RuleValue, string.Empty));
                            beginCounter = -1;
                            endCounter++;
                        }
                    }
                    else if (i == additionPayDetails.Count() && i < deductionPayDetails.Count())
                    {
                        if (deductionPayDetails[i] != null)
                        {
                            genericBuilder.Append(string.Format("<td colspan = \"1\">{0}</td><td colspan = \"1\">{0}</td><td colspan = \"1\">{1}</td><td colspan = \"1\">{2}</td></tr>", string.Empty, deductionPayDetails[i].RuleName, deductionPayDetails[i].RuleValue));
                            beginCounter = -1;
                            endCounter++;
                        }
                    }
                }
            }
            if (endCounter == largerListCount - 1)
            {
                if ((additionTotal != null && additionTotal.Count() > 0) && (deductionTotal != null && deductionTotal.Count() > 0))
                {
                    genericBuilder.Append(string.Format("<tr class=\"alignment-style\"><td colspan = \"1\">{0}</td><td colspan = \"1\">{1}</td><td colspan = \"1\">{2}</td><td colspan = \"1\">{3}</td></tr>", Constants.grossSalary, additionTotal[0].RuleValue, Constants.totalDeduction, deductionTotal[0].RuleValue));
                }
                else if ((additionTotal != null && additionTotal.Count() > 0) && (deductionTotal == null || deductionTotal.Count() == 0))
                {
                    genericBuilder.Append(string.Format("<tr class=\"alignment-style\"><td colspan = \"1\">{0}</td><td colspan = \"1\">{1}</td><td colspan = \"1\">{2}</td><td colspan = \"1\">{2}</td></tr>", Constants.grossSalary, additionPayDetails[0].RuleValue, string.Empty));
                }
                else if ((additionTotal == null || additionTotal.Count() == 0) && (deductionTotal != null && deductionTotal.Count() > 0))
                {
                    genericBuilder.Append(string.Format("<tr class=\"alignment-style\"><td colspan = \"1\">{0}</td><td colspan = \"1\">{0}</td><td colspan = \"1\">{1}</td><td colspan = \"1\">{2}</td></tr>", string.Empty, Constants.totalDeduction, deductionPayDetails[0].RuleValue));
                }
            }


            if (genericBuilder != null && genericBuilder.Length > 0)
            {
                templateBody = templateBody.Replace("$additionAndDeductionComponents", genericBuilder.ToString());
            }
            else
            {
                templateBody = templateBody.Replace("$additionAndDeductionComponents", string.Empty);
            }
            genericBuilder.Clear();

            var details = _objInitialData.ComputedRules.Where(a => a.RuleName == Constants.netPay).Select(a => a).ToList();
            //var ruleValue = details[0].RuleValue.ToString("#,#.##", System.Globalization.CultureInfo.CreateSpecificCulture("hi-IN"));
            //var ruleValueinDecimal = Convert.ToDecimal(ruleValue);
            var ruleValueinDecimal = details[0].RuleValue;

            genericBuilder.Append(string.Format("<tr class=\"alignment-style\"><td colspan=\"3\">{0}:</td><td colspan=\"1\">{1}</td></tr>", details[0].RuleName, ruleValueinDecimal));
            templateBody = templateBody.Replace("$netPay", genericBuilder.ToString());
            genericBuilder.Clear();
            var value = (NumberToWordsExtension.ToWords((long)ruleValueinDecimal)).Titleize();

            genericBuilder.Append(string.Format("<tr><td colspan=\"1\" class=\"left-alignment-style\">Net Pay in Words:</td><td colspan=\"3\" class=\"alignment-style-center\">{0}</td></tr>", value));
            templateBody = templateBody.Replace("$payInWords", genericBuilder.ToString());
            genericBuilder.Clear();
            templateBody = templateBody.Replace("$contentOfHeader", string.Format("<img src=\"{0}\" alt=\"{1}\">", ConfigurationManager.AppSettings[Constants.headerImage], "No Image Found"));
            templateBody = templateBody.Replace("$contentOfFooter", HelperMethods.FetchFooterContent() != null ? HelperMethods.FetchFooterContent() : string.Empty);
            _objInitialData.TemplateContent = templateBody;
        }
示例#3
0
        public static void Main(string[] args)
        {
            File.Copy("template/Collapse.docx", "Collapse.docx", true);
            var application1 =
                new Application()
                .setPaybackYears(20)
                .setUcCheck(true).setUcCheckResponse("Ok")
                .setApplicant(new Applicant("first applicant").setFrom("Google", 2012, 11));

            application1.getLoans().Add(new Loan("Big Bank", 10000, Color.Blue));
            application1.getLoans().Add(new Loan("Small Bank", 2000, Color.Lime));
            var application2 =
                new Application().hideLoans()
                .setPaybackYears(15)
                .setUcCheck(false)
                .setUcCheckResponse("Not good enough")
                .setApplicant(new Applicant("second applicant").setFrom("Apple", 2015, 12))
                .setCoApplicant(new Applicant("second co-applicant").setFromUntil("IBM", 2014, 11, 2015, 12));
            var application3 =
                new Application()
                .setPaybackYears(10)
                .setUcCheck(true).setUcCheckResponse("Ok")
                .setApplicant(new Applicant("third applicant").setFrom("Microsoft", 2010, 1));
            var factory = Configuration.Builder.Include((value, metadata, path, templater) =>
            {
                var str = value as string;
                if (str != null && metadata.StartsWith("collapseIf("))
                {
                    //Extract the matching expression
                    var expression = metadata.Substring("collapseIf(".Length, metadata.Length - "collapseIf(".Length - 1);
                    if (str == expression)
                    {
                        //remove the context around the specific property
                        templater.Resize(new[] { path }, 0);
                        return(true);
                    }
                }
                return(false);
            }).Include((value, metadata, property, templater) =>
            {
                if (value is IList && ("collapseNonEmpty" == metadata || "collapseEmpty" == metadata))
                {
                    var list = (IList)value;
                    //loop until all tags with the same name are processed
                    do
                    {
                        var md = templater.GetMetadata(property, false);
                        var collapseOnEmpty  = md.Contains("collapseEmpty");
                        var collapseNonEmpty = md.Contains("collapseNonEmpty");
                        if (list.Count == 0)
                        {
                            if (collapseOnEmpty)
                            {
                                templater.Resize(new[] { property }, 0);
                            }
                            else
                            {
                                templater.Replace(property, "");
                            }
                        }
                        else
                        {
                            if (collapseNonEmpty)
                            {
                                templater.Resize(new[] { property }, 0);
                            }
                            else
                            {
                                templater.Replace(property, "");
                            }
                        }
                    } while (templater.Tags.Contains(property));
                    //we want to stop further processing if list is empty
                    //otherwise we want to continue resizing list and processing it's elements
                    return(list.Count == 0);
                }
                return(false);
            }).Include(value =>
            {
                if (value is Color)
                {
                    var fillValue = ((Color)value).ToArgb().ToString("X4").Substring(2);
                    return(new XElement(
                               XName.Get("tc", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"),
                               new XElement(
                                   XName.Get("tcPr", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"),
                                   new XElement(
                                       XName.Get("shd", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"),
                                       new XAttribute(XName.Get("val", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"), "clear"),
                                       new XAttribute(XName.Get("color", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"), "auto"),
                                       new XAttribute(XName.Get("fill", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"), fillValue)))));
                }
                return(value);
            }).Include((value, metadata) =>
            {
                if ("verbalize" == metadata && value is decimal)
                {
                    var d = (decimal)value;
                    return(NumberToWordsExtension.ToWords((int)d, GrammaticalGender.Neuter, CultureInfo.CurrentUICulture));
                }
                return(value);
            }).Build();

            using (var doc = factory.Open("Collapse.docx"))
                doc.Process(new[] { application1, application2, application3 });
            Process.Start("Collapse.docx");
        }
示例#4
0
        public static void Main(string[] args)
        {
            File.Copy("template/Collapse.docx", "Collapse.docx", true);
            var application1 =
                new Application()
                .setPaybackYears(20)
                .setUcCheck(true).setUcCheckResponse("Ok")
                .setApplicant(new Applicant("first applicant").setFrom("Google", 2012, 11).addChild("Mary"));

            application1.getLoans().Add(new Loan("Big Bank", 10000, Color.Blue));
            application1.getLoans().Add(new Loan("Small Bank", 2000, Color.Lime));
            var application2 =
                new Application().hideLoans()
                .setPaybackYears(15)
                .setUcCheck(false)
                .setUcCheckResponse("Not good enough")
                .setApplicant(new Applicant("second applicant").setFrom("Apple", 2015, 12))
                .setCoApplicant(new Applicant("second co-applicant").setFromUntil("IBM", 2014, 11, 2015, 12));
            var application3 =
                new Application()
                .setPaybackYears(10)
                .setUcCheck(true).setUcCheckResponse("Ok")
                .setApplicant(new Applicant("third applicant").setFrom("Microsoft", 2010, 1).addChild("Jack").addChild("Jane"));
            var factory = Configuration.Builder.Include((value, metadata, path, position, templater) =>
            {
                var str = value as string;
                if (str != null && metadata.StartsWith("collapseIf("))
                {
                    //Extract the matching expression
                    var expression = metadata.Substring("collapseIf(".Length, metadata.Length - "collapseIf(".Length - 1);
                    if (str == expression)
                    {
                        //remove the context around the specific property
                        if (position == -1)
                        {
                            //when position is -1 it means non sharing tag is being used, in which case we can resize that region via "standard" API
                            templater.Resize(new[] { path }, 0);
                        }
                        else
                        {
                            //otherwise we need to use "advanced" resize API to specify which exact tag to replace
                            templater.Resize(new[] { new TagPosition(path, position) }, 0);
                        }
                        return(Handled.NestedTags);
                    }
                }
                return(Handled.Nothing);
            }).Include((value, metadata, tag, position, templater) =>
            {
                if (value is IList && ("collapseNonEmpty" == metadata || "collapseEmpty" == metadata))
                {
                    var list = (IList)value;
                    //loop until all tags with the same name are processed
                    do
                    {
                        var md = templater.GetMetadata(tag, false);
                        var collapseOnEmpty  = md.Contains("collapseEmpty");
                        var collapseNonEmpty = md.Contains("collapseNonEmpty");
                        if (list.Count == 0)
                        {
                            if (collapseOnEmpty)
                            {
                                //when position is -1 it means non sharing tag is being used, in which case we can resize that region via "standard" API
                                //otherwise we need to use "advanced" resize API to specify which exact tag to replace
                                if (position == -1)
                                {
                                    templater.Resize(new[] { tag }, 0);
                                }
                                else
                                {
                                    templater.Resize(new[] { new TagPosition(tag, position) }, 0);
                                }
                            }
                            else
                            {
                                //when position is -1 it means non sharing tag is being used, in which case we can just replace the first tag
                                //otherwise we can replace that exact tag via position API
                                //replacing the first tag is the same as calling replace(tag, 0, value)
                                if (position == -1)
                                {
                                    templater.Replace(tag, "");
                                }
                                else
                                {
                                    templater.Replace(tag, position, "");
                                }
                            }
                        }
                        else
                        {
                            if (collapseNonEmpty)
                            {
                                if (position == -1)
                                {
                                    templater.Resize(new[] { tag }, 0);
                                }
                                else
                                {
                                    templater.Resize(new[] { new TagPosition(tag, position) }, 0);
                                }
                            }
                            else
                            {
                                if (position == -1)
                                {
                                    templater.Replace(tag, "");
                                }
                                else
                                {
                                    templater.Replace(tag, position, "");
                                }
                            }
                        }
                    } while (templater.Tags.Contains(tag));
                    //we want to stop further processing if list is empty
                    //otherwise we want to continue resizing list and processing it's elements
                    return(list.Count == 0 ? Handled.NestedTags : Handled.Nothing);
                }
                return(Handled.Nothing);
            }).Include((value, tag, metadata) =>
            {
                if (value is Color)
                {
                    var fillValue = ((Color)value).ToArgb().ToString("X4").Substring(2);
                    return(new XElement(
                               XName.Get("tc", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"),
                               new XElement(
                                   XName.Get("tcPr", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"),
                                   new XElement(
                                       XName.Get("shd", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"),
                                       new XAttribute(XName.Get("val", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"), "clear"),
                                       new XAttribute(XName.Get("color", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"), "auto"),
                                       new XAttribute(XName.Get("fill", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"), fillValue)))));
                }
                return(value);
            }).Include((value, metadata, tag, position, templater) =>
            {
                if ("leaveIfEmpty" == metadata && value is IList)
                {
                    var list = (IList)value;
                    if (list.Count == 0)
                    {
                        //when list is empty we want to leave the default message
                        templater.Replace(tag, "");
                    }
                    else
                    {
                        //when list is not empty, we will remove the default message
                        templater.Resize(new[] { tag }, 0);
                    }
                    //indicates that only this tag was handled,
                    //so Templater will either duplicate or remove other tags from this collection
                    return(Handled.ThisTag);
                }
                return(Handled.Nothing);
            }).Include((value, metadata) =>
            {
                if ("verbalize" == metadata && value is decimal)
                {
                    var d = (decimal)value;
                    return(NumberToWordsExtension.ToWords((int)d, GrammaticalGender.Neuter, CultureInfo.CurrentUICulture));
                }
                return(value);
            }).Build();

            using (var doc = factory.Open("Collapse.docx"))
            {
                //manually invoke resize 0 on a tag. ideally this would be some boolean flag/empty collection
                doc.Templater.Resize(new[] { "remove_me" }, 0);
                doc.Process(new[] { application1, application2, application3 });
            }
            Process.Start(new ProcessStartInfo("Collapse.docx")
            {
                UseShellExecute = true
            });
        }
示例#5
0
        public static void Register()
        {
            // case functions
            Expression.Functions.Add($"humanizer.allCaps", (args) => CasingExtensions.ApplyCase(args[0], LetterCasing.AllCaps));
            Expression.Functions.Add($"humanizer.lowerCase", (args) => CasingExtensions.ApplyCase(args[0], LetterCasing.LowerCase));
            Expression.Functions.Add($"humanizer.sentence", (args) => CasingExtensions.ApplyCase(args[0], LetterCasing.Sentence));
            Expression.Functions.Add($"humanizer.title", (args) => CasingExtensions.ApplyCase(args[0], LetterCasing.Title));

            // humanize collections
            Expression.Functions.Add($"humanizer.humanizeList", (args) =>
            {
                CollectionHumanizeExtensions.Humanize <object>(args[0], args[1]);
                return(string.Empty);
            });

            // DateTime functions
            Expression.Functions.Add($"humanizer.humanizeDateTime", (args) =>
            {
                var culture       = ParseCulture(args);
                var referenceDate = ParseDate((object)args.Skip(1).FirstOrDefault());

                if (referenceDate.HasValue)
                {
                    return(DateHumanizeExtensions.Humanize(ParseDate(args[0]), referenceDate.Value, culture));
                }

                return(DateHumanizeExtensions.Humanize(ParseDate(args[0]), culture: culture));
            });

            Expression.Functions.Add($"humanizer.dateTimeToOrdinalWords", (args) =>
            {
                if (args.Count == 2)
                {
                    return(DateToOrdinalWordsExtensions.ToOrdinalWords(ParseDate(args[0]), ParseEnum <GrammaticalCase>(args.Skip(1).FirstOrDefault())));
                }
                return(DateToOrdinalWordsExtensions.ToOrdinalWords(ParseDate(args[0])));
            });

            // timespan functions
            Expression.Functions.Add($"humanizer.humanizeTimeSpan", (args) =>
            {
                var culture   = ParseCulture(args);
                var precision = (int)ParseInt(args.Skip(1).FirstOrDefault(), 1);
                return(TimeSpanHumanizeExtensions.Humanize(timeSpan: ParseTimeSpan(args[0]), precision: precision, culture: culture));
            });
            Expression.Functions.Add($"humanizer.weeks", (args) => NumberToTimeSpanExtensions.Weeks(ParseNumber((object)args[0])));
            Expression.Functions.Add($"humanizer.days", (args) => NumberToTimeSpanExtensions.Days(ParseNumber((object)args[0])));
            Expression.Functions.Add($"humanizer.hours", (args) => NumberToTimeSpanExtensions.Hours(ParseNumber((object)args[0])));
            Expression.Functions.Add($"humanizer.minutes", (args) => NumberToTimeSpanExtensions.Minutes(ParseNumber((object)args[0])));
            Expression.Functions.Add($"humanizer.seconds", (args) => NumberToTimeSpanExtensions.Seconds(ParseNumber((object)args[0])));
            Expression.Functions.Add($"humanizer.milliseconds", (args) => NumberToTimeSpanExtensions.Milliseconds(ParseNumber((object)args[0])));

            // bytesize functions
            Expression.Functions.Add($"humanizer.bits", (args) => ByteSizeExtensions.Bits(ParseInt((object)args[0])).ToString());
            Expression.Functions.Add($"humanizer.bytes", (args) => ByteSizeExtensions.Bytes(ParseNumber((object)args[0])).ToString());
            Expression.Functions.Add($"humanizer.kilobytes", (args) => ByteSizeExtensions.Kilobytes(ParseNumber((object)args[0])).ToString());
            Expression.Functions.Add($"humanizer.megabytes", (args) => ByteSizeExtensions.Megabytes(ParseNumber((object)args[0])).ToString());
            Expression.Functions.Add($"humanizer.gigabytes", (args) => ByteSizeExtensions.Gigabytes(ParseNumber((object)args[0])).ToString());
            Expression.Functions.Add($"humanizer.terabytes", (args) => ByteSizeExtensions.Terabytes(ParseNumber((object)args[0])).ToString());

            // headings (float => North) "north" => float
            Expression.Functions.Add($"humanizer.degrees2heading", (args) =>
            {
                var culture = ParseCulture(args);

                if (TryParseEnum <HeadingStyle>((object)args.Skip(1).FirstOrDefault(), out var style))
                {
                    return(HeadingExtensions.ToHeading(ParseNumber((object)args[0]), style, culture: culture));
                }
                return(HeadingExtensions.ToHeading(ParseNumber((object)args[0]), culture: culture));
            });
            Expression.Functions.Add($"humanizer.heading2degrees", (args) => HeadingExtensions.FromAbbreviatedHeading((string)args[0].ToString()));

            // inflector
            Expression.Functions.Add($"humanizer.pluralize", (args) => InflectorExtensions.Pluralize(((object)args[0]).ToString(), ParseBool(args.Skip(1).FirstOrDefault())));
            Expression.Functions.Add($"humanizer.camelize", (args) => InflectorExtensions.Camelize(((object)args[0]).ToString()));
            Expression.Functions.Add($"humanizer.dasherize", (args) => InflectorExtensions.Dasherize(((object)args[0]).ToString()));
            Expression.Functions.Add($"humanizer.hyphenate", (args) => InflectorExtensions.Hyphenate(((object)args[0]).ToString()));
            Expression.Functions.Add($"humanizer.kebaberize", (args) => InflectorExtensions.Kebaberize(((object)args[0]).ToString()));
            Expression.Functions.Add($"humanizer.pascalize", (args) => InflectorExtensions.Pascalize(((object)args[0]).ToString()));
            Expression.Functions.Add($"humanizer.singularize", (args) => InflectorExtensions.Singularize(((object)args[0]).ToString(), ParseBool(args.Skip(1).FirstOrDefault(), true), ParseBool(args.Skip(2).FirstOrDefault())));
            Expression.Functions.Add($"humanizer.titleize", (args) => InflectorExtensions.Titleize(((object)args[0]).ToString()));

            // metric
            Expression.Functions.Add($"humanizer.metric2number", (args) => MetricNumeralExtensions.FromMetric(((object)args[0]).ToString()));
            Expression.Functions.Add($"humanizer.number2metric", (args) =>
            {
                if (args.Count == 4)
                {
                    return(MetricNumeralExtensions.ToMetric(ParseNumber(args[0]), hasSpace: ParseBool(args[2]), useSymbol: ParseBool(args[3]), decimals: (Int32)ParseInt(args[1])));
                }
                else if (args.Count == 3)
                {
                    return(MetricNumeralExtensions.ToMetric(ParseNumber(args[0]), hasSpace: ParseBool(args[2]), decimals: (Int32)ParseInt(args[1])));
                }
                else if (args.Count == 2)
                {
                    return(MetricNumeralExtensions.ToMetric(ParseNumber(args[0]), decimals: (Int32)ParseInt(args[1])));
                }

                return(MetricNumeralExtensions.ToMetric(ParseNumber(args[0])));
            });

            // numberToWords functions
            Expression.Functions.Add($"humanizer.number2words", (args) =>
            {
                var culture = ParseCulture(args);
                if (TryParseEnum <GrammaticalGender>((object)args.Skip(1).FirstOrDefault(), out var enm))
                {
                    return(NumberToWordsExtension.ToWords(ParseInt(args[0]), enm, culture: culture));
                }
                return(NumberToWordsExtension.ToWords(ParseInt(args[0]), culture: culture));
            });

            Expression.Functions.Add($"humanizer.number2ordinalWords", (args) =>
            {
                var culture = ParseCulture(args);

                if (TryParseEnum <GrammaticalGender>((object)args.Skip(1).FirstOrDefault(), out var gender))
                {
                    return(NumberToWordsExtension.ToOrdinalWords((Int32)ParseInt(args[0]), gender, culture: culture));
                }

                return(NumberToWordsExtension.ToOrdinalWords((Int32)ParseInt(args[0]), culture: culture));
            });

            Expression.Functions.Add($"humanizer.number2ordinal", (args) =>
            {
                var culture = ParseCulture(args);

                if (TryParseEnum <GrammaticalGender>((object)args.Skip(1).FirstOrDefault(), out var gender))
                {
                    return(OrdinalizeExtensions.Ordinalize((Int32)ParseInt(args[0]), gender, culture: culture));
                }

                return(OrdinalizeExtensions.Ordinalize((Int32)ParseInt(args[0]), culture: culture));
            });

            // roman functions
            Expression.Functions.Add($"humanizer.fromRoman", (args) => RomanNumeralExtensions.FromRoman(((object)args[0]).ToString()));
            Expression.Functions.Add($"humanizer.toRoman", (args) => RomanNumeralExtensions.ToRoman((Int32)ParseInt(args[0])));

            // toQuantity functions
            Expression.Functions.Add($"humanizer.toQuantity", (args) =>
            {
                if (args.Count == 3)
                {
                    string arg3 = ((object)args[2]).ToString();
                    if (Enum.TryParse <ShowQuantityAs>(arg3, out var showQuanityAs))
                    {
                        return(ToQuantityExtensions.ToQuantity(((object)args[0]).ToString(), ParseInt(args[1]), showQuanityAs));
                    }

                    // use arg[2] as format string
                    return(ToQuantityExtensions.ToQuantity(((object)args[0]).ToString(), ParseInt(args[1]), format: arg3));
                }

                if (args.Count == 3)
                {
                    return(ToQuantityExtensions.ToQuantity(((object)args[0]).ToString(), ParseInt(args[1]), ParseEnum <ShowQuantityAs>(args[2])));
                }

                return(ToQuantityExtensions.ToQuantity(((object)args[0]).ToString(), ParseInt(args[1])));
            });

            // truncate functions
            Expression.Functions.Add($"humanizer.truncate", (args) =>
            {
                if (args.Count == 3)
                {
                    return(TruncateExtensions.Truncate(((object)args[0]).ToString(), (int)ParseInt(args[1]), ((object)args[2]).ToString()));
                }
                return(TruncateExtensions.Truncate(((object)args[0]).ToString(), (int)ParseInt(args[1])));
            });

            Expression.Functions.Add($"humanizer.truncateWords", (args) =>
            {
                if (args.Count == 3)
                {
                    return(TruncateExtensions.Truncate(((object)args[0]).ToString(), (int)ParseInt(args[1]), ((object)args[2]).ToString(), truncator: Truncator.FixedNumberOfWords));
                }
                return(TruncateExtensions.Truncate(((object)args[0]).ToString(), (int)ParseInt(args[1]), truncator: Truncator.FixedNumberOfWords));
            });

            // tupelize functions
            Expression.Functions.Add($"humanizer.tupleize", (args) => TupleizeExtensions.Tupleize((int)ParseInt(args[0])));

            // dotnet format functions
            Expression.Functions.Add($"dotnet.numberToString", (args) =>
            {
                var culture = ParseCulture(args);
                var number  = ParseNumber((object)args[0]);
                var format  = ((object)args[1]).ToString();
                return(number.ToString(format, culture));
            });
            Expression.Functions.Add($"dotnet.intToString", (args) =>
            {
                var culture = ParseCulture(args);
                var integer = ParseInt((object)args[0]);
                var format  = ((object)args[1]).ToString();
                return(integer.ToString(format, culture));
            });
            Expression.Functions.Add($"dotnet.dateTimeToString", (args) =>
            {
                var culture  = ParseCulture(args);
                var dateTime = ParseDate((object)args[0]);
                var format   = ((object)args[1]).ToString();
                return(dateTime.Value.ToString(format, culture));
            });
            Expression.Functions.Add($"dotnet.timeSpanToString", (args) =>
            {
                var culture  = ParseCulture(args);
                var timeSpan = ParseTimeSpan((object)args[0]);
                var format   = ((object)args[1]).ToString();
                return(timeSpan.Value.ToString(format, culture));
            });
        }