<commit_before>﻿using System;
using System.Collections.Generic;
using System.Linq;
using MailMergeLib.SmartFormatMail.Core.Extensions;
using MailMergeLib.SmartFormatMail.Core.Parsing;

namespace MailMergeLib.SmartFormatMail.Extensions
{
    public class TemplateFormatter : IFormatter
    {
        private readonly SmartFormatter _formatter;
        private readonly IDictionary<string, Format> _templates;
        public TemplateFormatter(SmartFormatter formatter)
        {
            _formatter = formatter;

            var stringComparer = formatter.Settings.GetCaseSensitivityComparer();
            _templates = new Dictionary<string, Format>(stringComparer);
        }
        public void Register(string templateName, string template)
        {
            var parsed = _formatter.Parser.ParseFormat(template, _formatter.GetNotEmptyFormatterExtensionNames());
            _templates.Add(templateName, parsed);
        }

        public bool Remove(string templateName)
        {
            return _templates.Remove(templateName);
        }

        private string[] names = { "template", "t" };
        public string[] Names { get { return names; } set { names = value; } }

        public bool TryEvaluateFormat(IFormattingInfo formattingInfo)
        {
            var templateName = formattingInfo.FormatterOptions;
            if (templateName == "")
            {
                if (formattingInfo.Format.HasNested)
                {
                    return false;
                }
                templateName = formattingInfo.Format.RawText;
            }
            
            Format template;
            if (!_templates.TryGetValue(templateName, out template))
            {
                if (Names.Contains(formattingInfo.Placeholder.FormatterName))
                {
                    // if the format contains the named formatter, we care for a more precise exception message
                    // instead of the generic "no formatter found"
                    throw new FormatException($"Formatter '{formattingInfo.Placeholder.FormatterName}' found no registered template named '{templateName}'");
                }

                return false;
            }

            formattingInfo.Write(template, formattingInfo.CurrentValue);
            return true;
        }

    }
}<commit_msg>Added a Clear() method to the TemplateFormatter (reverted from commit 31840109dee3e9289365a0bae868f39e767fd776) (reverted from commit 5<PASSWORD>5ddae3af1156ea1606e0ac)<commit_after>﻿using System;
using System.Collections.Generic;
using System.Linq;
using MailMergeLib.SmartFormatMail.Core.Extensions;
using MailMergeLib.SmartFormatMail.Core.Parsing;

namespace MailMergeLib.SmartFormatMail.Extensions
{
    /// <summary>
    /// Template Formatter allows for registering reusable templates, and use them by name.
    /// </summary>
    public class TemplateFormatter : IFormatter
    {
        private readonly SmartFormatter _formatter;
        private readonly IDictionary<string, Format> _templates;

        /// <summary>
        /// CTOR.
        /// </summary>
        /// <param name="formatter"></param>
        public TemplateFormatter(SmartFormatter formatter)
        {
            _formatter = formatter;

            var stringComparer = formatter.Settings.GetCaseSensitivityComparer();
            _templates = new Dictionary<string, Format>(stringComparer);
        }

        /// <summary>
        /// Register a new template.
        /// </summary>
        /// <param name="templateName">A name for the template, which is not already registered.</param>
        /// <param name="template">The string to be used as a template.</param>
        public void Register(string templateName, string template)
        {
            var parsed = _formatter.Parser.ParseFormat(template, _formatter.GetNotEmptyFormatterExtensionNames());
            _templates.Add(templateName, parsed);
        }

        /// <summary>
        /// Remove a template by its name.
        /// </summary>
        /// <param name="templateName"></param>
        /// <returns></returns>
        public bool Remove(string templateName)
        {
            return _templates.Remove(templateName);
        }

        /// <summary>
        /// Remove all templates.
        /// </summary>
        public void Clear()
        {
            _templates.Clear();
        }

        /// <summary>
        /// Gets or sets the name of the extension.
        /// </summary>
        public string[] Names { get; set; } = { "template", "t" };

        /// <summary>
        /// This method is called by the <see cref="SmartFormatter"/> to obtain the formatting result of this extension.
        /// </summary>
        /// <param name="formattingInfo"></param>
        /// <returns>Returns true if successful, else false.</returns>
        public bool TryEvaluateFormat(IFormattingInfo formattingInfo)
        {
            var templateName = formattingInfo.FormatterOptions;
            if (templateName == "")
            {
                if (formattingInfo.Format.HasNested)
                {
                    return false;
                }
                templateName = formattingInfo.Format.RawText;
            }
            
            Format template;
            if (!_templates.TryGetValue(templateName, out template))
            {
                if (Names.Contains(formattingInfo.Placeholder.FormatterName))
                {
                    // if the format contains the named formatter, we care for a more precise exception message
                    // instead of the generic "no formatter found"
                    throw new FormatException($"Formatter '{formattingInfo.Placeholder.FormatterName}' found no registered template named '{templateName}'");
                }

                return false;
            }

            formattingInfo.Write(template, formattingInfo.CurrentValue);
            return true;
        }
    }
}
{'fraction_non_alphanumeric': 0.09168622192423735, 'fraction_numerical': 0.00670465973851827, 'mean_word_length': 1.9568880079286421, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 1}}
{'dir': 'git-commits-cleaned', 'id': '2004991', 'n_tokens_mistral': 1466, 'n_tokens_neox': 1374, 'n_words': 368}