aboutsummaryrefslogtreecommitdiff
path: root/src/then.nim
diff options
context:
space:
mode:
Diffstat (limited to 'src/then.nim')
-rw-r--r--src/then.nim130
1 files changed, 44 insertions, 86 deletions
diff --git a/src/then.nim b/src/then.nim
index be3e813..c7c1e61 100644
--- a/src/then.nim
+++ b/src/then.nim
@@ -1,4 +1,4 @@
-import std/[times, os, strutils, strbasics, strscans, sets, re, deques], parseopt
+import std/[times, os, strutils, strbasics, strscans, sets, re, tables], parseopt
const VERSION = "0.1"
const configDir = expandTilde("~/.config/then/")
@@ -53,9 +53,12 @@ proc printVersion() =
echo "then " & VERSION
quit()
-proc checkType(cond: string): string =
- if cond.len == 4 and parseInt(cond) != 0: return "year"
- if cond.len in [1, 2] and parseInt(cond) != 0: return "day"
+proc checkType(c: string): string =
+ var cond = c
+ if cond[0] == '!':
+ cond.delete(0..0)
+ if find(cond, re"^\d{4}$") > -1: return "year"
+ if find(cond, re"^\d{1,2}$") > -1: return "day"
if cond in DefaultLocale.MMM.toHashSet or cond in DefaultLocale.MMMM.toHashSet: return "month"
if cond in DefaultLocale.ddd.toHashSet or cond in DefaultLocale.dddd.toHashSet: return "dayofweek"
if find(cond, re"\d{1,2}:\d{2}") > -1: return "time"
@@ -87,93 +90,48 @@ proc checkCond(cond: string, day: DateTime): bool =
echo "UNKNOWN THING ", cond
return false
-proc getConditions(dateStr: string): seq[string] =
- var conditions: seq[string]
- conditions = dateStr.rsplit(' ')
- return conditions
-
-# TODO simplify?? Would it be easier to identify conditions and replace them with TRUE/FALSE then just process the string?
-
-# Shunting yard to parse conditions, parens, and logical operators
-# Does NOT parse out individual conditions yet because some individual
-# conditions (like 1W) require context of surrounding conditions.
-# The logic around parentheses is a little weird because conditions like
-# "<(March 15)" contain parentheses that we don't want to throw out
-proc parseDateToEvents(dateStr: string): seq[string] =
- var holdingStack = initDeque[Token]()
- var resultStack = initDeque[Token]()
- var newToken: string = ""
- for c in dateStr:
- echo c
- case c:
- of '(':
- if newToken.len == 1:
- if newToken[0] == '>' or newToken[0] == '<':
- newToken.add(c)
- else
- echo "ERROR: newToken exists but we got an open paren?"
- else:
- holdingStack.addLast(Token(token: "(", precedence: 0))
- of ')':
- if newToken.len > 0: # Closing token like <(March 15). Push the token.
- resultStack.addLast(Token(token: newToken, precedence: 0))
- newToken = ""
- else: # Logical closing paren. Pop stack until (.
- while holdingStack.len > 0 and holdingStack.peekLast.token != "(":
- if holdingStack.len == 0:
- echo "UH OH, ERROR MISMATCHED PARENS"
- resultStack.addLast(holdingStack.popLast)
- discard holdingStack.popLast # Pop the (
- of '!':
- holdingStack.addLast(Token(token: "!", precedence: 3))
- of '|':
- while holdingStack.len > 0 and holdingStack.peekLast.precedence > 2:
- resultStack.addLast(holdingStack.popLast)
- holdingStack.addLast(Token(token: "|", precedence: 2))
- of ' ':
- if newToken.len > 1 and newToken[1] == '(' and newToken[newToken.len-1] != ')': # Middle of token like <(March 15).
- newToken.add(c)
- else: # End of new token, implicit &
- # Add newToken to result
- resultStack.addLast(Token(token: newToken, precedence: 0))
- newToken = ""
- # Add implicit & to holding
- while holdingStack.len > 0 and holdingStack.peekLast.precedence > 1:
- resultStack.addLast(holdingStack.popLast)
- holdingStack.addLast(Token(token:"&", precedence: 1))
- of '>','<',':','-','a'..'z','A'..'Z','0'..'9':
- newToken.add(c)
- else:
- echo "Weird character in dateStr: ", c
- discard
- # Push last token
- if newToken.len > 0:
- resultStack.addLast(Token(token: newToken, precedence: 0))
- # Clear the holding stack
- while holdingStack.len > 0:
- var t = holdingStack.popLast
- if t.token != "(":
- resultStack.addLast(t)
- echo resultStack
+# Splits a string on whitespace, but maintains whitespace in date groups
+proc splitWhitespaceExceptParens(str:string): seq[string] =
+ var result: seq[string] = newSeq[string]()
+ var inParens = false
+ for token in str.splitWhitespace:
+ if token.contains(')'): inParens = false
+ if inParens:
+ result.add(result.pop & ' ' & token)
+ else:
+ result.add(token)
+ if token.contains('('): inParens = true
+ return result
+
+proc parseDateToTable(date:string): Table[string,seq[string]] =
+ var table = initTable[string,seq[string]]()
+ let conditions = splitWhitespaceExceptParens(date)
+ for c in conditions:
+ let condType = checkType(c)
+ if not table.hasKey(condType):
+ table[condType] = @[]
+ table[condType].add(c)
+ return table
proc getEvents(cal: seq[string], day: DateTime): seq[string] =
- var events: seq[string]
+ var events: seq[string] = newSeq[string]()
for line in cal:
- var (success, dateStr, eventStr) = scanTuple(line, "$*,$*")
+ var (success, date, event) = scanTuple(line, "$*,$*")
if success:
- dateStr.strip
- eventStr.strip
- discard parseDateToEvents(dateStr)
- #let conditions = getConditions(dateStr)
- # var match = true
- # for c in conditions:
- # c = c.toLower.capitalizeAscii
- # if checkCond(c, day) == false:
- # match = false
- # break
- # if match:
- # events.add(eventStr)
+ date.strip
+ event.strip
+ let conditions = parseDateToTable(date)
+ echo conditions
+ var match = true
+ #for c in conditions:
+ # var cond = c.toLower.capitalizeAscii
+ # if checkCond(cond, day) == false:
+ # match = false
+ # break
+ #if match:
+ # events.add(event)
+ # break
else:
echo "WARNING: Cannot parse line: ", line
return events