org-ruby 0.5.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. data/History.txt +81 -77
  2. data/README.rdoc +66 -66
  3. data/Rakefile +28 -28
  4. data/bin/org-ruby +40 -40
  5. data/lib/org-ruby.rb +50 -50
  6. data/lib/org-ruby/headline.rb +102 -120
  7. data/lib/org-ruby/html_output_buffer.rb +174 -156
  8. data/lib/org-ruby/line.rb +206 -260
  9. data/lib/org-ruby/output_buffer.rb +227 -191
  10. data/lib/org-ruby/parser.rb +320 -272
  11. data/lib/org-ruby/regexp_helper.rb +156 -156
  12. data/lib/org-ruby/textile_output_buffer.rb +67 -68
  13. data/spec/data/freeform-example.org +113 -113
  14. data/spec/data/freeform.org +111 -111
  15. data/spec/data/hyp-planning.org +335 -335
  16. data/spec/data/remember.org +53 -53
  17. data/spec/headline_spec.rb +55 -55
  18. data/spec/html_examples/advanced-code.html +36 -36
  19. data/spec/html_examples/advanced-code.org +53 -53
  20. data/spec/html_examples/advanced-lists.html +31 -31
  21. data/spec/html_examples/advanced-lists.org +31 -31
  22. data/spec/html_examples/block_code.html +28 -28
  23. data/spec/html_examples/block_code.org +35 -35
  24. data/spec/html_examples/blockquote.html +7 -7
  25. data/spec/html_examples/blockquote.org +13 -13
  26. data/spec/html_examples/code-comment.html +18 -18
  27. data/spec/html_examples/code-comment.org +22 -22
  28. data/spec/html_examples/custom-seq-todo.html +15 -15
  29. data/spec/html_examples/custom-seq-todo.org +24 -24
  30. data/spec/html_examples/custom-todo.html +15 -15
  31. data/spec/html_examples/custom-todo.org +24 -24
  32. data/spec/html_examples/custom-typ-todo.html +15 -15
  33. data/spec/html_examples/custom-typ-todo.org +24 -24
  34. data/spec/html_examples/entities.html +4 -4
  35. data/spec/html_examples/entities.org +11 -11
  36. data/spec/html_examples/escape-pre.html +6 -6
  37. data/spec/html_examples/escape-pre.org +6 -6
  38. data/spec/html_examples/export-exclude-only.html +13 -13
  39. data/spec/html_examples/export-exclude-only.org +81 -81
  40. data/spec/html_examples/export-keywords.html +4 -4
  41. data/spec/html_examples/export-keywords.org +18 -18
  42. data/spec/html_examples/export-tags.html +8 -8
  43. data/spec/html_examples/export-tags.org +82 -82
  44. data/spec/html_examples/export-title.html +2 -2
  45. data/spec/html_examples/export-title.org +4 -4
  46. data/spec/html_examples/html-literal.html +2 -2
  47. data/spec/html_examples/html-literal.org +6 -6
  48. data/spec/html_examples/inline-formatting.html +10 -10
  49. data/spec/html_examples/inline-formatting.org +17 -17
  50. data/spec/html_examples/link-features.html +8 -8
  51. data/spec/html_examples/link-features.org +19 -19
  52. data/spec/html_examples/lists.html +19 -19
  53. data/spec/html_examples/lists.org +36 -36
  54. data/spec/html_examples/metadata-comment.html +27 -27
  55. data/spec/html_examples/metadata-comment.org +30 -30
  56. data/spec/html_examples/only-list.html +5 -5
  57. data/spec/html_examples/only-list.org +3 -3
  58. data/spec/html_examples/only-table.html +6 -6
  59. data/spec/html_examples/only-table.org +5 -5
  60. data/spec/html_examples/skip-header.html +3 -3
  61. data/spec/html_examples/skip-header.org +28 -28
  62. data/spec/html_examples/skip-table.html +4 -4
  63. data/spec/html_examples/skip-table.org +19 -19
  64. data/spec/html_examples/tables.html +20 -20
  65. data/spec/html_examples/tables.org +26 -26
  66. data/spec/html_examples/text.html +2 -2
  67. data/spec/html_examples/text.org +16 -16
  68. data/spec/line_spec.rb +151 -151
  69. data/spec/output_buffer_spec.rb +19 -0
  70. data/spec/parser_spec.rb +152 -166
  71. data/spec/regexp_helper_spec.rb +57 -57
  72. data/spec/spec_helper.rb +21 -21
  73. data/spec/textile_examples/block_code.org +35 -35
  74. data/spec/textile_examples/block_code.textile +29 -29
  75. data/spec/textile_examples/blockquote.org +13 -13
  76. data/spec/textile_examples/blockquote.textile +11 -11
  77. data/spec/textile_examples/keywords.org +13 -13
  78. data/spec/textile_examples/keywords.textile +11 -11
  79. data/spec/textile_examples/links.org +11 -11
  80. data/spec/textile_examples/links.textile +10 -10
  81. data/spec/textile_examples/lists.org +36 -36
  82. data/spec/textile_examples/lists.textile +20 -20
  83. data/spec/textile_examples/single-space-plain-list.org +13 -13
  84. data/spec/textile_examples/single-space-plain-list.textile +10 -10
  85. data/spec/textile_examples/tables.org +26 -26
  86. data/spec/textile_examples/tables.textile +23 -23
  87. data/spec/textile_output_buffer_spec.rb +21 -21
  88. data/tasks/test_case.rake +49 -49
  89. metadata +3 -2
@@ -1,156 +1,156 @@
1
- require 'logger'
2
-
3
- module Orgmode
4
-
5
- # = Summary
6
- #
7
- # This class contains helper routines to deal with the Regexp "black
8
- # magic" you need to properly parse org-mode files.
9
- #
10
- # = Key methods
11
- #
12
- # * Use +rewrite_emphasis+ to replace org-mode emphasis strings (e.g.,
13
- # \/italic/) with the suitable markup for the output.
14
- #
15
- # * Use +rewrite_links+ to get a chance to rewrite all org-mode
16
- # links with suitable markup for the output.
17
- class RegexpHelper
18
-
19
- ######################################################################
20
- # EMPHASIS
21
- #
22
- # I figure it's best to stick as closely to the elisp implementation
23
- # as possible for emphasis. org.el defines the regular expression that
24
- # is used to apply "emphasis" (in my terminology, inline formatting
25
- # instead of block formatting). Here's the documentation from org.el.
26
- #
27
- # Terminology: In an emphasis string like " *strong word* ", we
28
- # call the initial space PREMATCH, the final space POSTMATCH, the
29
- # stars MARKERS, "s" and "d" are BORDER characters and "trong wor"
30
- # is the body. The different components in this variable specify
31
- # what is allowed/forbidden in each part:
32
- #
33
- # pre Chars allowed as prematch. Line beginning allowed, too.
34
- # post Chars allowed as postmatch. Line end will be allowed too.
35
- # border The chars *forbidden* as border characters.
36
- # body-regexp A regexp like \".\" to match a body character. Don't use
37
- # non-shy groups here, and don't allow newline here.
38
- # newline The maximum number of newlines allowed in an emphasis exp.
39
- #
40
- # I currently don't use +newline+ because I've thrown this information
41
- # away by this point in the code. TODO -- revisit?
42
- attr_reader :pre_emphasis
43
- attr_reader :post_emphasis
44
- attr_reader :border_forbidden
45
- attr_reader :body_regexp
46
- attr_reader :markers
47
-
48
- attr_reader :org_emphasis_regexp
49
-
50
- def initialize
51
- # Set up the emphasis regular expression.
52
- @pre_emphasis = " \t\\('\""
53
- @post_emphasis = "- \t.,:!?;'\"\\)"
54
- @border_forbidden = " \t\r\n,\"'"
55
- @body_regexp = ".*?"
56
- @markers = "*/_=~+"
57
- @logger = Logger.new(STDERR)
58
- @logger.level = Logger::WARN
59
- build_org_emphasis_regexp
60
- build_org_link_regexp
61
- end
62
-
63
- # Finds all emphasis matches in a string.
64
- # Supply a block that will get the marker and body as parameters.
65
- def match_all(str)
66
- str.scan(@org_emphasis_regexp) do |match|
67
- yield $2, $3
68
- end
69
- end
70
-
71
- # Compute replacements for all matching emphasized phrases.
72
- # Supply a block that will get the marker and body as parameters;
73
- # return the replacement string from your block.
74
- #
75
- # = Example
76
- #
77
- # re = RegexpHelper.new
78
- # result = re.rewrite_emphasis("*bold*, /italic/, =code=") do |marker, body|
79
- # "<#{map[marker]}>#{body}</#{map[marker]}>"
80
- # end
81
- #
82
- # In this example, the block body will get called three times:
83
- #
84
- # 1. Marker: "*", body: "bold"
85
- # 2. Marker: "/", body: "italic"
86
- # 3. Marker: "=", body: "code"
87
- #
88
- # The return from this block is a string that will be used to
89
- # replace "*bold*", "/italic/", and "=code=",
90
- # respectively. (Clearly this sample string will use HTML-like
91
- # syntax, assuming +map+ is defined appropriately.)
92
- def rewrite_emphasis(str)
93
- str.gsub(@org_emphasis_regexp) do |match|
94
- inner = yield $2, $3
95
- "#{$1}#{inner}#{$4}"
96
- end
97
- end
98
-
99
- # = Summary
100
- #
101
- # Rewrite org-mode links in a string to markup suitable to the
102
- # output format.
103
- #
104
- # = Usage
105
- #
106
- # Give this a block that expect the link and optional friendly
107
- # text. Return how that link should get formatted.
108
- #
109
- # = Example
110
- #
111
- # re = RegexpHelper.new
112
- # result = re.rewrite_links("[[http://www.bing.com]] and [[http://www.hotmail.com][Hotmail]]") do |link, text}
113
- # text ||= link
114
- # "<a href=\"#{link}\">#{text}</a>"
115
- # end
116
- #
117
- # In this example, the block body will get called two times. In the
118
- # first instance, +text+ will be nil (the org-mode markup gives no
119
- # friendly text for the link +http://www.bing.com+. In the second
120
- # instance, the block will get text of *Hotmail* and the link
121
- # +http://www.hotmail.com+. In both cases, the block returns an
122
- # HTML-style link, and that is how things will get recorded in
123
- # +result+.
124
- def rewrite_links(str)
125
- i = str.gsub(@org_link_regexp) do |match|
126
- yield $1, nil
127
- end
128
- i.gsub(@org_link_text_regexp) do |match|
129
- yield $1, $2
130
- end
131
- end
132
-
133
- private
134
-
135
- def build_org_emphasis_regexp
136
- @org_emphasis_regexp = Regexp.new("([#{@pre_emphasis}]|^)\n" +
137
- "( [#{@markers}] )\n" +
138
- "( [^#{@border_forbidden}] | " +
139
- " [^#{@border_forbidden}]#{@body_regexp}[^#{@border_forbidden}] )\n" +
140
- "\\2\n" +
141
- "([#{@post_emphasis}]|$)\n", Regexp::EXTENDED)
142
- @logger.debug "Just created regexp: #{@org_emphasis_regexp}"
143
- end
144
-
145
- def build_org_link_regexp
146
- @org_link_regexp = /\[\[
147
- ([^\]]*) # This is the URL
148
- \]\]/x
149
- @org_link_text_regexp = /\[\[
150
- ([^\]]*) # This is the URL
151
- \]\[
152
- ([^\]]*) # This is the friendly text
153
- \]\]/x
154
- end
155
- end # class Emphasis
156
- end # module Orgmode
1
+ require 'logger'
2
+
3
+ module Orgmode
4
+
5
+ # = Summary
6
+ #
7
+ # This class contains helper routines to deal with the Regexp "black
8
+ # magic" you need to properly parse org-mode files.
9
+ #
10
+ # = Key methods
11
+ #
12
+ # * Use +rewrite_emphasis+ to replace org-mode emphasis strings (e.g.,
13
+ # \/italic/) with the suitable markup for the output.
14
+ #
15
+ # * Use +rewrite_links+ to get a chance to rewrite all org-mode
16
+ # links with suitable markup for the output.
17
+ class RegexpHelper
18
+
19
+ ######################################################################
20
+ # EMPHASIS
21
+ #
22
+ # I figure it's best to stick as closely to the elisp implementation
23
+ # as possible for emphasis. org.el defines the regular expression that
24
+ # is used to apply "emphasis" (in my terminology, inline formatting
25
+ # instead of block formatting). Here's the documentation from org.el.
26
+ #
27
+ # Terminology: In an emphasis string like " *strong word* ", we
28
+ # call the initial space PREMATCH, the final space POSTMATCH, the
29
+ # stars MARKERS, "s" and "d" are BORDER characters and "trong wor"
30
+ # is the body. The different components in this variable specify
31
+ # what is allowed/forbidden in each part:
32
+ #
33
+ # pre Chars allowed as prematch. Line beginning allowed, too.
34
+ # post Chars allowed as postmatch. Line end will be allowed too.
35
+ # border The chars *forbidden* as border characters.
36
+ # body-regexp A regexp like \".\" to match a body character. Don't use
37
+ # non-shy groups here, and don't allow newline here.
38
+ # newline The maximum number of newlines allowed in an emphasis exp.
39
+ #
40
+ # I currently don't use +newline+ because I've thrown this information
41
+ # away by this point in the code. TODO -- revisit?
42
+ attr_reader :pre_emphasis
43
+ attr_reader :post_emphasis
44
+ attr_reader :border_forbidden
45
+ attr_reader :body_regexp
46
+ attr_reader :markers
47
+
48
+ attr_reader :org_emphasis_regexp
49
+
50
+ def initialize
51
+ # Set up the emphasis regular expression.
52
+ @pre_emphasis = " \t\\('\""
53
+ @post_emphasis = "- \t.,:!?;'\"\\)"
54
+ @border_forbidden = " \t\r\n,\"'"
55
+ @body_regexp = ".*?"
56
+ @markers = "*/_=~+"
57
+ @logger = Logger.new(STDERR)
58
+ @logger.level = Logger::WARN
59
+ build_org_emphasis_regexp
60
+ build_org_link_regexp
61
+ end
62
+
63
+ # Finds all emphasis matches in a string.
64
+ # Supply a block that will get the marker and body as parameters.
65
+ def match_all(str)
66
+ str.scan(@org_emphasis_regexp) do |match|
67
+ yield $2, $3
68
+ end
69
+ end
70
+
71
+ # Compute replacements for all matching emphasized phrases.
72
+ # Supply a block that will get the marker and body as parameters;
73
+ # return the replacement string from your block.
74
+ #
75
+ # = Example
76
+ #
77
+ # re = RegexpHelper.new
78
+ # result = re.rewrite_emphasis("*bold*, /italic/, =code=") do |marker, body|
79
+ # "<#{map[marker]}>#{body}</#{map[marker]}>"
80
+ # end
81
+ #
82
+ # In this example, the block body will get called three times:
83
+ #
84
+ # 1. Marker: "*", body: "bold"
85
+ # 2. Marker: "/", body: "italic"
86
+ # 3. Marker: "=", body: "code"
87
+ #
88
+ # The return from this block is a string that will be used to
89
+ # replace "*bold*", "/italic/", and "=code=",
90
+ # respectively. (Clearly this sample string will use HTML-like
91
+ # syntax, assuming +map+ is defined appropriately.)
92
+ def rewrite_emphasis(str)
93
+ str.gsub(@org_emphasis_regexp) do |match|
94
+ inner = yield $2, $3
95
+ "#{$1}#{inner}#{$4}"
96
+ end
97
+ end
98
+
99
+ # = Summary
100
+ #
101
+ # Rewrite org-mode links in a string to markup suitable to the
102
+ # output format.
103
+ #
104
+ # = Usage
105
+ #
106
+ # Give this a block that expect the link and optional friendly
107
+ # text. Return how that link should get formatted.
108
+ #
109
+ # = Example
110
+ #
111
+ # re = RegexpHelper.new
112
+ # result = re.rewrite_links("[[http://www.bing.com]] and [[http://www.hotmail.com][Hotmail]]") do |link, text}
113
+ # text ||= link
114
+ # "<a href=\"#{link}\">#{text}</a>"
115
+ # end
116
+ #
117
+ # In this example, the block body will get called two times. In the
118
+ # first instance, +text+ will be nil (the org-mode markup gives no
119
+ # friendly text for the link +http://www.bing.com+. In the second
120
+ # instance, the block will get text of *Hotmail* and the link
121
+ # +http://www.hotmail.com+. In both cases, the block returns an
122
+ # HTML-style link, and that is how things will get recorded in
123
+ # +result+.
124
+ def rewrite_links(str)
125
+ i = str.gsub(@org_link_regexp) do |match|
126
+ yield $1, nil
127
+ end
128
+ i.gsub(@org_link_text_regexp) do |match|
129
+ yield $1, $2
130
+ end
131
+ end
132
+
133
+ private
134
+
135
+ def build_org_emphasis_regexp
136
+ @org_emphasis_regexp = Regexp.new("([#{@pre_emphasis}]|^)\n" +
137
+ "( [#{@markers}] )\n" +
138
+ "( [^#{@border_forbidden}] | " +
139
+ " [^#{@border_forbidden}]#{@body_regexp}[^#{@border_forbidden}] )\n" +
140
+ "\\2\n" +
141
+ "([#{@post_emphasis}]|$)\n", Regexp::EXTENDED)
142
+ @logger.debug "Just created regexp: #{@org_emphasis_regexp}"
143
+ end
144
+
145
+ def build_org_link_regexp
146
+ @org_link_regexp = /\[\[
147
+ ([^\]]*) # This is the URL
148
+ \]\]/x
149
+ @org_link_text_regexp = /\[\[
150
+ ([^\]]*) # This is the URL
151
+ \]\[
152
+ ([^\]]*) # This is the friendly text
153
+ \]\]/x
154
+ end
155
+ end # class Emphasis
156
+ end # module Orgmode
@@ -1,68 +1,67 @@
1
- require 'stringio'
2
-
3
- module Orgmode
4
-
5
- class TextileOutputBuffer < OutputBuffer
6
-
7
- def initialize(output)
8
- super(output)
9
- @add_paragraph = false
10
- end
11
-
12
- def push_mode(mode)
13
- super(mode)
14
- @output << "bc.. " if mode_is_code(mode)
15
- end
16
-
17
- def pop_mode(mode = nil)
18
- m = super(mode)
19
- @add_paragraph = (mode_is_code(m))
20
- m
21
- end
22
-
23
- # Maps org markup to textile markup.
24
- TextileMap = {
25
- "*" => "*",
26
- "/" => "_",
27
- "_" => "_",
28
- "=" => "@",
29
- "~" => "@",
30
- "+" => "+"
31
- }
32
-
33
- # Handles inline formatting for textile.
34
- def inline_formatting(input)
35
- input = @re_help.rewrite_emphasis(input) do |marker, body|
36
- m = TextileMap[marker]
37
- "#{m}#{body}#{m}"
38
- end
39
- input = @re_help.rewrite_links(input) do |link, text|
40
- text ||= link
41
- link = link.gsub(/ /, "%20")
42
- "\"#{text}\":#{link}"
43
- end
44
- input
45
- end
46
-
47
- # Flushes the current buffer
48
- def flush!
49
- @logger.debug "FLUSH ==========> #{@output_type}"
50
- if (@output_type == :blank) then
51
- @output << "\n"
52
- elsif (@buffer.length > 0) then
53
- if @add_paragraph then
54
- @output << "p. " if @output_type == :paragraph
55
- @add_paragraph = false
56
- end
57
- @output << "bq. " if current_mode == :blockquote
58
- @output << "#" * @list_indent_stack.length << " " if @output_type == :ordered_list
59
- @output << "*" * @list_indent_stack.length << " " if @output_type == :unordered_list
60
- @output << inline_formatting(@buffer) << "\n"
61
- end
62
- @buffer = ""
63
- @buffer_mode = nil
64
- end
65
-
66
-
67
- end # class TextileOutputBuffer
68
- end # module Orgmode
1
+ require 'stringio'
2
+
3
+ module Orgmode
4
+
5
+ class TextileOutputBuffer < OutputBuffer
6
+
7
+ def initialize(output)
8
+ super(output)
9
+ @add_paragraph = false
10
+ end
11
+
12
+ def push_mode(mode)
13
+ super(mode)
14
+ @output << "bc.. " if mode_is_code(mode)
15
+ end
16
+
17
+ def pop_mode(mode = nil)
18
+ m = super(mode)
19
+ @add_paragraph = (mode_is_code(m))
20
+ m
21
+ end
22
+
23
+ # Maps org markup to textile markup.
24
+ TextileMap = {
25
+ "*" => "*",
26
+ "/" => "_",
27
+ "_" => "_",
28
+ "=" => "@",
29
+ "~" => "@",
30
+ "+" => "+"
31
+ }
32
+
33
+ # Handles inline formatting for textile.
34
+ def inline_formatting(input)
35
+ input = @re_help.rewrite_emphasis(input) do |marker, body|
36
+ m = TextileMap[marker]
37
+ "#{m}#{body}#{m}"
38
+ end
39
+ input = @re_help.rewrite_links(input) do |link, text|
40
+ text ||= link
41
+ link = link.gsub(/ /, "%20")
42
+ "\"#{text}\":#{link}"
43
+ end
44
+ input
45
+ end
46
+
47
+ # Flushes the current buffer
48
+ def flush!
49
+ @logger.debug "FLUSH ==========> #{@output_type}"
50
+ if (@output_type == :blank) then
51
+ @output << "\n"
52
+ elsif (@buffer.length > 0) then
53
+ if @add_paragraph then
54
+ @output << "p. " if @output_type == :paragraph
55
+ @add_paragraph = false
56
+ end
57
+ @output << "bq. " if current_mode == :blockquote
58
+ @output << "#" * @list_indent_stack.length << " " if @output_type == :ordered_list
59
+ @output << "*" * @list_indent_stack.length << " " if @output_type == :unordered_list
60
+ @output << inline_formatting(@buffer) << "\n"
61
+ end
62
+ clear_accumulation_buffer!
63
+ end
64
+
65
+
66
+ end # class TextileOutputBuffer
67
+ end # module Orgmode
@@ -1,113 +1,113 @@
1
- #+BEGIN_EXAMPLE
2
- #+TITLE: Freeform
3
- #+AUTHOR:
4
- #+EMAIL: bdewey@gmail.com
5
- #+DATE: 2009-12-20 Sun
6
- #+DESCRIPTION:
7
- #+KEYWORDS:
8
- #+LANGUAGE: en
9
- #+OPTIONS: H:3 num:t toc:nil \n:nil @:t ::t |:t ^:t -:t f:t *:t <:t
10
- #+OPTIONS: TeX:t LaTeX:nil skip:nil d:nil todo:t pri:nil tags:not-in-toc
11
- #+INFOJS_OPT: view:nil toc:nil ltoc:t mouse:underline buttons:0 path:http://orgmode.org/org-info.js
12
- #+EXPORT_SELECT_TAGS: export
13
- #+EXPORT_EXCLUDE_TAGS: noexport
14
- #+LINK_UP:
15
- #+LINK_HOME:
16
- #+END_EXAMPLE
17
- Freeform
18
-
19
- This is my todo list, research file, and log record from working on
20
- the Freeform project.
21
-
22
- * Future ideas :someday:
23
- - Add *posts*
24
- - Enforce uniqueness of url_token
25
- - Add FeedSync support
26
- - Auto-recognize URLs
27
- - Edit in place
28
- - Import/export of content. I want it to be safe to store real content on the site.
29
- - Page reordering.
30
- - AtomPub support.
31
- - Organization:
32
- - Move pages around
33
- - Add tags and navigation by tags
34
- - Add a breadcrumb bar
35
-
36
- * TODO Add versioning support :current:feature:
37
-
38
- ** DONE UI rough-in
39
- CLOSED: [2009-11-26 Thu]
40
-
41
- ** DONE Author logging
42
- CLOSED: [2009-11-27 Fri]
43
-
44
- ** DONE Version table and model updates
45
- CLOSED: [2009-11-28 Sat 22:40]
46
- CLOCK: [2009-11-28 Sat 21:35]--[2009-11-28 Sat 22:40] => 1:05
47
- CLOCK: [2009-11-28 Sat 21:01]--[2009-11-28 Sat 21:25] => 0:24
48
- CLOCK: [2009-11-28 Sat 19:46]--[2009-11-28 Sat 20:54] => 1:08
49
- CLOCK: [2009-11-28 Sat 14:38]--[2009-11-28 Sat 15:08] => 0:30
50
- CLOCK: [2009-11-28 Sat 13:21]--[2009-11-28 Sat 14:37] => 1:16
51
-
52
- OK, my current thinking is to have each idea have many Changes. A
53
- change has many change records. A change record is a list of
54
- specific attributes that change, and includes the old and the new
55
- values. I'll use callbacks on the Idea model to maintain the
56
- changes.
57
-
58
-
59
- *** DONE Create version method
60
- CLOSED: [2009-11-28 Sat 22:40]
61
-
62
- *** DONE Make current method
63
- CLOSED: [2009-11-28 Sat 22:40]
64
-
65
- ** Update pages controller
66
-
67
- *** DONE Show versions
68
- CLOSED: [2009-11-30 Mon 00:34]
69
- CLOCK: [2009-11-29 Sun 21:27]--[2009-11-29 Sun 21:54] => 0:27
70
- CLOCK: [2009-11-29 Sun 15:40]--[2009-11-29 Sun 15:44] => 0:04
71
- CLOCK: [2009-11-28 Sat 22:44]--[2009-11-28 Sat 23:50] => 1:06
72
-
73
- I'm now at the point where I *list* versions, but I can't show
74
- them.
75
-
76
- - [X] I currently suspect that I broke my version recovery code
77
- when I switched the order of the idea_changes. I need to
78
- investigate why nothing's failing in the tests; I expected
79
- failures. Possible addition to test: start looking at those
80
- version numbers.
81
-
82
- OK, here's what was going on: In the test, you need to
83
- reload the idea_changes array from the database to get the
84
- database sort order. I also make sure I do this inside the
85
- Idea methods.
86
-
87
- **** DONE Write a test for Idea::attributes_for_change
88
- CLOSED: [2009-11-29 Sun 23:59]
89
- CLOCK: [2009-11-29 Sun 23:47]--[2009-11-29 Sun 23:58] => 0:11
90
- CLOCK: [2009-11-29 Sun 22:02]--[2009-11-29 Sun 23:42] => 1:40
91
- CLOCK: [2009-11-29 Sun 21:54]--[2009-11-29 Sun 21:56] => 0:02
92
-
93
- *** DONE Write integration tests that cover versions.
94
- CLOSED: [2009-12-11 Fri 23:25]
95
- CLOCK: [2009-12-11 Fri 20:27]--[2009-12-11 Fri 23:25] => 2:58
96
-
97
- *** DONE Recover versions
98
- CLOSED: [2009-12-12 Sat 22:09]
99
- CLOCK: [2009-12-12 Sat 21:02]--[2009-12-12 Sat 22:09] => 1:07
100
- CLOCK: [2009-12-12 Sat 20:13]--[2009-12-12 Sat 21:00] => 0:47
101
-
102
- *** DONE Move to recycle bin
103
- CLOSED: [2009-12-12 Sat 22:59]
104
- CLOCK: [2009-12-12 Sat 22:23]--[2009-12-12 Sat 22:59] => 0:36
105
-
106
- Note I'm avoiding logging delete operations because I'm presuming
107
- there will be a recycle bin, and therefore the *pages* controller
108
- will never actually delete files. At some point, when I want to
109
- support full FeedSync, I'll need to tackle this.
110
-
111
- The other timebomb: I don't know how well my logging scheme will
112
- work when pages move. I don't yet know if I will address this in
113
- the current sprint.
1
+ #+BEGIN_EXAMPLE
2
+ #+TITLE: Freeform
3
+ #+AUTHOR:
4
+ #+EMAIL: bdewey@gmail.com
5
+ #+DATE: 2009-12-20 Sun
6
+ #+DESCRIPTION:
7
+ #+KEYWORDS:
8
+ #+LANGUAGE: en
9
+ #+OPTIONS: H:3 num:t toc:nil \n:nil @:t ::t |:t ^:t -:t f:t *:t <:t
10
+ #+OPTIONS: TeX:t LaTeX:nil skip:nil d:nil todo:t pri:nil tags:not-in-toc
11
+ #+INFOJS_OPT: view:nil toc:nil ltoc:t mouse:underline buttons:0 path:http://orgmode.org/org-info.js
12
+ #+EXPORT_SELECT_TAGS: export
13
+ #+EXPORT_EXCLUDE_TAGS: noexport
14
+ #+LINK_UP:
15
+ #+LINK_HOME:
16
+ #+END_EXAMPLE
17
+ Freeform
18
+
19
+ This is my todo list, research file, and log record from working on
20
+ the Freeform project.
21
+
22
+ * Future ideas :someday:
23
+ - Add *posts*
24
+ - Enforce uniqueness of url_token
25
+ - Add FeedSync support
26
+ - Auto-recognize URLs
27
+ - Edit in place
28
+ - Import/export of content. I want it to be safe to store real content on the site.
29
+ - Page reordering.
30
+ - AtomPub support.
31
+ - Organization:
32
+ - Move pages around
33
+ - Add tags and navigation by tags
34
+ - Add a breadcrumb bar
35
+
36
+ * TODO Add versioning support :current:feature:
37
+
38
+ ** DONE UI rough-in
39
+ CLOSED: [2009-11-26 Thu]
40
+
41
+ ** DONE Author logging
42
+ CLOSED: [2009-11-27 Fri]
43
+
44
+ ** DONE Version table and model updates
45
+ CLOSED: [2009-11-28 Sat 22:40]
46
+ CLOCK: [2009-11-28 Sat 21:35]--[2009-11-28 Sat 22:40] => 1:05
47
+ CLOCK: [2009-11-28 Sat 21:01]--[2009-11-28 Sat 21:25] => 0:24
48
+ CLOCK: [2009-11-28 Sat 19:46]--[2009-11-28 Sat 20:54] => 1:08
49
+ CLOCK: [2009-11-28 Sat 14:38]--[2009-11-28 Sat 15:08] => 0:30
50
+ CLOCK: [2009-11-28 Sat 13:21]--[2009-11-28 Sat 14:37] => 1:16
51
+
52
+ OK, my current thinking is to have each idea have many Changes. A
53
+ change has many change records. A change record is a list of
54
+ specific attributes that change, and includes the old and the new
55
+ values. I'll use callbacks on the Idea model to maintain the
56
+ changes.
57
+
58
+
59
+ *** DONE Create version method
60
+ CLOSED: [2009-11-28 Sat 22:40]
61
+
62
+ *** DONE Make current method
63
+ CLOSED: [2009-11-28 Sat 22:40]
64
+
65
+ ** Update pages controller
66
+
67
+ *** DONE Show versions
68
+ CLOSED: [2009-11-30 Mon 00:34]
69
+ CLOCK: [2009-11-29 Sun 21:27]--[2009-11-29 Sun 21:54] => 0:27
70
+ CLOCK: [2009-11-29 Sun 15:40]--[2009-11-29 Sun 15:44] => 0:04
71
+ CLOCK: [2009-11-28 Sat 22:44]--[2009-11-28 Sat 23:50] => 1:06
72
+
73
+ I'm now at the point where I *list* versions, but I can't show
74
+ them.
75
+
76
+ - [X] I currently suspect that I broke my version recovery code
77
+ when I switched the order of the idea_changes. I need to
78
+ investigate why nothing's failing in the tests; I expected
79
+ failures. Possible addition to test: start looking at those
80
+ version numbers.
81
+
82
+ OK, here's what was going on: In the test, you need to
83
+ reload the idea_changes array from the database to get the
84
+ database sort order. I also make sure I do this inside the
85
+ Idea methods.
86
+
87
+ **** DONE Write a test for Idea::attributes_for_change
88
+ CLOSED: [2009-11-29 Sun 23:59]
89
+ CLOCK: [2009-11-29 Sun 23:47]--[2009-11-29 Sun 23:58] => 0:11
90
+ CLOCK: [2009-11-29 Sun 22:02]--[2009-11-29 Sun 23:42] => 1:40
91
+ CLOCK: [2009-11-29 Sun 21:54]--[2009-11-29 Sun 21:56] => 0:02
92
+
93
+ *** DONE Write integration tests that cover versions.
94
+ CLOSED: [2009-12-11 Fri 23:25]
95
+ CLOCK: [2009-12-11 Fri 20:27]--[2009-12-11 Fri 23:25] => 2:58
96
+
97
+ *** DONE Recover versions
98
+ CLOSED: [2009-12-12 Sat 22:09]
99
+ CLOCK: [2009-12-12 Sat 21:02]--[2009-12-12 Sat 22:09] => 1:07
100
+ CLOCK: [2009-12-12 Sat 20:13]--[2009-12-12 Sat 21:00] => 0:47
101
+
102
+ *** DONE Move to recycle bin
103
+ CLOSED: [2009-12-12 Sat 22:59]
104
+ CLOCK: [2009-12-12 Sat 22:23]--[2009-12-12 Sat 22:59] => 0:36
105
+
106
+ Note I'm avoiding logging delete operations because I'm presuming
107
+ there will be a recycle bin, and therefore the *pages* controller
108
+ will never actually delete files. At some point, when I want to
109
+ support full FeedSync, I'll need to tackle this.
110
+
111
+ The other timebomb: I don't know how well my logging scheme will
112
+ work when pages move. I don't yet know if I will address this in
113
+ the current sprint.