From c4261ee98ef5fd75a208e8e981486ecb4dfcdafc Mon Sep 17 00:00:00 2001 From: historia Date: Wed, 31 Jul 2024 03:15:30 -0400 Subject: Implemented most ranges (missing Julian/Dategroups) --- src/then.nim | 103 +++++------------------------------------------------------ 1 file changed, 8 insertions(+), 95 deletions(-) (limited to 'src') diff --git a/src/then.nim b/src/then.nim index a74a863..5395ca4 100644 --- a/src/then.nim +++ b/src/then.nim @@ -1,14 +1,13 @@ -import std/[times, os, strutils, strbasics, strscans, sets, re, tables], parseopt +import std/[times, os, strutils, strbasics, strscans, sets, tables], parseopt +import then/[conditions,typechecker] const VERSION = "0.1" -const MONTHS = DefaultLocale.MMM.toHashSet + DefaultLocale.MMMM.toHashSet -const WEEKDAYS = DefaultLocale.ddd.toHashSet + DefaultLocale.dddd.toHashSet const configDir = expandTilde("~/.config/then/") const defaultConfigFile = configDir & "then.toml" const defaultCalendarFile = configDir & "calendar.then" -# Forward declarations -proc checkCond(cond: string, date: DateTime): bool +const MONTHS = DefaultLocale.MMM.toHashSet + DefaultLocale.MMMM.toHashSet +const WEEKDAYS = DefaultLocale.ddd.toHashSet + DefaultLocale.dddd.toHashSet # Creates a default configuration file if it doesn't exist proc createDefaultConfigFile() = @@ -53,104 +52,19 @@ proc printVersion() = echo "then " & VERSION quit() -# Check an individual condition (Jan) and return the condition type (month) -proc checkType(c: string): string = - var cond = c - if find(cond, re"^\d{4}$") > -1: return "year" - if find(cond, re"^\d{1,2}$") > -1: return "day" - if find(cond, re"^\dw$") > -1: return "firstweek" - if find(cond, re"^\dl$") > -1: return "lastweek" - if find(cond, re"^\([A-Za-z0-9 ]+\)$") > -1: return "dategroup" - if find(cond, re"^\d{4}-\d{4}$") > -1: return "rangeyear" - if find(cond, re"^\d{1,2}-\d{1,2}$") > -1: return "rangeday" - if find(cond, re"^\d{1,2}:\d{2}(-\d{1,2}:\d{2})?$") > -1: return "time" - if find(cond, re"^\(?\s*[Jj]\s*%\s*\d+\s*([-+]\d+)?\s*\)?$") > -1: return "julian" - cond = cond.toLower.capitalizeAscii - if cond in MONTHS: return "month" - if cond in WEEKDAYS: return "dayofweek" - - # Split c on - and check for ranges - let cs = cond.split("-", maxsplit = 1) - if cs.len != 2: return "unknown" - let startRange = cs[0].toLower.capitalizeAscii - let endRange = cs[1].toLower.capitalizeAscii - if (startRange in MONTHS) and (endRange in MONTHS): return "rangemonth" - if (startRange in WEEKDAYS) and (endRange in WEEKDAYS): return "rangedayofweek" - if find(startRange, re"^\([A-Za-z0-9 ]+\)$") > -1 and find(endRange, re"^\([A-Za-z0-9 ]+\)$") > -1: - return "rangedategroup" - return "unknown" - -proc getWeekFromEnd(date: DateTime): int = - let daysInMonth = getDaysInMonth(date.month, date.year) - return int((daysInMonth - date.monthday) / 7) + 1 - -proc getWeek(date: DateTime): int = - return int((date.monthDay - 1) / 7) + 1 - -# Check each condition in a date group like (Jan 1 2025) -proc checkDateGroup(s: string, date: DateTime): bool = - var conditions = s - let cs = conditions[1..conditions.len-2].splitWhitespace - for c in cs: - if checkCond(c, date) == false: - return false - return true - -proc checkRangeYear(s: string, date: DateTime): bool = - var years = s.split('-') - return date.year >= years[0] and date.year <= years[1] - -proc checkCond(cond: string, date: DateTime): bool = - var condition = cond - var invert = false - var found = false - if condition[0] == '!': - condition.delete(0..0) - invert = true - case checkType(condition): - of "time": - return true - of "year": - if parseInt(condition) == date.year: - found = true - of "day": - if condition == date.format("d") or condition == date.format("dd"): - found = true - of "month": - if condition == date.format("MMM") or condition == date.format("MMMM"): - found = true - of "dayofweek": - if condition == date.format("ddd") or condition == date.format("dddd"): - found = true - of "firstweek": - if parseInt(condition[0..1]) == getWeek(date): - found = true - of "lastweek": - if parseInt(condition[0..1]) == getWeekFromEnd(date): - found = true - of "dategroup": - found = checkDateGroup(condition, date) - of "rangeyear": - found = checkRangeYear(condition, date) - of "unknown": - echo "ERROR: Unknown condition: ", condition - if invert == true: - return not found - return found - # Splits a string on whitespace, but maintains whitespace in date groups proc splitWhitespaceExceptParens(str:string): seq[string] = - var result: seq[string] = newSeq[string]() + var output: seq[string] = newSeq[string]() var inParens = false for token in str.splitWhitespace: if inParens: - result.add(result.pop & ' ' & token) + output.add(output.pop & ' ' & token) else: - result.add(token) + output.add(token) for c in token: if c == '(': inParens = true if c == ')': inParens = false - return result + return output # Returns Table[conditionType, seq of conditions] proc parseDateToTable(date:string): Table[string,seq[string]] = @@ -177,7 +91,6 @@ proc getEvents(cal: seq[string], date: DateTime): seq[string] = for k,cs in conditions: var keyMatched = false for c in cs: - #var cond = c.toLower.capitalizeAscii if checkCond(c, date) == true: keyMatched = true break -- cgit v1.2.3