org-ruby 0.2.0 → 0.3.0
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/History.txt +32 -24
- data/README.txt +66 -66
- data/Rakefile +26 -22
- data/bin/org-ruby +40 -40
- data/lib/org-ruby.rb +50 -48
- data/lib/org-ruby/headline.rb +75 -75
- data/lib/org-ruby/html_output_buffer.rb +81 -80
- data/lib/org-ruby/line.rb +173 -172
- data/lib/org-ruby/output_buffer.rb +154 -154
- data/lib/org-ruby/parser.rb +76 -72
- data/lib/org-ruby/regexp_helper.rb +156 -156
- data/lib/org-ruby/textile_output_buffer.rb +67 -67
- data/spec/data/freeform.org +111 -111
- data/spec/data/hyp-planning.org +335 -335
- data/spec/data/remember.org +53 -53
- data/spec/headline_spec.rb +55 -55
- data/spec/html_examples/block_code.html +30 -29
- data/spec/html_examples/block_code.org +35 -35
- data/spec/html_examples/blockquote.html +7 -7
- data/spec/html_examples/blockquote.org +13 -13
- data/spec/html_examples/escape-pre.html +7 -0
- data/spec/html_examples/escape-pre.org +6 -0
- data/spec/html_examples/inline-formatting.html +10 -10
- data/spec/html_examples/inline-formatting.org +17 -17
- data/spec/html_examples/lists.html +19 -19
- data/spec/html_examples/lists.org +36 -36
- data/spec/html_examples/only-list.html +5 -0
- data/spec/html_examples/only-list.org +3 -0
- data/spec/html_examples/only-table.html +6 -0
- data/spec/html_examples/only-table.org +5 -0
- data/spec/html_examples/tables.html +20 -20
- data/spec/html_examples/tables.org +26 -26
- data/spec/html_examples/text.html +2 -2
- data/spec/html_examples/text.org +16 -16
- data/spec/line_spec.rb +89 -89
- data/spec/parser_spec.rb +86 -86
- data/spec/regexp_helper_spec.rb +57 -57
- data/spec/spec_helper.rb +20 -20
- data/spec/textile_examples/block_code.org +35 -35
- data/spec/textile_examples/block_code.textile +29 -29
- data/spec/textile_examples/blockquote.org +13 -13
- data/spec/textile_examples/blockquote.textile +11 -11
- data/spec/textile_examples/keywords.org +13 -13
- data/spec/textile_examples/keywords.textile +11 -11
- data/spec/textile_examples/links.org +11 -11
- data/spec/textile_examples/links.textile +10 -10
- data/spec/textile_examples/lists.org +36 -36
- data/spec/textile_examples/lists.textile +20 -20
- data/spec/textile_examples/single-space-plain-list.org +13 -13
- data/spec/textile_examples/single-space-plain-list.textile +10 -10
- data/spec/textile_examples/tables.org +26 -26
- data/spec/textile_examples/tables.textile +23 -23
- data/spec/textile_output_buffer_spec.rb +21 -21
- data/tasks/test_case.rake +49 -0
- metadata +21 -5
- data/.bnsignore +0 -18
@@ -1,80 +1,81 @@
|
|
1
|
-
require OrgRuby.libpath(*%w[org-ruby output_buffer])
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
:
|
10
|
-
:
|
11
|
-
:
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
:
|
17
|
-
:
|
18
|
-
:
|
19
|
-
:
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
#
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
<<
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
"
|
54
|
-
"
|
55
|
-
|
56
|
-
|
57
|
-
"
|
58
|
-
"
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
"#{
|
71
|
-
end
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
end
|
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 push_mode(mode)
|
24
|
+
super(mode)
|
25
|
+
@output << "<#{ModeTag[mode]}>\n" if ModeTag[mode]
|
26
|
+
end
|
27
|
+
|
28
|
+
def pop_mode(mode = nil)
|
29
|
+
m = super(mode)
|
30
|
+
@output << "</#{ModeTag[m]}>\n" if ModeTag[m]
|
31
|
+
end
|
32
|
+
|
33
|
+
def flush!
|
34
|
+
@logger.debug "FLUSH ==========> #{@output_type}"
|
35
|
+
if current_mode == :code then
|
36
|
+
# Whitespace is significant in :code mode. Always output the buffer
|
37
|
+
# and do not do any additional translation.
|
38
|
+
@output << CGI.escapeHTML(@buffer) << "\n"
|
39
|
+
else
|
40
|
+
if (@buffer.length > 0) then
|
41
|
+
@output << "<#{HtmlBlockTag[@output_type]}>" \
|
42
|
+
<< inline_formatting(@buffer) \
|
43
|
+
<< "</#{HtmlBlockTag[@output_type]}>\n"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
@buffer = ""
|
47
|
+
end
|
48
|
+
|
49
|
+
######################################################################
|
50
|
+
private
|
51
|
+
|
52
|
+
Tags = {
|
53
|
+
"*" => { :open => "<b>", :close => "</b>" },
|
54
|
+
"/" => { :open => "<i>", :close => "</i>" },
|
55
|
+
"_" => { :open => "<span style=\"text-decoration:underline;\">",
|
56
|
+
:close => "</span>" },
|
57
|
+
"=" => { :open => "<code>", :close => "</code>" },
|
58
|
+
"~" => { :open => "<code>", :close => "</code>" },
|
59
|
+
"+" => { :open => "<del>", :close => "</del>" }
|
60
|
+
}
|
61
|
+
|
62
|
+
# Applies inline formatting rules to a string.
|
63
|
+
def inline_formatting(str)
|
64
|
+
str.rstrip!
|
65
|
+
str = @re_help.rewrite_emphasis(str) do |marker, s|
|
66
|
+
"#{Tags[marker][:open]}#{s}#{Tags[marker][:close]}"
|
67
|
+
end
|
68
|
+
str = @re_help.rewrite_links(str) do |link, text|
|
69
|
+
text ||= link
|
70
|
+
"<a href=\"#{link}\">#{text}</a>"
|
71
|
+
end
|
72
|
+
if (@output_type == :table_row) then
|
73
|
+
str.gsub!(/^\|\s*/, "<td>")
|
74
|
+
str.gsub!(/\s*\|$/, "</td>")
|
75
|
+
str.gsub!(/\s*\|\s*/, "</td><td>")
|
76
|
+
end
|
77
|
+
str
|
78
|
+
end
|
79
|
+
|
80
|
+
end # class HtmlOutputBuffer
|
81
|
+
end # module Orgmode
|
data/lib/org-ruby/line.rb
CHANGED
@@ -1,172 +1,173 @@
|
|
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)
|
122
|
-
output = ""
|
123
|
-
output_buffer = HtmlOutputBuffer.new(output)
|
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.
|
170
|
-
|
171
|
-
|
172
|
-
end
|
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)
|
122
|
+
output = ""
|
123
|
+
output_buffer = HtmlOutputBuffer.new(output)
|
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
|