org_mode 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Gemfile CHANGED
@@ -6,6 +6,7 @@ gemspec
6
6
  gem "commander"
7
7
  gem "facets"
8
8
  gem "mustache"
9
+ gem "colorize"
9
10
 
10
11
  group :development do
11
12
  if RUBY_VERSION =~ /^1\.9/
@@ -21,6 +22,7 @@ group :test do
21
22
  gem "timecop"
22
23
  gem "guard-cucumber"
23
24
  gem "popen4"
25
+ gem "pry"
24
26
  end
25
27
 
26
28
 
data/bin/org-mode CHANGED
@@ -11,22 +11,20 @@ program :description, 'Formats and extracts information out of org-mode files'
11
11
  program :help_formatter, :compact
12
12
 
13
13
  command :agenda do |c|
14
- c.syntax = 'org-mode agenda [options]'
15
- c.summary = ''
16
- c.description = ''
17
- c.example 'description', 'command example'
18
- c.option '--some-switch', 'Some switch that does something'
14
+ c.syntax = 'org-mode agenda [options] *org-mode-files'
15
+ c.summary = 'Displays information on scheduled items'
16
+ c.description = nil
17
+ c.example 'extract information on scheduled items out of files', 'org-mode agenda an-org-file.org'
18
+ c.option '--no-color', 'Do not use color in output'
19
19
  c.when_called OrgMode::Commands::Agenda, :execute
20
20
  end
21
21
 
22
22
  command :update do |c|
23
- c.syntax = 'Orgy update [options]'
24
- c.summary = ''
25
- c.description = ''
23
+ c.syntax = 'org-mode update [options]'
24
+ c.summary = 'Reformats an org-file'
25
+ c.description = 'Reformat and update the org-file. Converting the org-file to a standard format'
26
26
  c.example 'description', 'command example'
27
- c.option '--some-switch', 'Some switch that does something'
28
- c.action do |args, options|
29
- # Do something or c.when_called Orgy::Commands::Update
30
- end
27
+ c.option '--archive-done', 'Archives done items'
28
+ c.when_called OrgMode::Commands::Update, :execute
31
29
  end
32
30
 
@@ -11,12 +11,11 @@ Feature: agenda
11
11
  """
12
12
  When the script is executed on the org-file
13
13
  When the script is called with "agenda"
14
- Then the output should be
15
- """
16
- Agenda ()
17
- 2012-01-01
18
- TODO Scheduled task
19
- """
14
+ Then the output should contain "Agenda"
15
+ And the output should contain "2012-01-01"
16
+ And the output should contain "15:15"
17
+ And the output should contain "TODO"
18
+ And the output should contain "Scheduled task"
20
19
 
21
20
  # @focus
22
21
  # Scenario: should limit restults in a day view
@@ -0,0 +1,42 @@
1
+ Feature: org-mode update <orgfile>
2
+ org-mode script should reformat a file correctly
3
+ to a user can easily reformat an org-file in a
4
+ standarized way. This also enables certain
5
+ filters to be applied.
6
+
7
+ Scenario: should present meaningfull agenda information
8
+ Given we have an org-file with the following content
9
+ """
10
+ a header
11
+ * TODO Scheduled task <1-1-2012 Wed 15:15>
12
+ content that will be indented
13
+ multiline that is
14
+ ** TODO Scheduled task <1-1-2012 Wed 15:15-16:15>
15
+ some other content that will be indented
16
+ """
17
+ When the script is called with "update"
18
+ Then the output should be
19
+ """
20
+ a header
21
+
22
+ * TODO <2012-01-01 Sun 15:15> Scheduled task
23
+ content that will be indented
24
+ multiline that is
25
+ ** TODO <2012-01-01 Sun 15:15-16:15> Scheduled task
26
+ some other content that will be indented
27
+ """
28
+
29
+ # @focus
30
+ # Scenario: should limit restults in a day view
31
+ # Given date is "1-1-2012 15:00"
32
+ # And we have an org-file with the following content
33
+ # """
34
+ # * TODO Todays task <1-1-2012 Wed 15:15>
35
+ # * TODO Tommorrows task <2-1-2012 Wed 15:15>
36
+ # """
37
+ # When the script is called with "agenda today"
38
+ # Then the output should be
39
+ # """
40
+ # Todays activities:
41
+ # TODO Todays task
42
+ # """
data/features/steps.rb CHANGED
@@ -30,6 +30,10 @@ end
30
30
  Then /^the output should be$/ do |string|
31
31
  @stdout.should == string
32
32
  end
33
+ Then /^the output should contain "([^""]*)"$/ do |pattern|
34
+ @stdout.should match(pattern)
35
+ end
36
+
33
37
  Then /^the error should be$/ do |string|
34
38
  @script_error.stderr.chomp.should == string
35
39
  end
@@ -0,0 +1,13 @@
1
+ require 'stringio'
2
+
3
+ def capture_stdout
4
+ out = StringIO.new
5
+ old_stdout = $stdout
6
+ $stdout = out
7
+ yield
8
+ out.rewind
9
+ return out.read
10
+ ensure
11
+ $stdout = old_stdout
12
+ end
13
+
@@ -1,9 +1,9 @@
1
1
  require 'org_mode/parser'
2
2
  require 'org_mode/loader'
3
3
  require 'org_mode/reporters/agenda'
4
+ require 'org_mode/presenters/console'
4
5
 
5
6
  require 'core_ext/string'
6
- require 'mustache'
7
7
 
8
8
  module OrgMode::Commands
9
9
  class Agenda
@@ -18,19 +18,9 @@ module OrgMode::Commands
18
18
 
19
19
  file_collection = OrgMode::Loader.load_and_parse_files(*args)
20
20
  agenda_reporter = OrgMode::Reporters::Agenda.new(file_collection)
21
+ text_presenter = OrgMode::Presenters::Agenda::Console.new(agenda_reporter)
21
22
 
22
- tmpl_vars = {}
23
- tmpl_vars[:noi_per_date] = agenda_reporter.open_nodes_grouped_by_day
24
-
25
- puts Mustache.render <<-eos.strip_indent(8), tmpl_vars
26
- Agenda ()
27
- {{#noi_per_date}}
28
- {{date}}
29
- {{#nodes}}
30
- {{todo_state}}{{title}}
31
- {{/nodes}}
32
- {{/noi_per_date}}
33
- eos
23
+ puts text_presenter.open_items_per_day_colorized
34
24
 
35
25
  rescue SystemCallError => e
36
26
  puts "Encountered a little problem: #{e}"
@@ -1,4 +1,23 @@
1
+ require 'org_mode/parser'
2
+ require 'org_mode/loader'
3
+ require 'org_mode/formatters/textual'
4
+ require 'org_mode/processors/archive_done'
5
+
1
6
  module OrgMode::Commands
2
7
  class Update
8
+ def execute(args, options)
9
+ org_file = OrgMode::Loader.load_and_parse_file(args[0])
10
+
11
+ if options.archive_done
12
+ org_file = OrgMode::Processors::ArchiveDone.new(org_file).process
13
+ end
14
+
15
+ org_formatter = OrgMode::Formatters::Textual.new(org_file)
16
+
17
+ puts org_formatter.format
18
+
19
+ rescue StandardError => e
20
+ puts "Encountered a little problem: #{e}"
21
+ end
3
22
  end
4
23
  end
@@ -0,0 +1,48 @@
1
+ require 'org_mode'
2
+ require 'facets/kernel/blank'
3
+
4
+ module OrgMode
5
+ module Formatters
6
+ class Textual
7
+ def initialize(org_file)
8
+ @org_file = org_file
9
+ end
10
+
11
+ def format
12
+ [ @org_file.header,
13
+ @org_file.nodes.map {|n| format_node(n)} * "\n",
14
+ @org_file.footer ].reject(&:blank?) * "\n\n"
15
+ end
16
+
17
+ def format_node(node)
18
+ [format_title(node), format_content(node)].reject(&:blank?) * "\n"
19
+ end
20
+
21
+ def format_title(node)
22
+ stars = "*" * node.stars
23
+ [stars, node.todo_state, format_date(node), node.title].reject(&:blank?) * ' '
24
+ end
25
+
26
+ def format_content(node)
27
+ node.content.lines.map do |l|
28
+ [" " * node.indent, l].join
29
+ end.join
30
+ end
31
+
32
+ def format_date(node)
33
+ date = if node.date_end_time
34
+ "#{node.date_start_time.strftime('%Y-%m-%d %a %H:%M')}-#{node.date_end_time.strftime('%H:%M')}"
35
+ elsif node.date_start_time
36
+ "#{node.date_start_time.strftime('%Y-%m-%d %a %H:%M')}"
37
+ elsif node.date
38
+ "#{node.date.strftime('%Y-%m-%d %a')}"
39
+ else
40
+ nil
41
+ end
42
+
43
+ date ? "<#{date}>" : nil
44
+ end
45
+
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,20 @@
1
+ module OrgMode
2
+ class NodeUtils
3
+ # Public: transforms a sequental list of
4
+ # nodes into a tree structure setting
5
+ # parents and children on the nodes
6
+ def self.convert_sequential_nodelist_into_tree(nodes)
7
+ parent_stack = []
8
+ nodes.map! do |node|
9
+ node.parent = parent_stack[node.stars - 1]
10
+ if node.parent
11
+ node.parent.children << node
12
+ end
13
+ parent_stack[node.stars] = node
14
+ end
15
+
16
+ # filter out all non root nodes
17
+ nodes.select(&:root_node?)
18
+ end
19
+ end
20
+ end
@@ -7,6 +7,7 @@
7
7
  # Parser is decoupled from object model to make it easy to write updated
8
8
  # parsers or use a database to serialize an org-mode file out of.
9
9
  require 'org_mode'
10
+ require 'org_mode/node_utils'
10
11
  require 'date'
11
12
 
12
13
  module OrgMode
@@ -29,18 +30,18 @@ module OrgMode
29
30
  # Returns OrgMode::File object containing all
30
31
  # information of the file.
31
32
  def parse(buffer)
32
- b, nodes, e = parse_buffer(buffer)
33
-
34
- parent_stack = []
35
- nodes.map! do |title, content|
36
- node = NodeParser.parse(title,content)
37
- node.parent = parent_stack[node.stars - 1]
38
- if node.parent
39
- node.parent.children << node
40
- end
41
- parent_stack[node.stars] = node
33
+ b, nodes, e = parse_buffer(buffer)
34
+
35
+ parsed_nodes = parse_nodes(nodes)
36
+ root_nodes = NodeUtils.convert_sequential_nodelist_into_tree(parsed_nodes)
37
+
38
+ return File.new(b,root_nodes,e)
39
+ end
40
+
41
+ def parse_nodes(nodes)
42
+ nodes.map do |title,content|
43
+ NodeParser.parse(title,content)
42
44
  end
43
- return File.new(b,nodes,e)
44
45
  end
45
46
 
46
47
  def parse_buffer(buffer)
@@ -110,11 +111,11 @@ module OrgMode
110
111
  def parse_extract_dates(node)
111
112
  _, extracted_date, start_time, end_time = node.title.match(RxDateRegexp).to_a
112
113
  node.title = node.title.gsub(RxDateRegexp, '')
114
+ node.title.strip!
113
115
 
114
- if extracted_date
115
- node.date_start_time = DateTime.parse("#{extracted_date} #{start_time}")
116
- node.date_end_time = DateTime.parse("#{extracted_date} #{end_time}")
117
- end
116
+ node.date = DateTime.parse(extracted_date) if extracted_date
117
+ node.date_start_time = DateTime.parse("#{extracted_date} #{start_time}") if start_time
118
+ node.date_end_time = DateTime.parse("#{extracted_date} #{end_time}") if end_time
118
119
  end
119
120
 
120
121
  RxEmptyLine = /^\s*$/
@@ -0,0 +1,51 @@
1
+ require 'colorize'
2
+ require 'capture_stdout'
3
+
4
+ module OrgMode
5
+ module Presenters
6
+ module Agenda
7
+
8
+ class Console
9
+ def initialize reporter
10
+ @agenda_reporter = reporter
11
+ end
12
+
13
+ def open_items_per_day_colorized
14
+ capture_stdout do
15
+ now = DateTime.now
16
+ puts "Agenda: open items grouped by day [#{now.strftime('%Y-%m-%d %H:%M')}]".yellow.underline
17
+ puts
18
+ ongbd = @agenda_reporter.open_nodes_grouped_by_day
19
+ ongbd.each do |e|
20
+ puts "#{e.date}".blue.underline
21
+ e.nodes.each do |n|
22
+ color = :green
23
+ color = :red if n.date_start_time && n.node.date_start_time < now
24
+ color = :red if n.date && n.node.date < now
25
+
26
+ puts " " + node_line(n).send(color)
27
+ end
28
+ puts
29
+ end
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def node_line(n)
36
+ title = [n.todo_state, n.title].reject(&:nil?) * ' '
37
+ if n.appointment?
38
+ if n.date_end_time
39
+ "%s-%s %s" % [n.date_start_time, n.date_end_time, title]
40
+ else
41
+ "%s %s" % [n.date_start_time, title]
42
+ end
43
+ else
44
+ "ALL-DAY %s" % [title]
45
+ end
46
+ end
47
+
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,69 @@
1
+ require 'org_mode'
2
+ require 'core_ext/string'
3
+ require 'delegate'
4
+
5
+ module OrgMode
6
+ module Processors
7
+ class ArchiveDoneOrgFile < SimpleDelegator
8
+ def initialize(org_file)
9
+ super(org_file)
10
+ end
11
+
12
+ def archived_root_node
13
+ select_by_title(/^Archived$/, :stars => 1).first
14
+ end
15
+
16
+ def create_archived_root_node
17
+ self.root_nodes << OrgMode::Node.new.tap do |n|
18
+ n.title = "Archived"
19
+ n.content = <<-eos.strip_indent(10)
20
+ This node contains archived items. Appended
21
+ due to calling the script with update --archive-done
22
+ eos
23
+ n.stars = 1
24
+ end
25
+ end
26
+
27
+ def move_done_trees_to_archived_root_node
28
+ processed_nodes = []
29
+ self.nodes.each do |n|
30
+ # if not done move to processed nodes
31
+ # if done append to archived_root_node
32
+ end
33
+ end
34
+ end
35
+
36
+ class ArchiveDone
37
+ def initialize(org_file)
38
+ @org_file = ArchiveDoneOrgFile.new(org_file)
39
+ end
40
+
41
+ def process
42
+ @org_file.create_archived_root_node unless @org_file.archived_root_node
43
+
44
+ to_be_archived_trees = []
45
+ walk_and_update_node_children @org_file do |children|
46
+ to_be_archived_trees << children.select(&:done?)
47
+ children.reject(&:done?)
48
+ end
49
+
50
+ @org_file.archived_root_node.children.concat( to_be_archived_trees.flatten )
51
+
52
+ @org_file
53
+ end
54
+
55
+ # Private: walks all nodes
56
+ # but updates children array with
57
+ # return value of called function.
58
+ #
59
+ # Can be used to extract nodes from
60
+ # tree
61
+ def walk_and_update_node_children(node, &block)
62
+ node.children = block.call(node.children)
63
+ node.children.map do |n|
64
+ walk_and_update_node_children(n, &block)
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -1,4 +1,5 @@
1
1
  require 'facets/to_hash'
2
+ require 'facets/ostruct'
2
3
 
3
4
  module OrgMode
4
5
  module Reporters
@@ -26,17 +27,21 @@ module OrgMode
26
27
  # build a nice orderd struct
27
28
  noi_per_day.keys.sort.map do |date|
28
29
  { :date => date, :nodes => noi_per_day[date].map { |n| node_to_hash(n) } }
29
- end
30
+ end.map(&:to_ostruct)
31
+
30
32
  end
31
33
 
32
34
  private
33
35
 
34
36
  def node_to_hash(node)
35
- rv = [:title, :content, :todo_state, :date, :stars].
37
+ rv = [:title, :content, :todo_state, :date, :date_start_time, :date_end_time, :stars, :appointment?].
36
38
  map { |k| [ k, node.send(k) ] }.to_h
37
39
 
38
40
  rv[:date] = rv[:date].strftime('%Y-%m-%d %H:%M') if rv[:date]
39
- rv
41
+ rv[:date_start_time] = rv[:date_start_time].strftime('%H:%M') if rv[:date_start_time]
42
+ rv[:date_end_time] = rv[:date_end_time].strftime('%H:%M') if rv[:date_end_time]
43
+ rv[:node] = node
44
+ rv.to_ostruct
40
45
  end
41
46
 
42
47
  end
@@ -1,3 +1,3 @@
1
1
  module OrgMode
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
data/lib/org_mode.rb CHANGED
@@ -14,9 +14,8 @@ require "org_mode/version"
14
14
 
15
15
  module OrgMode
16
16
 
17
-
18
17
  class Node
19
- attr_accessor :title, :content, :stars, :date_start_time, :date_end_time, :todo_state
18
+ attr_accessor :title, :content, :stars, :date, :date_start_time, :date_end_time, :todo_state
20
19
  attr_accessor :parent, :children
21
20
 
22
21
  def initialize
@@ -24,9 +23,6 @@ module OrgMode
24
23
  @children = []
25
24
  end
26
25
 
27
- alias :date :date_start_time
28
- alias :date= :date_start_time=
29
-
30
26
  def indent
31
27
  stars + 1
32
28
  end
@@ -39,6 +35,10 @@ module OrgMode
39
35
  !date.nil?
40
36
  end
41
37
 
38
+ def appointment?
39
+ !!( date_start_time || date_end_time )
40
+ end
41
+
42
42
  def open?
43
43
  not done?
44
44
  end
@@ -50,24 +50,47 @@ module OrgMode
50
50
  end
51
51
 
52
52
  module FileInterface
53
- def root_nodes
54
- nodes.select(&:root_node?)
55
- end
56
-
57
53
  def scheduled_nodes
58
54
  nodes.select(&:scheduled?)
59
55
  end
56
+
57
+ def select_by_title(pattern, props={})
58
+ result = nodes
59
+ props.each do |k,v|
60
+ result = result.select {|n| n.send(k) == v }
61
+ end
62
+ result.select {|n| n.title =~ pattern}
63
+ end
60
64
  end
61
65
 
62
66
  class File
63
- attr_accessor :header, :nodes, :footer
67
+ attr_accessor :header, :root_nodes, :footer
64
68
 
65
69
  include FileInterface
66
70
 
67
- def initialize(header, nodes, footer)
71
+ # For universial children accessor
72
+ # file is just a node
73
+ alias :children :root_nodes
74
+ alias :children= :root_nodes=
75
+
76
+ def initialize(header, root_nodes, footer)
68
77
  @header = header
69
78
  @footer = footer
70
- @nodes = nodes
79
+ @root_nodes = root_nodes
80
+ end
81
+
82
+ def nodes
83
+ serialize_nodes(root_nodes)
84
+ end
85
+
86
+ private
87
+
88
+ # recusively serializes
89
+ # the nodes
90
+ def serialize_nodes(nodes)
91
+ nodes.map do |n|
92
+ [n] + serialize_nodes(n.children)
93
+ end.flatten
71
94
  end
72
95
  end
73
96
 
@@ -83,5 +106,10 @@ module OrgMode
83
106
  def nodes
84
107
  files.map(&:nodes).flatten
85
108
  end
109
+
110
+ def root_nodes
111
+ nodes.select(&:root_node?)
112
+ end
113
+
86
114
  end
87
115
  end
data/org_mode.gemspec CHANGED
@@ -25,4 +25,5 @@ Gem::Specification.new do |s|
25
25
  s.add_runtime_dependency "commander", ["~> 4.0"]
26
26
  s.add_runtime_dependency "facets", ["~> 2.9"]
27
27
  s.add_runtime_dependency "mustache", ["~> 0.99"]
28
+ s.add_runtime_dependency "colorize", ["~> 0.5"]
28
29
  end
@@ -1,23 +1,13 @@
1
1
  require 'org_mode/commands/agenda'
2
- require 'tempfile'
3
- require 'core_ext/string'
4
- require 'support/capture_stdout'
5
- require 'support/write_into_tempfile'
6
2
  require 'timecop'
7
3
 
8
- # Helper to execute agenda and compare the output
9
- def execute_and_compare_stdout_with args, options, expected_output
10
- output = capture_stdout do
11
- @org_mode_commands_agenda.execute(args, options)
12
- end
13
- output.should == expected_output
14
- end
4
+ require 'lib/org_mode/commands/helpers'
15
5
 
16
6
  describe OrgMode::Commands::Agenda do
17
7
  before do
18
8
  Timecop.freeze('2012-01-01 15:00')
19
9
 
20
- @org_mode_commands_agenda = OrgMode::Commands::Agenda.new
10
+ @cmd = @org_mode_commands_agenda = OrgMode::Commands::Agenda.new
21
11
  end
22
12
 
23
13
  context '#execute' do
@@ -26,11 +16,8 @@ describe OrgMode::Commands::Agenda do
26
16
  org_file = write_into_tempfile <<-eos.strip_indent(10)
27
17
  * TODO Scheduled task <1-1-2012 Wed 15:15>
28
18
  eos
29
- execute_and_compare_stdout_with [org_file.path], stub, <<-eos.strip_indent(10)
30
- Agenda ()
31
- 2012-01-01
32
- TODO Scheduled task
33
- eos
19
+ execute_and_output_should_contain @cmd, [org_file.path], stub,
20
+ /TODO/, /2012-01-01/, /15:15/ ,/Scheduled task/
34
21
  end
35
22
  end
36
23
  context 'when loaded with two files' do
@@ -41,14 +28,8 @@ describe OrgMode::Commands::Agenda do
41
28
  org_file2 = write_into_tempfile <<-eos.strip_indent(10)
42
29
  * TODO Scheduled task on the 1th <1-1-2012 Wed 15:15>
43
30
  eos
44
- execute_and_compare_stdout_with [org_file, org_file2].map(&:path), stub,
45
- <<-eos.strip_indent(10)
46
- Agenda ()
47
- 2012-01-01
48
- TODO Scheduled task on the 1th
49
- 2012-01-05
50
- TODO Scheduled task on the 5th
51
- eos
31
+ execute_and_output_should_contain @cmd, [org_file, org_file2].map(&:path), stub,
32
+ /TODO/, /2012-01-01/, /15:15/ ,/Scheduled task/, /on the 1th/, /on the 5th/
52
33
  end
53
34
  end
54
35
  end
@@ -0,0 +1,20 @@
1
+ require 'tempfile'
2
+ require 'core_ext/string'
3
+ require 'support/write_into_tempfile'
4
+ require 'capture_stdout'
5
+
6
+ # Helper to execute agenda and compare the output
7
+ def execute_and_compare_stdout_with cmd, args, options, expected_output
8
+ output = capture_stdout do
9
+ cmd.execute(args, options)
10
+ end
11
+ output.should == expected_output
12
+ end
13
+ def execute_and_output_should_contain cmd, args, options, *expected_output
14
+ output = capture_stdout do
15
+ cmd.execute(args, options)
16
+ end
17
+ expected_output.each do |pattern|
18
+ output.should match( pattern )
19
+ end
20
+ end
@@ -0,0 +1,39 @@
1
+ require 'org_mode/commands/update'
2
+ require 'lib/org_mode/commands/helpers'
3
+
4
+ describe OrgMode::Commands::Update do
5
+ before do
6
+ @cmd = OrgMode::Commands::Update.new
7
+ end
8
+
9
+ context '#execute' do
10
+ context 'without options' do
11
+ it 'reformats a file correctly' do
12
+ org_file = write_into_tempfile <<-eos.strip_indent(10)
13
+ * TODO Scheduled task <1-1-2012 Wed 15:15>
14
+ eos
15
+ execute_and_compare_stdout_with @cmd, [org_file.path], stub(:archive_done => false), <<-eos.strip_indent(10)
16
+ * TODO <2012-01-01 Sun 15:15> Scheduled task
17
+ eos
18
+ end
19
+ end
20
+ context 'option --archive-done' do
21
+ it 'archives the subtree as expected' do
22
+ org_file = write_into_tempfile <<-eos.strip_indent(10)
23
+ * TODO Scheduled task <1-1-2012 Wed 15:15>
24
+ ** DONE Scheduled child task <1-1-2012 Wed 12:15>
25
+ *** TODO Scheduled child of child
26
+ eos
27
+ execute_and_compare_stdout_with @cmd, [org_file.path], stub(:archive_done => true), <<-eos.strip_indent(10)
28
+ * TODO <2012-01-01 Sun 15:15> Scheduled task
29
+ * Archived
30
+ This node contains archived items. Appended
31
+ due to calling the script with update --archive-done
32
+
33
+ ** DONE <2012-01-01 Sun 12:15> Scheduled child task
34
+ *** TODO Scheduled child of child
35
+ eos
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,46 @@
1
+ require 'org_mode/formatters/textual'
2
+ require 'support/blueprints'
3
+
4
+ describe OrgMode::Formatters::Textual do
5
+ let(:org_file) do
6
+ nodes = []
7
+ files = []
8
+ nodes << OrgMode::Node.make(:stars => 1,
9
+ :todo_state => 'DONE',
10
+ :date => Date.parse('2012-06-01'))
11
+
12
+ # make helper for this
13
+ date = DateTime.parse('2012-02-01')
14
+ date_start = DateTime.parse('2012-02-01 15:00')
15
+ date_end = DateTime.parse('2012-02-01 16:00')
16
+ nodes << OrgMode::Node.make(:stars => 2, :date=>Date.parse('2012-02-03'))
17
+ nodes << OrgMode::Node.make(:stars => 3, :date=>date_start,
18
+ :date_end_time=>date_end,
19
+ :date_start_time=>date_start)
20
+ OrgMode::File.make(:nodes => nodes)
21
+ end
22
+
23
+
24
+ context '#format' do
25
+ before do
26
+ formatter = OrgMode::Formatters::Textual.new(org_file)
27
+ @output = formatter.format
28
+ end
29
+
30
+ it "is formatted as expected" do
31
+ @output.should == <<-eos.gsub(/^ {1,8}/,'').chomp
32
+ aheader
33
+
34
+ * DONE <2012-06-01 Fri> org-node
35
+ org-node content
36
+ ** TODO <2012-02-03 Fri> org-node
37
+ org-node content
38
+ *** TODO <2012-02-01 Wed 15:00-16:00> org-node
39
+ org-node content
40
+
41
+ afooter
42
+ eos
43
+ end
44
+ end
45
+
46
+ end
@@ -180,14 +180,20 @@ describe OrgMode::NodeParser do
180
180
  end
181
181
  context "node title with date time" do
182
182
  let(:node) {OrgMode::NodeParser.parse('** Date node title <2012-02-03 Wed 15:15>', nil)}
183
- it "parses the date-time from the title correcty" do
184
- node.date.strftime('%Y-%m-%d %H:%M').should == '2012-02-03 15:15'
183
+ it "parses the date from the title correcty" do
184
+ node.date.strftime('%Y-%m-%d %H:%M').should == '2012-02-03 00:00'
185
+ end
186
+ it "parses the date_start_time from the title correcty" do
187
+ node.date_start_time.strftime('%Y-%m-%d %H:%M').should == '2012-02-03 15:15'
188
+ end
189
+ it "parses the date_end_time from the title correcty" do
190
+ node.date_end_time.should be_nil
185
191
  end
186
192
  end
187
193
  context "node title with date-range" do
188
194
  let(:node) {OrgMode::NodeParser.parse('** Date node title <2012-02-03 Wed 15:15-16:15>', nil)}
189
195
  it "parses the date from the title correcty" do
190
- node.date.strftime('%Y-%m-%d %H:%M').should == '2012-02-03 15:15'
196
+ node.date.strftime('%Y-%m-%d %H:%M').should == '2012-02-03 00:00'
191
197
  end
192
198
  it "parses the start_tiem correctly" do
193
199
  node.date_start_time.strftime('%Y-%m-%d %H:%M').should == '2012-02-03 15:15'
@@ -0,0 +1,44 @@
1
+ require 'org_mode/processors/archive_done'
2
+ require 'support/blueprints'
3
+ require 'support/include_hash'
4
+ require 'timecop'
5
+
6
+ # When can we archive a tree
7
+ #
8
+ # we can archive a tree when all dones
9
+ # of a tree are done. Or the root-tree is done
10
+
11
+ describe OrgMode::Processors::ArchiveDone do
12
+
13
+ let(:org_file) do
14
+ nodes = []
15
+ nodes << OrgMode::Node.make(:stars => 1,
16
+ :todo_state => 'DONE',
17
+ :date => Date.parse('2012-06-01'))
18
+ nodes << OrgMode::Node.make(:stars => 2, :date=>Date.parse('2012-02-03'))
19
+ nodes << OrgMode::Node.make(:stars => 3, :date=>DateTime.parse('2012-02-01 15:00'))
20
+ OrgMode::File.make(:nodes => nodes)
21
+ end
22
+
23
+ context '#process' do
24
+ let(:processed_org_file) do
25
+ processor = OrgMode::Processors::ArchiveDone.new(org_file)
26
+ processor.process
27
+ end
28
+
29
+ context 'archived_node' do
30
+ let(:archived_nodes) do
31
+ processed_org_file.select_by_title(/^Archived$/, :stars => 1)
32
+ end
33
+
34
+ it 'should have created a node "Archived"' do
35
+ archived_nodes.length.should == 1
36
+ end
37
+
38
+ it 'should have added the DONE tree to the archived ones' do
39
+ #archived_nodes[0].children.length.should == 1
40
+ end
41
+ end
42
+ end
43
+
44
+ end
@@ -36,35 +36,6 @@ describe OrgMode::Reporters::Agenda do
36
36
  nodecount_per_date = reported.map { |e| [e[:date], e[:nodes].length] }
37
37
  nodecount_per_date.should == [["2012-02-01", 2], ["2012-02-03", 1], ["2012-02-05", 1]]
38
38
  end
39
- it "should result in the following subhashes" do
40
- reported.should ==
41
- [{:date=>"2012-02-01",
42
- :nodes=>
43
- [{:title=>"org-node",
44
- :content=>"org-node content",
45
- :todo_state=>"TODO",
46
- :date=>"2012-02-01 00:00",
47
- :stars=>1},
48
- {:title=>"org-node",
49
- :content=>"org-node content",
50
- :todo_state=>"TODO",
51
- :date=>"2012-02-01 15:00",
52
- :stars=>3}]},
53
- {:date=>"2012-02-03",
54
- :nodes=>
55
- [{:title=>"org-node",
56
- :content=>"org-node content",
57
- :todo_state=>"TODO",
58
- :date=>"2012-02-03 00:00",
59
- :stars=>2}]},
60
- {:date=>"2012-02-05",
61
- :nodes=>
62
- [{:title=>"org-node",
63
- :content=>"org-node content",
64
- :todo_state=>"TODO",
65
- :date=>"2012-02-05 00:00",
66
- :stars=>2}]}]
67
- end
68
39
  it "it ignores the DONE task" do
69
40
  dates = reported.map {|e| e[:date] }
70
41
  dates.should_not include("2012-06-01")
@@ -1,4 +1,5 @@
1
1
  require 'org_mode'
2
+ require 'org_mode/node_utils'
2
3
  require 'support/blueprints'
3
4
 
4
5
  describe OrgMode::File do
@@ -1,4 +1,5 @@
1
1
  require 'org_mode'
2
+ require 'org_mode/node_utils'
2
3
 
3
4
  class OrgMode::Node
4
5
  def self.make(attrs={})
@@ -7,6 +8,8 @@ class OrgMode::Node
7
8
  n.stars = attrs[:stars] || rand(4)
8
9
  n.content = attrs[:content] || "org-node content"
9
10
  n.date = attrs[:date]
11
+ n.date_start_time = attrs[:date_start_time]
12
+ n.date_end_time = attrs[:date_end_time]
10
13
  n.todo_state = attrs[:todo_state] || 'TODO'
11
14
  end
12
15
  end
@@ -15,7 +18,8 @@ end
15
18
  class OrgMode::File
16
19
  def self.make(attrs={})
17
20
  nodes = attrs[:nodes] || Array.new(2) { OrgMode::Node.make }
18
- self.new("aheader", nodes , "afooter")
21
+ root_nodes = OrgMode::NodeUtils.convert_sequential_nodelist_into_tree(nodes)
22
+ self.new("aheader", root_nodes , "afooter")
19
23
  end
20
24
  end
21
25
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: org_mode
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 3
10
- version: 0.0.3
9
+ - 4
10
+ version: 0.0.4
11
11
  platform: ruby
12
12
  authors:
13
13
  - Boy Maas
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-02-10 00:00:00 Z
18
+ date: 2012-02-12 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: rake
@@ -77,6 +77,21 @@ dependencies:
77
77
  version: "0.99"
78
78
  type: :runtime
79
79
  version_requirements: *id004
80
+ - !ruby/object:Gem::Dependency
81
+ name: colorize
82
+ prerelease: false
83
+ requirement: &id005 !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ~>
87
+ - !ruby/object:Gem::Version
88
+ hash: 1
89
+ segments:
90
+ - 0
91
+ - 5
92
+ version: "0.5"
93
+ type: :runtime
94
+ version_requirements: *id005
80
95
  description: Org-mode parser, presenter, and reformatter. Read more about it on the github pages.
81
96
  email:
82
97
  - boy.maas@gmail.com
@@ -96,22 +111,32 @@ files:
96
111
  - features/cmdline_handles_errors_cracefully.feature
97
112
  - features/cmdline_noparams.feature
98
113
  - features/cmdline_todos.feature
114
+ - features/cmdline_update.feature
99
115
  - features/steps.rb
100
116
  - features/support/env.rb
101
117
  - features/support/org_mode_script.rb
118
+ - lib/capture_stdout.rb
102
119
  - lib/core_ext/string.rb
103
120
  - lib/org_mode.rb
104
121
  - lib/org_mode/commands.rb
105
122
  - lib/org_mode/commands/agenda.rb
106
123
  - lib/org_mode/commands/update.rb
124
+ - lib/org_mode/formatters/textual.rb
107
125
  - lib/org_mode/loader.rb
126
+ - lib/org_mode/node_utils.rb
108
127
  - lib/org_mode/parser.rb
128
+ - lib/org_mode/presenters/console.rb
129
+ - lib/org_mode/processors/archive_done.rb
109
130
  - lib/org_mode/reporters/agenda.rb
110
131
  - lib/org_mode/version.rb
111
132
  - org_mode.gemspec
112
133
  - spec/data/org-file-01-simple-node-structure.org
113
134
  - spec/lib/org_mode/commands/agenda_spec.rb
135
+ - spec/lib/org_mode/commands/helpers.rb
136
+ - spec/lib/org_mode/commands/update_spec.rb
137
+ - spec/lib/org_mode/formatters/textual_spec.rb
114
138
  - spec/lib/org_mode/parser_spec.rb
139
+ - spec/lib/org_mode/processors/archive_done_spec.rb
115
140
  - spec/lib/org_mode/reporters/agenda_spec.rb
116
141
  - spec/lib/org_mode_spec.rb
117
142
  - spec/support/blueprints.rb
@@ -156,12 +181,17 @@ test_files:
156
181
  - features/cmdline_handles_errors_cracefully.feature
157
182
  - features/cmdline_noparams.feature
158
183
  - features/cmdline_todos.feature
184
+ - features/cmdline_update.feature
159
185
  - features/steps.rb
160
186
  - features/support/env.rb
161
187
  - features/support/org_mode_script.rb
162
188
  - spec/data/org-file-01-simple-node-structure.org
163
189
  - spec/lib/org_mode/commands/agenda_spec.rb
190
+ - spec/lib/org_mode/commands/helpers.rb
191
+ - spec/lib/org_mode/commands/update_spec.rb
192
+ - spec/lib/org_mode/formatters/textual_spec.rb
164
193
  - spec/lib/org_mode/parser_spec.rb
194
+ - spec/lib/org_mode/processors/archive_done_spec.rb
165
195
  - spec/lib/org_mode/reporters/agenda_spec.rb
166
196
  - spec/lib/org_mode_spec.rb
167
197
  - spec/support/blueprints.rb