org-ruby 0.4.0 → 0.4.1

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 (63) hide show
  1. data/History.txt +45 -40
  2. data/{README.txt → README.rdoc} +66 -66
  3. data/Rakefile +28 -27
  4. data/bin/org-ruby +40 -40
  5. data/lib/org-ruby.rb +50 -50
  6. data/lib/org-ruby/headline.rb +80 -80
  7. data/lib/org-ruby/html_output_buffer.rb +117 -105
  8. data/lib/org-ruby/line.rb +178 -173
  9. data/lib/org-ruby/output_buffer.rb +172 -172
  10. data/lib/org-ruby/parser.rb +80 -80
  11. data/lib/org-ruby/regexp_helper.rb +156 -156
  12. data/lib/org-ruby/textile_output_buffer.rb +67 -67
  13. data/spec/data/freeform.org +111 -111
  14. data/spec/data/hyp-planning.org +335 -335
  15. data/spec/data/remember.org +53 -53
  16. data/spec/headline_spec.rb +55 -55
  17. data/spec/html_examples/advanced-lists.html +31 -31
  18. data/spec/html_examples/advanced-lists.org +31 -31
  19. data/spec/html_examples/block_code.html +30 -30
  20. data/spec/html_examples/block_code.org +35 -35
  21. data/spec/html_examples/blockquote.html +7 -7
  22. data/spec/html_examples/blockquote.org +13 -13
  23. data/spec/html_examples/code-comment.html +19 -0
  24. data/spec/html_examples/code-comment.org +22 -0
  25. data/spec/html_examples/escape-pre.html +7 -7
  26. data/spec/html_examples/escape-pre.org +6 -6
  27. data/spec/html_examples/html-literal.html +2 -0
  28. data/spec/html_examples/html-literal.org +6 -0
  29. data/spec/html_examples/inline-formatting.html +10 -10
  30. data/spec/html_examples/inline-formatting.org +17 -17
  31. data/spec/html_examples/lists.html +19 -19
  32. data/spec/html_examples/lists.org +36 -36
  33. data/spec/html_examples/metadata-comment.org-fail +30 -0
  34. data/spec/html_examples/only-list.html +5 -5
  35. data/spec/html_examples/only-list.org +3 -3
  36. data/spec/html_examples/only-table.html +6 -6
  37. data/spec/html_examples/only-table.org +5 -5
  38. data/spec/html_examples/tables.html +20 -20
  39. data/spec/html_examples/tables.org +26 -26
  40. data/spec/html_examples/text.html +2 -2
  41. data/spec/html_examples/text.org +16 -16
  42. data/spec/line_spec.rb +89 -89
  43. data/spec/parser_spec.rb +86 -86
  44. data/spec/regexp_helper_spec.rb +57 -57
  45. data/spec/spec_helper.rb +20 -20
  46. data/spec/textile_examples/block_code.org +35 -35
  47. data/spec/textile_examples/block_code.textile +29 -29
  48. data/spec/textile_examples/blockquote.org +13 -13
  49. data/spec/textile_examples/blockquote.textile +11 -11
  50. data/spec/textile_examples/keywords.org +13 -13
  51. data/spec/textile_examples/keywords.textile +11 -11
  52. data/spec/textile_examples/links.org +11 -11
  53. data/spec/textile_examples/links.textile +10 -10
  54. data/spec/textile_examples/lists.org +36 -36
  55. data/spec/textile_examples/lists.textile +20 -20
  56. data/spec/textile_examples/single-space-plain-list.org +13 -13
  57. data/spec/textile_examples/single-space-plain-list.textile +10 -10
  58. data/spec/textile_examples/tables.org +26 -26
  59. data/spec/textile_examples/tables.textile +23 -23
  60. data/spec/textile_output_buffer_spec.rb +21 -21
  61. data/tasks/test_case.rake +49 -49
  62. metadata +10 -6
  63. data/.bnsignore +0 -18
@@ -1,80 +1,80 @@
1
- require OrgRuby.libpath(*%w[org-ruby line])
2
-
3
- module Orgmode
4
-
5
- # Represents a headline in an orgmode file.
6
- class Headline < Line
7
-
8
- # This is the "level" of the headline
9
- attr_reader :level
10
-
11
- # This is the headline text -- the part of the headline minus the leading
12
- # asterisks, the keywords, and the tags.
13
- attr_reader :headline_text
14
-
15
- # This contains the lines that "belong" to the headline.
16
- attr_reader :body_lines
17
-
18
- # These are the headline tags
19
- attr_reader :tags
20
-
21
- # Optional keyword found at the beginning of the headline.
22
- attr_reader :keyword
23
-
24
- # This is the regex that matches a line
25
- LineRegexp = /^\*+\s+/
26
-
27
- # This matches the tags on a headline
28
- TagsRegexp = /\s*:[\w:]*:\s*$/
29
-
30
- # Special keywords allowed at the start of a line.
31
- Keywords = %w[TODO DONE]
32
-
33
- KeywordsRegexp = Regexp.new("\\s*(#{Keywords.join('|')})\\s*")
34
-
35
- def initialize(line)
36
- super(line)
37
- @body_lines = []
38
- @tags = []
39
- if (@line =~ LineRegexp) then
40
- @level = $&.strip.length
41
- @headline_text = $'.strip
42
- if (@headline_text =~ TagsRegexp) then
43
- @tags = $&.split(/:/) # split tag text on semicolon
44
- @tags.delete_at(0) # the first item will be empty; discard
45
- @headline_text.gsub!(TagsRegexp, "") # Removes the tags from the headline
46
- end
47
- if (@headline_text =~ KeywordsRegexp) then
48
- @headline_text = $'
49
- @keyword = $1
50
- end
51
- else
52
- raise "'#{line}' is not a valid headline"
53
- end
54
- end
55
-
56
- # Determines if a line is an orgmode "headline":
57
- # A headline begins with one or more asterisks.
58
- def self.headline?(line)
59
- line =~ LineRegexp
60
- end
61
-
62
- # Converts this headline and its body to textile.
63
- def to_textile
64
- output = "h#{@level}. #{@headline_text}\n"
65
- output << Line.to_textile(@body_lines)
66
- output
67
- end
68
-
69
- def to_html(opts = {})
70
- if opts[:decorate_title]
71
- decoration = " class=\"title\""
72
- else
73
- decoration = ""
74
- end
75
- output = "<h#{@level}#{decoration}>#{@headline_text}</h#{@level}>\n"
76
- output << Line.to_html(@body_lines)
77
- output
78
- end
79
- end # class Headline
80
- end # class Orgmode
1
+ require OrgRuby.libpath(*%w[org-ruby line])
2
+
3
+ module Orgmode
4
+
5
+ # Represents a headline in an orgmode file.
6
+ class Headline < Line
7
+
8
+ # This is the "level" of the headline
9
+ attr_reader :level
10
+
11
+ # This is the headline text -- the part of the headline minus the leading
12
+ # asterisks, the keywords, and the tags.
13
+ attr_reader :headline_text
14
+
15
+ # This contains the lines that "belong" to the headline.
16
+ attr_reader :body_lines
17
+
18
+ # These are the headline tags
19
+ attr_reader :tags
20
+
21
+ # Optional keyword found at the beginning of the headline.
22
+ attr_reader :keyword
23
+
24
+ # This is the regex that matches a line
25
+ LineRegexp = /^\*+\s+/
26
+
27
+ # This matches the tags on a headline
28
+ TagsRegexp = /\s*:[\w:]*:\s*$/
29
+
30
+ # Special keywords allowed at the start of a line.
31
+ Keywords = %w[TODO DONE]
32
+
33
+ KeywordsRegexp = Regexp.new("\\s*(#{Keywords.join('|')})\\s*")
34
+
35
+ def initialize(line)
36
+ super(line)
37
+ @body_lines = []
38
+ @tags = []
39
+ if (@line =~ LineRegexp) then
40
+ @level = $&.strip.length
41
+ @headline_text = $'.strip
42
+ if (@headline_text =~ TagsRegexp) then
43
+ @tags = $&.split(/:/) # split tag text on semicolon
44
+ @tags.delete_at(0) # the first item will be empty; discard
45
+ @headline_text.gsub!(TagsRegexp, "") # Removes the tags from the headline
46
+ end
47
+ if (@headline_text =~ KeywordsRegexp) then
48
+ @headline_text = $'
49
+ @keyword = $1
50
+ end
51
+ else
52
+ raise "'#{line}' is not a valid headline"
53
+ end
54
+ end
55
+
56
+ # Determines if a line is an orgmode "headline":
57
+ # A headline begins with one or more asterisks.
58
+ def self.headline?(line)
59
+ line =~ LineRegexp
60
+ end
61
+
62
+ # Converts this headline and its body to textile.
63
+ def to_textile
64
+ output = "h#{@level}. #{@headline_text}\n"
65
+ output << Line.to_textile(@body_lines)
66
+ output
67
+ end
68
+
69
+ def to_html(opts = {})
70
+ if opts[:decorate_title]
71
+ decoration = " class=\"title\""
72
+ else
73
+ decoration = ""
74
+ end
75
+ output = "<h#{@level}#{decoration}>#{@headline_text}</h#{@level}>\n"
76
+ output << Line.to_html(@body_lines)
77
+ output
78
+ end
79
+ end # class Headline
80
+ end # class Orgmode
@@ -1,105 +1,117 @@
1
- require OrgRuby.libpath(*%w[org-ruby output_buffer])
2
- require 'cgi'
3
-
4
- module Orgmode
5
-
6
- class HtmlOutputBuffer < OutputBuffer
7
-
8
- HtmlBlockTag = {
9
- :paragraph => "p",
10
- :ordered_list => "li",
11
- :unordered_list => "li",
12
- :table_row => "tr"
13
- }
14
-
15
- ModeTag = {
16
- :unordered_list => "ul",
17
- :ordered_list => "ol",
18
- :table => "table",
19
- :blockquote => "blockquote",
20
- :code => "pre"
21
- }
22
-
23
- def initialize(output, opts = {})
24
- super(output)
25
- if opts[:decorate_title] then
26
- @title_decoration = " class=\"title\""
27
- else
28
- @title_decoration = ""
29
- end
30
- end
31
-
32
- def push_mode(mode)
33
- if ModeTag[mode] then
34
- output_indentation
35
- @output << "<#{ModeTag[mode]}>\n"
36
- # Entering a new mode obliterates the title decoration
37
- @title_decoration = ""
38
- end
39
- super(mode)
40
- end
41
-
42
- def pop_mode(mode = nil)
43
- m = super(mode)
44
- if ModeTag[m] then
45
- output_indentation
46
- @output << "</#{ModeTag[m]}>\n"
47
- end
48
- end
49
-
50
- def flush!
51
- @logger.debug "FLUSH ==========> #{@output_type}"
52
- if current_mode == :code then
53
- # Whitespace is significant in :code mode. Always output the buffer
54
- # and do not do any additional translation.
55
- @output << CGI.escapeHTML(@buffer) << "\n"
56
- else
57
- if (@buffer.length > 0) then
58
- output_indentation
59
- @output << "<#{HtmlBlockTag[@output_type]}#{@title_decoration}>" \
60
- << inline_formatting(@buffer) \
61
- << "</#{HtmlBlockTag[@output_type]}>\n"
62
- @title_decoration = ""
63
- end
64
- end
65
- @buffer = ""
66
- end
67
-
68
- ######################################################################
69
- private
70
-
71
- def output_indentation
72
- indent = " " * (@mode_stack.length - 1)
73
- @output << indent
74
- end
75
-
76
- Tags = {
77
- "*" => { :open => "<b>", :close => "</b>" },
78
- "/" => { :open => "<i>", :close => "</i>" },
79
- "_" => { :open => "<span style=\"text-decoration:underline;\">",
80
- :close => "</span>" },
81
- "=" => { :open => "<code>", :close => "</code>" },
82
- "~" => { :open => "<code>", :close => "</code>" },
83
- "+" => { :open => "<del>", :close => "</del>" }
84
- }
85
-
86
- # Applies inline formatting rules to a string.
87
- def inline_formatting(str)
88
- str.rstrip!
89
- str = @re_help.rewrite_emphasis(str) do |marker, s|
90
- "#{Tags[marker][:open]}#{s}#{Tags[marker][:close]}"
91
- end
92
- str = @re_help.rewrite_links(str) do |link, text|
93
- text ||= link
94
- "<a href=\"#{link}\">#{text}</a>"
95
- end
96
- if (@output_type == :table_row) then
97
- str.gsub!(/^\|\s*/, "<td>")
98
- str.gsub!(/\s*\|$/, "</td>")
99
- str.gsub!(/\s*\|\s*/, "</td><td>")
100
- end
101
- str
102
- end
103
-
104
- end # class HtmlOutputBuffer
105
- end # module Orgmode
1
+ require OrgRuby.libpath(*%w[org-ruby output_buffer])
2
+ require 'cgi'
3
+
4
+ module Orgmode
5
+
6
+ class HtmlOutputBuffer < OutputBuffer
7
+
8
+ HtmlBlockTag = {
9
+ :paragraph => "p",
10
+ :ordered_list => "li",
11
+ :unordered_list => "li",
12
+ :table_row => "tr"
13
+ }
14
+
15
+ ModeTag = {
16
+ :unordered_list => "ul",
17
+ :ordered_list => "ol",
18
+ :table => "table",
19
+ :blockquote => "blockquote",
20
+ :code => "pre"
21
+ }
22
+
23
+ def initialize(output, opts = {})
24
+ super(output)
25
+ if opts[:decorate_title] then
26
+ @title_decoration = " class=\"title\""
27
+ else
28
+ @title_decoration = ""
29
+ end
30
+ end
31
+
32
+ def push_mode(mode)
33
+ if ModeTag[mode] then
34
+ output_indentation
35
+ @logger.debug "<#{ModeTag[mode]}>\n"
36
+ @output << "<#{ModeTag[mode]}>\n"
37
+ # Entering a new mode obliterates the title decoration
38
+ @title_decoration = ""
39
+ end
40
+ super(mode)
41
+ end
42
+
43
+ def pop_mode(mode = nil)
44
+ m = super(mode)
45
+ if ModeTag[m] then
46
+ output_indentation
47
+ @logger.debug "</#{ModeTag[m]}>\n"
48
+ @output << "</#{ModeTag[m]}>\n"
49
+ end
50
+ end
51
+
52
+ def flush!
53
+ escape_buffer!
54
+ if current_mode == :code then
55
+ # Whitespace is significant in :code mode. Always output the buffer
56
+ # and do not do any additional translation.
57
+ #
58
+ # FIXME 2009-12-29 bdewey: It looks like I'll always get an extraneous
59
+ # newline at the start of code blocks. Find a way to fix this.
60
+ @logger.debug "FLUSH CODE ==========> #{@buffer.inspect}"
61
+ @output << @buffer << "\n"
62
+ else
63
+ if (@buffer.length > 0) then
64
+ @logger.debug "FLUSH ==========> #{@output_type}"
65
+ output_indentation
66
+ @output << "<#{HtmlBlockTag[@output_type]}#{@title_decoration}>" \
67
+ << inline_formatting(@buffer) \
68
+ << "</#{HtmlBlockTag[@output_type]}>\n"
69
+ @title_decoration = ""
70
+ end
71
+ end
72
+ @buffer = ""
73
+ end
74
+
75
+ ######################################################################
76
+ private
77
+
78
+ # Escapes any HTML content in the output accumulation buffer @buffer.
79
+ def escape_buffer!
80
+ @buffer = CGI.escapeHTML(@buffer)
81
+ end
82
+
83
+ def output_indentation
84
+ indent = " " * (@mode_stack.length - 1)
85
+ @output << indent
86
+ end
87
+
88
+ Tags = {
89
+ "*" => { :open => "<b>", :close => "</b>" },
90
+ "/" => { :open => "<i>", :close => "</i>" },
91
+ "_" => { :open => "<span style=\"text-decoration:underline;\">",
92
+ :close => "</span>" },
93
+ "=" => { :open => "<code>", :close => "</code>" },
94
+ "~" => { :open => "<code>", :close => "</code>" },
95
+ "+" => { :open => "<del>", :close => "</del>" }
96
+ }
97
+
98
+ # Applies inline formatting rules to a string.
99
+ def inline_formatting(str)
100
+ str.rstrip!
101
+ str = @re_help.rewrite_emphasis(str) do |marker, s|
102
+ "#{Tags[marker][:open]}#{s}#{Tags[marker][:close]}"
103
+ end
104
+ str = @re_help.rewrite_links(str) do |link, text|
105
+ text ||= link
106
+ "<a href=\"#{link}\">#{text}</a>"
107
+ end
108
+ if (@output_type == :table_row) then
109
+ str.gsub!(/^\|\s*/, "<td>")
110
+ str.gsub!(/\s*\|$/, "</td>")
111
+ str.gsub!(/\s*\|\s*/, "</td><td>")
112
+ end
113
+ str
114
+ end
115
+
116
+ end # class HtmlOutputBuffer
117
+ end # module Orgmode
data/lib/org-ruby/line.rb CHANGED
@@ -1,173 +1,178 @@
1
- module Orgmode
2
-
3
- # Represents a single line of an orgmode file.
4
- class Line
5
-
6
- # This is the line itself.
7
- attr_reader :line
8
-
9
- # The indent level of this line. this is important to properly translate
10
- # nested lists from orgmode to textile.
11
- # TODO 2009-12-20 bdewey: Handle tabs
12
- attr_reader :indent
13
-
14
- def initialize(line)
15
- @line = line
16
- @indent = 0
17
- @line =~ /\s*/
18
- @indent = $&.length unless blank?
19
- end
20
-
21
- def to_s
22
- return @line
23
- end
24
-
25
- # Tests if a line is a comment.
26
- def comment?
27
- @line =~ /^\s*#/
28
- end
29
-
30
- # Tests if a line contains metadata instead of actual content.
31
- def metadata?
32
- @line =~ /^\s*(CLOCK|DEADLINE|START|CLOSED|SCHEDULED):/
33
- end
34
-
35
- def nonprinting?
36
- comment? || metadata?
37
- end
38
-
39
- def blank?
40
- @line =~ /^\s*$/
41
- end
42
-
43
- def plain_list?
44
- ordered_list? or unordered_list?
45
- end
46
-
47
- UnorderedListRegexp = /^\s*(-|\+)\s*/
48
-
49
- def unordered_list?
50
- @line =~ UnorderedListRegexp
51
- end
52
-
53
- def strip_unordered_list_tag
54
- @line.sub(UnorderedListRegexp, "")
55
- end
56
-
57
- OrderedListRegexp = /^\s*\d+(\.|\))\s*/
58
-
59
- def ordered_list?
60
- @line =~ OrderedListRegexp
61
- end
62
-
63
- def strip_ordered_list_tag
64
- @line.sub(OrderedListRegexp, "")
65
- end
66
-
67
- def plain_text?
68
- not metadata? and not blank? and not plain_list?
69
- end
70
-
71
- def table_row?
72
- # for an org-mode table, the first non-whitespace character is a
73
- # | (pipe).
74
- @line =~ /^\s*\|/
75
- end
76
-
77
- def table_separator?
78
- # an org-mode table separator has the first non-whitespace
79
- # character as a | (pipe), then consists of nothing else other
80
- # than pipes, hyphens, and pluses.
81
-
82
- @line =~ /^\s*\|[-\|\+]*\s*$/
83
- end
84
-
85
- def table?
86
- table_row? or table_separator?
87
- end
88
-
89
- BlockRegexp = /^\s*#\+(BEGIN|END)_(\w*)/
90
-
91
- def begin_block?
92
- @line =~ BlockRegexp && $1 == "BEGIN"
93
- end
94
-
95
- def end_block?
96
- @line =~ BlockRegexp && $1 == "END"
97
- end
98
-
99
- def block_type
100
- $2 if @line =~ BlockRegexp
101
- end
102
-
103
- # Determines the paragraph type of the current line.
104
- def paragraph_type
105
- return :blank if blank?
106
- return :ordered_list if ordered_list?
107
- return :unordered_list if unordered_list?
108
- return :metadata if metadata?
109
- return :comment if comment?
110
- return :table_separator if table_separator?
111
- return :table_row if table_row?
112
- return :paragraph
113
- end
114
-
115
- def self.to_textile(lines)
116
- output = ""
117
- output_buffer = TextileOutputBuffer.new(output)
118
- translate(lines, output_buffer)
119
- end
120
-
121
- def self.to_html(lines, opts = { })
122
- output = ""
123
- output_buffer = HtmlOutputBuffer.new(output, opts)
124
- translate(lines, output_buffer)
125
- end
126
-
127
- # Converts an array of lines to textile format.
128
- def self.translate(lines, output_buffer)
129
- lines.each do |line|
130
-
131
- # See if we're carrying paragraph payload, and output
132
- # it if we're about to switch to some other output type.
133
- output_buffer.prepare(line)
134
-
135
- case line.paragraph_type
136
- when :metadata, :table_separator, :blank
137
-
138
- # IGNORE
139
-
140
- when :comment
141
-
142
- output_buffer.push_mode(:blockquote) if line.begin_block? and line.block_type == "QUOTE"
143
- output_buffer.push_mode(:code) if line.begin_block? and line.block_type == "EXAMPLE"
144
- output_buffer.pop_mode(:blockquote) if line.end_block? and line.block_type == "QUOTE"
145
- output_buffer.pop_mode(:code) if line.end_block? and line.block_type == "EXAMPLE"
146
-
147
- when :table_row
148
-
149
- output_buffer << line.line.lstrip
150
-
151
- when :ordered_list
152
-
153
- output_buffer << line.strip_ordered_list_tag << " "
154
-
155
- when :unordered_list
156
-
157
- output_buffer << line.strip_unordered_list_tag << " "
158
-
159
- when :paragraph
160
-
161
- if output_buffer.preserve_whitespace? then
162
- output_buffer << line.line
163
- else
164
- output_buffer << line.line.strip << " "
165
- end
166
- end
167
- end
168
- output_buffer.flush!
169
- output_buffer.pop_mode until output_buffer.current_mode == :normal
170
- output_buffer.output
171
- end
172
- end # class Line
173
- end # module Orgmode
1
+ module Orgmode
2
+
3
+ # Represents a single line of an orgmode file.
4
+ class Line
5
+
6
+ # This is the line itself.
7
+ attr_reader :line
8
+
9
+ # The indent level of this line. this is important to properly translate
10
+ # nested lists from orgmode to textile.
11
+ # TODO 2009-12-20 bdewey: Handle tabs
12
+ attr_reader :indent
13
+
14
+ def initialize(line)
15
+ @line = line
16
+ @indent = 0
17
+ @line =~ /\s*/
18
+ @indent = $&.length unless blank?
19
+ end
20
+
21
+ def to_s
22
+ return @line
23
+ end
24
+
25
+ # Tests if a line is a comment.
26
+ def comment?
27
+ @line =~ /^\s*#/
28
+ end
29
+
30
+ # Tests if a line contains metadata instead of actual content.
31
+ def metadata?
32
+ @line =~ /^\s*(CLOCK|DEADLINE|START|CLOSED|SCHEDULED):/
33
+ end
34
+
35
+ def nonprinting?
36
+ comment? || metadata?
37
+ end
38
+
39
+ def blank?
40
+ @line =~ /^\s*$/
41
+ end
42
+
43
+ def plain_list?
44
+ ordered_list? or unordered_list?
45
+ end
46
+
47
+ UnorderedListRegexp = /^\s*(-|\+)\s*/
48
+
49
+ def unordered_list?
50
+ @line =~ UnorderedListRegexp
51
+ end
52
+
53
+ def strip_unordered_list_tag
54
+ @line.sub(UnorderedListRegexp, "")
55
+ end
56
+
57
+ OrderedListRegexp = /^\s*\d+(\.|\))\s*/
58
+
59
+ def ordered_list?
60
+ @line =~ OrderedListRegexp
61
+ end
62
+
63
+ def strip_ordered_list_tag
64
+ @line.sub(OrderedListRegexp, "")
65
+ end
66
+
67
+ def plain_text?
68
+ not metadata? and not blank? and not plain_list?
69
+ end
70
+
71
+ def table_row?
72
+ # for an org-mode table, the first non-whitespace character is a
73
+ # | (pipe).
74
+ @line =~ /^\s*\|/
75
+ end
76
+
77
+ def table_separator?
78
+ # an org-mode table separator has the first non-whitespace
79
+ # character as a | (pipe), then consists of nothing else other
80
+ # than pipes, hyphens, and pluses.
81
+
82
+ @line =~ /^\s*\|[-\|\+]*\s*$/
83
+ end
84
+
85
+ def table?
86
+ table_row? or table_separator?
87
+ end
88
+
89
+ BlockRegexp = /^\s*#\+(BEGIN|END)_(\w*)/
90
+
91
+ def begin_block?
92
+ @line =~ BlockRegexp && $1 == "BEGIN"
93
+ end
94
+
95
+ def end_block?
96
+ @line =~ BlockRegexp && $1 == "END"
97
+ end
98
+
99
+ def block_type
100
+ $2 if @line =~ BlockRegexp
101
+ end
102
+
103
+ # Determines the paragraph type of the current line.
104
+ def paragraph_type
105
+ return :blank if blank?
106
+ return :ordered_list if ordered_list?
107
+ return :unordered_list if unordered_list?
108
+ return :metadata if metadata?
109
+ return :comment if comment?
110
+ return :table_separator if table_separator?
111
+ return :table_row if table_row?
112
+ return :paragraph
113
+ end
114
+
115
+ def self.to_textile(lines)
116
+ output = ""
117
+ output_buffer = TextileOutputBuffer.new(output)
118
+ translate(lines, output_buffer)
119
+ end
120
+
121
+ def self.to_html(lines, opts = { })
122
+ output = ""
123
+ output_buffer = HtmlOutputBuffer.new(output, opts)
124
+ translate(lines, output_buffer)
125
+ end
126
+
127
+ # Converts an array of lines to textile format.
128
+ def self.translate(lines, output_buffer)
129
+ lines.each do |line|
130
+
131
+ # See if we're carrying paragraph payload, and output
132
+ # it if we're about to switch to some other output type.
133
+ output_buffer.prepare(line)
134
+
135
+ case line.paragraph_type
136
+ when :metadata, :table_separator, :blank
137
+
138
+ output_buffer << line.line if output_buffer.preserve_whitespace?
139
+
140
+ when :comment
141
+
142
+ if line.begin_block?
143
+ output_buffer.push_mode(:blockquote) if line.block_type == "QUOTE"
144
+ output_buffer.push_mode(:code) if line.block_type == "EXAMPLE"
145
+ elsif line.end_block?
146
+ output_buffer.pop_mode(:blockquote) if line.block_type == "QUOTE"
147
+ output_buffer.pop_mode(:code) if line.block_type == "EXAMPLE"
148
+ else
149
+ output_buffer << line.line if output_buffer.preserve_whitespace?
150
+ end
151
+
152
+ when :table_row
153
+
154
+ output_buffer << line.line.lstrip
155
+
156
+ when :ordered_list
157
+
158
+ output_buffer << line.strip_ordered_list_tag << " "
159
+
160
+ when :unordered_list
161
+
162
+ output_buffer << line.strip_unordered_list_tag << " "
163
+
164
+ when :paragraph
165
+
166
+ if output_buffer.preserve_whitespace? then
167
+ output_buffer << line.line
168
+ else
169
+ output_buffer << line.line.strip << " "
170
+ end
171
+ end
172
+ end
173
+ output_buffer.flush!
174
+ output_buffer.pop_mode until output_buffer.current_mode == :normal
175
+ output_buffer.output
176
+ end
177
+ end # class Line
178
+ end # module Orgmode