aboutsummaryrefslogtreecommitdiff
path: root/parser.rb
blob: 08cc50c4cfa9903f866ee11c07e9c3098cafe11b (plain)
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
75
76
77
78
79
80
81
82
#!/usr/bin/env ruby

require "pp"

require "parslet"
include Parslet

class CassParser < Parslet::Parser
  root :doc

  ### Type segments
  # rule(:hour)       { hour_.as(:hour) }
  # rule(:minute)     { minute_.as(:minute) }
  # rule(:second)     { second_.as(:second) }

  # rule(:year)       { year_.as(:year) }
  # rule(:month)      { month_.as(:month) }
  # rule(:day)        { day_.as(:day) }

  # rule(:time)       { time_.as(:time) }
  # rule(:local)      { local_.as(:local) }
  # rule(:offset)     { offset_.as(:offset) }

  # rule(:date)       { date_.as(:date) }
  rule(:datetime)   { date >> str(" ") >> time }
  rule(:daterange)  { start >> str(" -") >> stop }
  
  rule(:start)      { datetime.as(:start) }
  rule(:stop)       { (str(" ") >> datetime).maybe.as(:stop) }
  
  rule(:title)      { title_.as(:title) }
  rule(:doc)        { line_.repeat }

  ### Combinatory segments
  rule(:hour)      { digit.repeat(2, 2) }
  rule(:minute)    { digit.repeat(2, 2) }
  rule(:second)    { digit.repeat(2, 2) }

  rule(:time)      { local >> offset }
  rule(:date)      { year >> str("-") >> month >> str("-") >> day }
  
  rule(:year)      { digit.repeat(4, 4) }
  rule(:month)     { digit.repeat(2, 2) }
  rule(:day)       { digit.repeat(2, 2) }

  rule(:local)     { hour >> str(":") >> minute >> str(":") >> second }
  rule(:offset)    { match("[zZ]") | tnoffset }
  rule(:poffset)   { str(" ") >> match("[+\-]") }
  rule(:tnoffset)  { poffset >> hour >> str(":").maybe >> minute }
  
  rule(:title_)     { text >> str(":") }
  
  rule(:entry_)     { title >> spaces >> daterange }
  rule(:comment)    { str("#") >> text }
  rule(:line_)      { comment | entry_ |  newline }
  
  ### Primitive modes
  rule(:digit)      { match("[0-9]") }
  rule(:text)       { match("[a-zA-Z0-9 ]").repeat }
  rule(:spaces)     { match("[ \t]").repeat }
  rule(:newline)    { spaces.maybe >> str("\n") }
end

__END__

# Following is an example of what the `timebox` file format looks like
# Comment lines start with `#`, description lines start with ` `. Every
# other line is an entry, with the account first, followed by `:`, then
# time slice information in YYYY-MM-DD hh:mm:ss +TZ - ...
# An ongoing shift is allowed to have no "end" time information

Bobs Burger:       2019-07-21 21:00:00 +0200 - 2019-07-21 22:00:00 +0200
  Learning how to not burn down the kitchen

Bobs Burger:       2019-07-21 21:00:00 +0200 - 2019-07-21 22:00:00 +0200
  Serving some food

ACME Inc:          2019-07-21 21:00:00 +0200 - 2019-07-21 22:00:00 +0200
ACME Inc:          2019-07-21 21:00:00 +0200 - 2019-07-21 22:00:00 +0200

Bobs Burger:       2019-07-22 09:00:00 +0200 - 2019-07-22 15:00:00 +0200
Bobs Burger:       2019-07-22 21:00:00 +0200 -