1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
import std/[times, strutils, strbasics, strscans, tables]
import conditionchecker, typechecker
# Splits a string on whitespace, but maintains whitespace in date groups
proc splitWhitespaceExceptParens(str:string): seq[string] =
var output: seq[string] = newSeq[string]()
var inParens = false
for token in str.splitWhitespace:
if inParens:
output.add(output.pop & ' ' & token)
else:
output.add(token)
for c in token:
if c == '(': inParens = true
if c == ')': inParens = false
return output
# Returns Table[conditionType, seq of conditions]
proc parseDateToTable(date:string): Table[string, seq[string]] =
var table = initTable[string,seq[string]]()
let conditions = splitWhitespaceExceptParens(date)
for c in conditions:
let condType = typechecker.checkType(c)
if not table.hasKey(condType):
table[condType] = @[]
table[condType].add(c)
return table
proc allConditionsMet(dateConditions: string, date: DateTime): bool =
let conditions = parseDateToTable(dateConditions.strip)
if conditions.hasKey("unknown"): return false
for k,cs in conditions:
var keyMatched = false
for c in cs:
if conditionchecker.checkCond(c, date):
keyMatched = true
break
if not keyMatched:
return false
return true
# Returns Table[event, attachments]
proc getEventsForDate(cal: seq[string], date: DateTime): Table[string, seq[string]] =
var lastInsertion = ""
for line in cal:
var (success, dateConditions, event) = scanTuple(line, "$*,$*")
if success:
if allConditionsMet(dateConditions, date):
event.strip
result[event] = @[]
lastInsertion = event
elif line.strip[0] == '+':
if result.hasKey(lastInsertion):
result[lastInsertion].add(line)
elif line[0..1] == "- ":
lastInsertion = ""
else:
echo "WARNING: Cannot parse line: ", line
proc printEvents(cal: seq[string], date: DateTime, format: string) =
let events = getEventsForDate(cal, date)
if events.len > 0:
for e in events.keys:
echo date.format(format), " ", e
for attachment in events[e]:
let space = date.format(format).len + 2
echo attachment.indent(space)
proc printAgenda*(calendar: seq[string], past: int, future: int) =
let now = now()
var today = dateTime(now.year, now.month, now.monthday, 00, 00, 00, 00, local())
for i in past..future:
let curDay = today + i.days
printEvents(calendar, curDay, "ddd yyyy MMM dd")
|