aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorhistoria <gravel.justness270@slmail.me>2024-07-31 03:15:30 -0400
committerhistoria <gravel.justness270@slmail.me>2024-07-31 03:15:30 -0400
commitc4261ee98ef5fd75a208e8e981486ecb4dfcdafc (patch)
tree365841f4fff686a02a8be281157341bb4dc31969 /src
parentf60ceeaa79af1e2438b8829c8a32f9187ffb6aa7 (diff)
downloadsoon-c4261ee98ef5fd75a208e8e981486ecb4dfcdafc.tar.gz
Implemented most ranges (missing Julian/Dategroups)
Diffstat (limited to 'src')
-rw-r--r--src/then.nim103
1 files changed, 8 insertions, 95 deletions
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