diff --git a/.gitignore b/.gitignore index e895975..5e80aab 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,4 @@ # ============== Project specific ignores src/packages build +/src/.vs/* diff --git a/nuget/Chronic.NetStandard.nuspec b/nuget/Chronic.NetStandard.nuspec new file mode 100644 index 0000000..2a61dbc --- /dev/null +++ b/nuget/Chronic.NetStandard.nuspec @@ -0,0 +1,22 @@ + + + + Chronic.Netstandard + 0.3.2 + Robert Wilczynski + Robert Wilczynski + https://raw.github.com/robertwilczynski/nChronic/master/LICENSE + https://github.com/robertwilczynski/nChronic + https://raw.github.com/robertwilczynski/nChronic/master/doc/chronic.png + false + A natural language date parser for .Net. A port of Ruby's chronic. + Initial release. + Copyright Robert Wilczynski 2011-2016 + date time parsing DateTime chronic natural language signed + + + + + + + diff --git a/src/Chronic/Chronic.NetStandard.csproj b/src/Chronic/Chronic.NetStandard.csproj new file mode 100644 index 0000000..d9bbab8 --- /dev/null +++ b/src/Chronic/Chronic.NetStandard.csproj @@ -0,0 +1,8 @@ + + + + netstandard2.0 + false + + + diff --git a/src/Chronic/Tags/GrabberScanner.cs b/src/Chronic/Tags/GrabberScanner.cs index 3901585..7c0987b 100644 --- a/src/Chronic/Tags/GrabberScanner.cs +++ b/src/Chronic/Tags/GrabberScanner.cs @@ -4,14 +4,20 @@ namespace Chronic { public class GrabberScanner : ITokenScanner { - static readonly dynamic[] _matches = new dynamic[] - { - new { Pattern = "last", Tag = new Grabber(Grabber.Type.Last) }, - new { Pattern = "next", Tag = new Grabber(Grabber.Type.Next) }, - new { Pattern = "this", Tag = new Grabber(Grabber.Type.This) } - }; + static readonly PatternGrabber[] _matches = new PatternGrabber[] + { + new PatternGrabber() { Pattern = "last", Tag = new Grabber(Grabber.Type.Last) }, + new PatternGrabber() { Pattern = "next", Tag = new Grabber(Grabber.Type.Next) }, + new PatternGrabber() { Pattern = "this", Tag = new Grabber(Grabber.Type.This) } + }; + + public class PatternGrabber + { + public string Pattern { get; set; } + public Grabber Tag { get; set; } + } - public IList Scan(IList tokens, Options options) + public IList Scan(IList tokens, Options options) { tokens.ForEach(ApplyGrabberTags); return tokens; diff --git a/src/Chronic/Tags/PointerScanner.cs b/src/Chronic/Tags/PointerScanner.cs index b396947..5787506 100644 --- a/src/Chronic/Tags/PointerScanner.cs +++ b/src/Chronic/Tags/PointerScanner.cs @@ -5,14 +5,20 @@ namespace Chronic { public class PointerScanner : ITokenScanner { - static readonly dynamic[] Patterns = new dynamic[] - { - new { Pattern = new Regex(@"\bin\b"), Tag = new Pointer(Pointer.Type.Future) }, - new { Pattern = new Regex(@"\bfuture\b"), Tag = new Pointer(Pointer.Type.Future) }, - new { Pattern = new Regex(@"\bpast\b"), Tag = new Pointer(Pointer.Type.Past) }, - }; + static readonly PatternPointer[] Patterns = new PatternPointer[] + { + new PatternPointer() { Pattern = new Regex(@"\bin\b"), Tag = new Pointer(Pointer.Type.Future) }, + new PatternPointer() { Pattern = new Regex(@"\bfuture\b"), Tag = new Pointer(Pointer.Type.Future) }, + new PatternPointer() { Pattern = new Regex(@"\bpast\b"), Tag = new Pointer(Pointer.Type.Past) }, + }; + + public class PatternPointer + { + public Regex Pattern { get; set; } + public Pointer Tag { get; set; } + } - public IList Scan(IList tokens, Options options) + public IList Scan(IList tokens, Options options) { tokens.ForEach(ApplyTags); return tokens; diff --git a/src/Chronic/Tags/Repeaters/RepeaterScanner.cs b/src/Chronic/Tags/Repeaters/RepeaterScanner.cs index cfba2ab..c65e931 100644 --- a/src/Chronic/Tags/Repeaters/RepeaterScanner.cs +++ b/src/Chronic/Tags/Repeaters/RepeaterScanner.cs @@ -126,62 +126,81 @@ static ITag ScanSeasonNames(Token token, Options options) static readonly Regex _timePattern = @"^\d{1,2}(:?\d{2})?([\.:]?\d{2})?$".Compile(); - static readonly List DayPortionPatterns = new List - { - new {Pattern = "^ams?$".Compile(), Portion = DayPortion.AM}, - new {Pattern = "^pms?$".Compile(), Portion = DayPortion.PM}, - new {Pattern = "^mornings?$".Compile(), Portion = DayPortion.MORNING}, - new {Pattern = "^afternoons?$".Compile(), Portion = DayPortion.AFTERNOON}, - new {Pattern = "^evenings?$".Compile(), Portion = DayPortion.EVENING}, - new {Pattern = "^(night|nite)s?$".Compile(), Portion = DayPortion.NIGHT}, - }; - - static readonly List DayPatterns = new List - { - new {Pattern ="^m[ou]n(day)?$".Compile(), Day = DayOfWeek.Monday}, - new {Pattern = "^t(ue|eu|oo|u|)s(day)?$".Compile(), Day = DayOfWeek.Tuesday}, - new {Pattern = "^tue$".Compile(), Day = DayOfWeek.Tuesday}, - new {Pattern = "^we(dnes|nds|nns)day$".Compile(), Day = DayOfWeek.Wednesday}, - new {Pattern = "^wed$".Compile(), Day = DayOfWeek.Wednesday}, - new {Pattern = "^th(urs|ers)day$".Compile(), Day = DayOfWeek.Thursday}, - new {Pattern = "^thu$".Compile(), Day = DayOfWeek.Thursday}, - new {Pattern = "^fr[iy](day)?$".Compile(), Day = DayOfWeek.Friday}, - new {Pattern = "^sat(t?[ue]rday)?$".Compile(), Day = DayOfWeek.Saturday}, - new {Pattern = "^su[nm](day)?$".Compile(), Day = DayOfWeek.Sunday}, - }; - - static readonly List MonthPatterns = new List - { - new {Pattern = "^jan\\.?(uary)?$".Compile(), Month = MonthName.January}, - new {Pattern = "^feb\\.?(ruary)?$".Compile(), Month = MonthName.February}, - new {Pattern = "^mar\\.?(ch)?$".Compile(), Month = MonthName.March}, - new {Pattern = "^apr\\.?(il)?$".Compile(), Month = MonthName.April}, - new {Pattern = "^may$".Compile(), Month = MonthName.May}, - new {Pattern = "^jun\\.?e?$".Compile(), Month = MonthName.June}, - new {Pattern = "^jul\\.?y?$".Compile(), Month = MonthName.July}, - new {Pattern = "^aug\\.?(ust)?$".Compile(), Month = MonthName.August}, - new - { - Pattern = "^sep\\.?(t\\.?|tember)?$".Compile(), - Month = MonthName.September - }, - new {Pattern = "^oct\\.?(ober)?$".Compile(), Month = MonthName.October}, - new {Pattern = "^nov\\.?(ember)?$".Compile(), Month = MonthName.November}, - new {Pattern = "^dec\\.?(ember)?$".Compile(), Month = MonthName.December}, - }; - - static readonly List UnitPatterns = new List - { - new { Pattern = "^years?$".Compile(), Unit = typeof(RepeaterYear) }, - new { Pattern = "^seasons?$".Compile(), Unit = typeof(RepeaterSeason) }, - new { Pattern = "^months?$".Compile(), Unit = typeof(RepeaterMonth) }, - new { Pattern = "^fortnights?$".Compile(), Unit = typeof(RepeaterFortnight) }, - new { Pattern = "^weeks?$".Compile(), Unit = typeof(RepeaterWeek) }, - new { Pattern = "^weekends?$".Compile(), Unit = typeof(RepeaterWeekend) }, - new { Pattern = "^days?$".Compile(), Unit = typeof(RepeaterDay) }, - new { Pattern = "^hours?$".Compile(), Unit = typeof(RepeaterHour) }, - new { Pattern = "^minutes?$".Compile(), Unit = typeof(RepeaterMinute) }, - new { Pattern = "^seconds?$".Compile(), Unit = typeof(RepeaterSecond) } - }; - } + static readonly List DayPortionPatterns = new List + { + new PatternDayPortion() {Pattern = "^ams?$".Compile(), Portion = DayPortion.AM}, + new PatternDayPortion() {Pattern = "^pms?$".Compile(), Portion = DayPortion.PM}, + new PatternDayPortion() {Pattern = "^mornings?$".Compile(), Portion = DayPortion.MORNING}, + new PatternDayPortion() {Pattern = "^afternoons?$".Compile(), Portion = DayPortion.AFTERNOON}, + new PatternDayPortion() {Pattern = "^evenings?$".Compile(), Portion = DayPortion.EVENING}, + new PatternDayPortion() {Pattern = "^(night|nite)s?$".Compile(), Portion = DayPortion.NIGHT}, + }; + public class PatternDayPortion + { + public Regex Pattern { get; set; } + public DayPortion Portion { get; set; } + } + static readonly List DayPatterns = new List + { + new PatternDay() {Pattern ="^m[ou]n(day)?$".Compile(), Day = DayOfWeek.Monday}, + new PatternDay() {Pattern = "^t(ue|eu|oo|u|)s(day)?$".Compile(), Day = DayOfWeek.Tuesday}, + new PatternDay() {Pattern = "^tue$".Compile(), Day = DayOfWeek.Tuesday}, + new PatternDay() {Pattern = "^we(dnes|nds|nns)day$".Compile(), Day = DayOfWeek.Wednesday}, + new PatternDay() {Pattern = "^wed$".Compile(), Day = DayOfWeek.Wednesday}, + new PatternDay() {Pattern = "^th(urs|ers)day$".Compile(), Day = DayOfWeek.Thursday}, + new PatternDay() {Pattern = "^thu$".Compile(), Day = DayOfWeek.Thursday}, + new PatternDay() {Pattern = "^fr[iy](day)?$".Compile(), Day = DayOfWeek.Friday}, + new PatternDay() {Pattern = "^sat(t?[ue]rday)?$".Compile(), Day = DayOfWeek.Saturday}, + new PatternDay() {Pattern = "^su[nm](day)?$".Compile(), Day = DayOfWeek.Sunday}, + }; + public class PatternDay + { + public Regex Pattern { get; set; } + public DayOfWeek Day { get; set; } + } + static readonly List MonthPatterns = new List + { + new PatternMonth() {Pattern = "^jan\\.?(uary)?$".Compile(), Month = MonthName.January}, + new PatternMonth() {Pattern = "^feb\\.?(ruary)?$".Compile(), Month = MonthName.February}, + new PatternMonth() {Pattern = "^mar\\.?(ch)?$".Compile(), Month = MonthName.March}, + new PatternMonth() {Pattern = "^apr\\.?(il)?$".Compile(), Month = MonthName.April}, + new PatternMonth() {Pattern = "^may$".Compile(), Month = MonthName.May}, + new PatternMonth() {Pattern = "^jun\\.?e?$".Compile(), Month = MonthName.June}, + new PatternMonth() {Pattern = "^jul\\.?y?$".Compile(), Month = MonthName.July}, + new PatternMonth() {Pattern = "^aug\\.?(ust)?$".Compile(), Month = MonthName.August}, + new PatternMonth() + { + Pattern = "^sep\\.?(t\\.?|tember)?$".Compile(), + Month = MonthName.September + }, + new PatternMonth() {Pattern = "^oct\\.?(ober)?$".Compile(), Month = MonthName.October}, + new PatternMonth() {Pattern = "^nov\\.?(ember)?$".Compile(), Month = MonthName.November}, + new PatternMonth() {Pattern = "^dec\\.?(ember)?$".Compile(), Month = MonthName.December}, + }; + + public class PatternMonth + { + public Regex Pattern { get; set; } + public MonthName Month { get; set; } + } + static readonly List UnitPatterns = new List + { + new PatternUnit() { Pattern = "^years?$".Compile(), Unit = typeof(RepeaterYear) }, + new PatternUnit() { Pattern = "^seasons?$".Compile(), Unit = typeof(RepeaterSeason) }, + new PatternUnit() { Pattern = "^months?$".Compile(), Unit = typeof(RepeaterMonth) }, + new PatternUnit() { Pattern = "^fortnights?$".Compile(), Unit = typeof(RepeaterFortnight) }, + new PatternUnit() { Pattern = "^weeks?$".Compile(), Unit = typeof(RepeaterWeek) }, + new PatternUnit() { Pattern = "^weekends?$".Compile(), Unit = typeof(RepeaterWeekend) }, + new PatternUnit() { Pattern = "^days?$".Compile(), Unit = typeof(RepeaterDay) }, + new PatternUnit() { Pattern = "^hours?$".Compile(), Unit = typeof(RepeaterHour) }, + new PatternUnit() { Pattern = "^minutes?$".Compile(), Unit = typeof(RepeaterMinute) }, + new PatternUnit() { Pattern = "^seconds?$".Compile(), Unit = typeof(RepeaterSecond) } + }; + + public class PatternUnit + { + public Regex Pattern { get; set; } + public Type Unit { get; set; } + } + } } \ No newline at end of file diff --git a/src/Chronic/Tags/SeparatorScanner.cs b/src/Chronic/Tags/SeparatorScanner.cs index 2d4f6ec..455accf 100644 --- a/src/Chronic/Tags/SeparatorScanner.cs +++ b/src/Chronic/Tags/SeparatorScanner.cs @@ -5,18 +5,22 @@ namespace Chronic { public class SeparatorScanner : ITokenScanner { - static readonly dynamic[] Patterns = new dynamic[] - { - new { Pattern = @"^,$".Compile(), Tag = new SeparatorComma() }, - new { Pattern = @"^and$".Compile(), Tag = new SeparatorComma() }, - new { Pattern = @"^(at|@)$".Compile(), Tag = new SeparatorAt() }, - new { Pattern = @"^in$".Compile(), Tag = new SeparatorIn() }, - new { Pattern = @"^/$".Compile(), Tag = new SeparatorDate(Separator.Type.Slash) }, - new { Pattern = @"^-$".Compile(), Tag = new SeparatorDate(Separator.Type.Dash) }, - new { Pattern = @"^on$".Compile(), Tag = new SeparatorOn() }, - }; - - public IList Scan(IList tokens, Options options) + static readonly PatternSeparator[] Patterns = new PatternSeparator[] + { + new PatternSeparator() { Pattern = @"^,$".Compile(), Tag = new SeparatorComma() }, + new PatternSeparator() { Pattern = @"^and$".Compile(), Tag = new SeparatorComma() }, + new PatternSeparator() { Pattern = @"^(at|@)$".Compile(), Tag = new SeparatorAt() }, + new PatternSeparator() { Pattern = @"^in$".Compile(), Tag = new SeparatorIn() }, + new PatternSeparator() { Pattern = @"^/$".Compile(), Tag = new SeparatorDate(Separator.Type.Slash) }, + new PatternSeparator() { Pattern = @"^-$".Compile(), Tag = new SeparatorDate(Separator.Type.Dash) }, + new PatternSeparator() { Pattern = @"^on$".Compile(), Tag = new SeparatorOn() }, + }; + public class PatternSeparator + { + public Regex Pattern { get; set; } + public Separator Tag { get; set; } + } + public IList Scan(IList tokens, Options options) { tokens.ForEach(ApplyTags); return tokens;