org-ruby 0.5.1 → 0.5.2

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.
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.