Ctrl K
ComunidadGuías…

src/TemplateResolver.cs

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
using System;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;

namespace Clipman
{
    internal static class TemplateResolver
    {
        private static readonly Regex VariablePattern = new Regex(@"\{\{([A-Za-z0-9_]+)\}\}", RegexOptions.Compiled);

        public sealed class TemplateItem
        {
            public string Name { get; private set; }
            public string Text { get; private set; }

            public TemplateItem(string name, string text)
            {
                Name = name ?? string.Empty;
                Text = text ?? string.Empty;
            }

            public override string ToString()
            {
                return Name;
            }
        }

        public static readonly TemplateItem[] Presets =
        {
            new TemplateItem("Date, year/month/day", "{{year_full}}/{{month_num_padded}}/{{day_of_month_padded}}"),
            new TemplateItem("Date, day short-month year", "{{day_of_month_padded}} {{month_name_short}} {{year_full}}"),
            new TemplateItem("Date, short-month day, year", "{{month_name_short}} {{day_of_month_padded}}, {{year_full}}"),
            new TemplateItem("Today sentence", "Today is {{day_name_full}}, {{month_name_full}} {{day_of_month}}, {{year_full}}"),
            new TemplateItem("Operating system version", "{{os_name}} version {{os_version}}")
        };

        public static readonly TemplateItem[] Variables =
        {
            new TemplateItem("Year, four digits", "{{year_full}}"),
            new TemplateItem("Year, two digits", "{{year_short}}"),
            new TemplateItem("Month name", "{{month_name_full}}"),
            new TemplateItem("Month name, short", "{{month_name_short}}"),
            new TemplateItem("Month number", "{{month_num}}"),
            new TemplateItem("Month number, two digits", "{{month_num_padded}}"),
            new TemplateItem("Day of month", "{{day_of_month}}"),
            new TemplateItem("Day of month, two digits", "{{day_of_month_padded}}"),
            new TemplateItem("Day name", "{{day_name_full}}"),
            new TemplateItem("Day name, short", "{{day_name_short}}"),
            new TemplateItem("Hour, 24-hour clock", "{{hour_24}}"),
            new TemplateItem("Hour, 24-hour clock, two digits", "{{hour_24_padded}}"),
            new TemplateItem("Hour, 12-hour clock", "{{hour_12}}"),
            new TemplateItem("Hour, 12-hour clock, two digits", "{{hour_12_padded}}"),
            new TemplateItem("Minute", "{{minute}}"),
            new TemplateItem("Minute, two digits", "{{minute_padded}}"),
            new TemplateItem("Second", "{{second}}"),
            new TemplateItem("Second, two digits", "{{second_padded}}"),
            new TemplateItem("UTC offset", "{{utc_offset}}"),
            new TemplateItem("Time zone", "{{time_zone}}"),
            new TemplateItem("Time zone, short", "{{time_zone_short}}"),
            new TemplateItem("Operating system name", "{{os_name}}"),
            new TemplateItem("Operating system version", "{{os_version}}"),
            new TemplateItem("User name", "{{username}}")
        };

        public static readonly string VariableReferenceText =
            "Template variables are resolved only when the entry is copied or pasted.\r\n\r\n" +
            "Presets:\r\n" +
            string.Join("\r\n", Presets.Select(p => p.Name + " - " + p.Text).ToArray()) +
            "\r\n\r\n" +
            "Date and time:\r\n" +
            "{{year_full}} - four-digit year\r\n" +
            "{{year_short}} - two-digit year\r\n" +
            "{{month_name}} - full month name\r\n" +
            "{{month_name_full}} - full month name\r\n" +
            "{{month_name_short}} - short month name\r\n" +
            "{{month_num}} - month number\r\n" +
            "{{month_num_padded}} - two-digit month number\r\n" +
            "{{day_of_month}} - day of month\r\n" +
            "{{day_of_month_padded}} - two-digit day of month\r\n" +
            "{{day_name_full}} - full day name\r\n" +
            "{{day_name_short}} - short day name\r\n" +
            "{{hour_24}} - 24-hour clock hour\r\n" +
            "{{hour_24_padded}} - two-digit 24-hour clock hour\r\n" +
            "{{hour_12}} - 12-hour clock hour\r\n" +
            "{{hour_12_padded}} - two-digit 12-hour clock hour\r\n" +
            "{{minute}} - minute\r\n" +
            "{{minute_padded}} - two-digit minute\r\n" +
            "{{second}} - second\r\n" +
            "{{second_padded}} - two-digit second\r\n" +
            "{{utc_offset}} - local UTC offset\r\n" +
            "{{time_zone}} - local time zone name\r\n" +
            "{{time_zone_short}} - local time zone abbreviation\r\n\r\n" +
            "System:\r\n" +
            "{{os_name}} - operating system name\r\n" +
            "{{os_version}} - operating system version\r\n" +
            "{{username}} - current user name\r\n\r\n" +
            "Examples:\r\n" +
            "{{year_full}}-{{month_num_padded}}-{{day_of_month_padded}}\r\n" +
            "Today is {{day_name_full}}, {{month_name_full}} {{day_of_month}}, {{year_full}}\r\n" +
            "{{os_name}} version {{os_version}}";

        public static string Resolve(string text)
        {
            if (string.IsNullOrEmpty(text)) return string.Empty;
            var now = DateTime.Now;
            var culture = CultureInfo.CurrentCulture;
            return VariablePattern.Replace(text, match =>
            {
                var name = match.Groups[1].Value;
                var value = ResolveVariable(name, now, culture);
                return value == null ? match.Value : value;
            });
        }

        private static string ResolveVariable(string name, DateTime now, CultureInfo culture)
        {
            switch ((name ?? string.Empty).Trim().ToLowerInvariant())
            {
                case "year_full": return now.ToString("yyyy", culture);
                case "year_short": return now.ToString("yy", culture);
                case "month_name":
                case "month_name_full": return culture.DateTimeFormat.GetMonthName(now.Month);
                case "month_name_short": return culture.DateTimeFormat.GetAbbreviatedMonthName(now.Month);
                case "month_num": return now.Month.ToString(culture);
                case "month_num_padded": return now.Month.ToString("00", culture);
                case "day_of_month": return now.Day.ToString(culture);
                case "day_of_month_padded": return now.Day.ToString("00", culture);
                case "day_name_full": return culture.DateTimeFormat.GetDayName(now.DayOfWeek);
                case "day_name_short": return culture.DateTimeFormat.GetAbbreviatedDayName(now.DayOfWeek);
                case "hour_24": return now.Hour.ToString(culture);
                case "hour_24_padded": return now.Hour.ToString("00", culture);
                case "hour_12": return ToTwelveHour(now.Hour).ToString(culture);
                case "hour_12_padded": return ToTwelveHour(now.Hour).ToString("00", culture);
                case "minute": return now.Minute.ToString(culture);
                case "minute_padded": return now.Minute.ToString("00", culture);
                case "second": return now.Second.ToString(culture);
                case "second_padded": return now.Second.ToString("00", culture);
                case "utc_offset": return UtcOffsetText(TimeZoneInfo.Local.GetUtcOffset(now));
                case "time_zone": return TimeZoneName(now);
                case "time_zone_short": return TimeZoneShortName(TimeZoneName(now));
                case "os_name": return "Windows";
                case "os_version": return Environment.OSVersion.VersionString;
                case "username": return Environment.UserName;
                default: return null;
            }
        }

        private static int ToTwelveHour(int hour)
        {
            var value = hour % 12;
            return value == 0 ? 12 : value;
        }

        private static string UtcOffsetText(TimeSpan offset)
        {
            var sign = offset < TimeSpan.Zero ? "-" : "+";
            offset = offset.Duration();
            return sign + ((int)offset.TotalHours).ToString(CultureInfo.InvariantCulture) + ":" + offset.Minutes.ToString("00", CultureInfo.InvariantCulture);
        }

        private static string TimeZoneName(DateTime now)
        {
            return TimeZoneInfo.Local.IsDaylightSavingTime(now)
                ? TimeZoneInfo.Local.DaylightName
                : TimeZoneInfo.Local.StandardName;
        }

        private static string TimeZoneShortName(string name)
        {
            if (string.IsNullOrWhiteSpace(name)) return string.Empty;
            var letters = name
                .Split(new[] { ' ', '-', '_' }, StringSplitOptions.RemoveEmptyEntries)
                .Where(part => part.Length > 0)
                .Select(part => char.ToUpperInvariant(part[0]))
                .ToArray();
            return letters.Length == 0 ? name : new string(letters);
        }
    }
}