src/TemplateResolver.cs
Rama main · réplica de lectura del repositorio original.
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);
}
}
}