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,154 +1,154 @@
|
|
1
|
-
require 'logger'
|
2
|
-
|
3
|
-
module Orgmode
|
4
|
-
|
5
|
-
# The OutputBuffer is used to accumulate multiple lines of orgmode
|
6
|
-
# text, and then emit them to the output all in one go. The class
|
7
|
-
# will do the final textile substitution for inline formatting and
|
8
|
-
# add a newline character prior emitting the output.
|
9
|
-
class OutputBuffer
|
10
|
-
|
11
|
-
# This is the temporary buffer that we accumulate into.
|
12
|
-
attr_reader :buffer
|
13
|
-
|
14
|
-
# This is the overall output buffer
|
15
|
-
attr_reader :output
|
16
|
-
|
17
|
-
# This is the current type of output being accumulated.
|
18
|
-
attr_accessor :output_type
|
19
|
-
|
20
|
-
# Creates a new OutputBuffer object that is bound to an output object.
|
21
|
-
# The output will get flushed to =output=.
|
22
|
-
def initialize(output)
|
23
|
-
@output = output
|
24
|
-
@buffer = ""
|
25
|
-
@output_type = :start
|
26
|
-
@list_indent_stack = []
|
27
|
-
@paragraph_modifier = nil
|
28
|
-
@cancel_modifier = false
|
29
|
-
@mode_stack = []
|
30
|
-
push_mode(:normal)
|
31
|
-
|
32
|
-
@logger = Logger.new(STDERR)
|
33
|
-
@logger.level = Logger::WARN
|
34
|
-
|
35
|
-
@re_help = RegexpHelper.new
|
36
|
-
end
|
37
|
-
|
38
|
-
Modes = [:normal, :ordered_list, :unordered_list, :blockquote, :code, :table]
|
39
|
-
|
40
|
-
def current_mode
|
41
|
-
@mode_stack.last
|
42
|
-
end
|
43
|
-
|
44
|
-
def current_mode_list?
|
45
|
-
(current_mode == :ordered_list) or (current_mode == :unordered_list)
|
46
|
-
end
|
47
|
-
|
48
|
-
def push_mode(mode)
|
49
|
-
raise "Not a recognized mode: #{mode}" unless Modes.include?(mode)
|
50
|
-
@mode_stack.push(mode)
|
51
|
-
end
|
52
|
-
|
53
|
-
def pop_mode(mode = nil)
|
54
|
-
m = @mode_stack.pop
|
55
|
-
@logger.warn "Modes don't match. Expected to pop #{mode}, but popped #{m}" if mode && mode != m
|
56
|
-
m
|
57
|
-
end
|
58
|
-
|
59
|
-
# Prepares the output buffer to receive content from a line.
|
60
|
-
# As a side effect, this may flush the current accumulated text.
|
61
|
-
def prepare(line)
|
62
|
-
@logger.debug "Looking at #{line.paragraph_type}: #{line.to_s}"
|
63
|
-
if not should_accumulate_output?(line) then
|
64
|
-
flush!
|
65
|
-
maintain_list_indent_stack(line)
|
66
|
-
@output_type = line.paragraph_type
|
67
|
-
end
|
68
|
-
push_mode(:table) if enter_table?
|
69
|
-
pop_mode(:table) if exit_table?
|
70
|
-
end
|
71
|
-
|
72
|
-
# Tests if we are entering a table mode.
|
73
|
-
def enter_table?
|
74
|
-
((@output_type == :table_row) || (@output_type == :table_separator)) &&
|
75
|
-
(current_mode != :table)
|
76
|
-
end
|
77
|
-
|
78
|
-
# Tests if we are existing a table mode.
|
79
|
-
def exit_table?
|
80
|
-
((@output_type != :table_row) && (@output_type != :table_separator)) &&
|
81
|
-
(current_mode == :table)
|
82
|
-
end
|
83
|
-
|
84
|
-
# Accumulate the string @str@.
|
85
|
-
def << (str)
|
86
|
-
@buffer << str
|
87
|
-
end
|
88
|
-
|
89
|
-
# Gets the current list indent level.
|
90
|
-
def list_indent_level
|
91
|
-
@list_indent_stack.length
|
92
|
-
end
|
93
|
-
|
94
|
-
# Test if we're in an output mode in which whitespace is significant.
|
95
|
-
def preserve_whitespace?
|
96
|
-
return current_mode == :code
|
97
|
-
end
|
98
|
-
|
99
|
-
######################################################################
|
100
|
-
private
|
101
|
-
|
102
|
-
def maintain_list_indent_stack(line)
|
103
|
-
if (line.plain_list?) then
|
104
|
-
while (not @list_indent_stack.empty? \
|
105
|
-
and (@list_indent_stack.last > line.indent))
|
106
|
-
@list_indent_stack.pop
|
107
|
-
pop_mode
|
108
|
-
end
|
109
|
-
if (@list_indent_stack.empty? \
|
110
|
-
or @list_indent_stack.last < line.indent)
|
111
|
-
@list_indent_stack.push(line.indent)
|
112
|
-
push_mode line.paragraph_type
|
113
|
-
end
|
114
|
-
else
|
115
|
-
@list_indent_stack = []
|
116
|
-
while ((current_mode == :ordered_list) or
|
117
|
-
(current_mode == :unordered_list))
|
118
|
-
pop_mode
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
# Tests if the current line should be accumulated in the current
|
124
|
-
# output buffer. (Extraneous line breaks in the orgmode buffer
|
125
|
-
# are removed by accumulating lines in the output buffer without
|
126
|
-
# line breaks.)
|
127
|
-
def should_accumulate_output?(line)
|
128
|
-
|
129
|
-
# Special case: Preserve line breaks in block code mode.
|
130
|
-
return false if preserve_whitespace?
|
131
|
-
|
132
|
-
# Special case: Multiple blank lines get accumulated.
|
133
|
-
return true if line.paragraph_type == :blank and @output_type == :blank
|
134
|
-
|
135
|
-
# Currently only "paragraphs" get accumulated with previous output.
|
136
|
-
return false unless line.paragraph_type == :paragraph
|
137
|
-
if ((@output_type == :ordered_list) or
|
138
|
-
(@output_type == :unordered_list)) then
|
139
|
-
|
140
|
-
# If the previous output type was a list item, then we only put a paragraph in it
|
141
|
-
# if its indent level is greater than the list indent level.
|
142
|
-
|
143
|
-
return false unless line.indent > @list_indent_stack.last
|
144
|
-
end
|
145
|
-
|
146
|
-
# Only accumulate paragraphs with lists & paragraphs.
|
147
|
-
return false unless
|
148
|
-
((@output_type == :paragraph) or
|
149
|
-
(@output_type == :ordered_list) or
|
150
|
-
(@output_type == :unordered_list))
|
151
|
-
true
|
152
|
-
end
|
153
|
-
end # class OutputBuffer
|
154
|
-
end # module Orgmode
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module Orgmode
|
4
|
+
|
5
|
+
# The OutputBuffer is used to accumulate multiple lines of orgmode
|
6
|
+
# text, and then emit them to the output all in one go. The class
|
7
|
+
# will do the final textile substitution for inline formatting and
|
8
|
+
# add a newline character prior emitting the output.
|
9
|
+
class OutputBuffer
|
10
|
+
|
11
|
+
# This is the temporary buffer that we accumulate into.
|
12
|
+
attr_reader :buffer
|
13
|
+
|
14
|
+
# This is the overall output buffer
|
15
|
+
attr_reader :output
|
16
|
+
|
17
|
+
# This is the current type of output being accumulated.
|
18
|
+
attr_accessor :output_type
|
19
|
+
|
20
|
+
# Creates a new OutputBuffer object that is bound to an output object.
|
21
|
+
# The output will get flushed to =output=.
|
22
|
+
def initialize(output)
|
23
|
+
@output = output
|
24
|
+
@buffer = ""
|
25
|
+
@output_type = :start
|
26
|
+
@list_indent_stack = []
|
27
|
+
@paragraph_modifier = nil
|
28
|
+
@cancel_modifier = false
|
29
|
+
@mode_stack = []
|
30
|
+
push_mode(:normal)
|
31
|
+
|
32
|
+
@logger = Logger.new(STDERR)
|
33
|
+
@logger.level = Logger::WARN
|
34
|
+
|
35
|
+
@re_help = RegexpHelper.new
|
36
|
+
end
|
37
|
+
|
38
|
+
Modes = [:normal, :ordered_list, :unordered_list, :blockquote, :code, :table]
|
39
|
+
|
40
|
+
def current_mode
|
41
|
+
@mode_stack.last
|
42
|
+
end
|
43
|
+
|
44
|
+
def current_mode_list?
|
45
|
+
(current_mode == :ordered_list) or (current_mode == :unordered_list)
|
46
|
+
end
|
47
|
+
|
48
|
+
def push_mode(mode)
|
49
|
+
raise "Not a recognized mode: #{mode}" unless Modes.include?(mode)
|
50
|
+
@mode_stack.push(mode)
|
51
|
+
end
|
52
|
+
|
53
|
+
def pop_mode(mode = nil)
|
54
|
+
m = @mode_stack.pop
|
55
|
+
@logger.warn "Modes don't match. Expected to pop #{mode}, but popped #{m}" if mode && mode != m
|
56
|
+
m
|
57
|
+
end
|
58
|
+
|
59
|
+
# Prepares the output buffer to receive content from a line.
|
60
|
+
# As a side effect, this may flush the current accumulated text.
|
61
|
+
def prepare(line)
|
62
|
+
@logger.debug "Looking at #{line.paragraph_type}: #{line.to_s}"
|
63
|
+
if not should_accumulate_output?(line) then
|
64
|
+
flush!
|
65
|
+
maintain_list_indent_stack(line)
|
66
|
+
@output_type = line.paragraph_type
|
67
|
+
end
|
68
|
+
push_mode(:table) if enter_table?
|
69
|
+
pop_mode(:table) if exit_table?
|
70
|
+
end
|
71
|
+
|
72
|
+
# Tests if we are entering a table mode.
|
73
|
+
def enter_table?
|
74
|
+
((@output_type == :table_row) || (@output_type == :table_separator)) &&
|
75
|
+
(current_mode != :table)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Tests if we are existing a table mode.
|
79
|
+
def exit_table?
|
80
|
+
((@output_type != :table_row) && (@output_type != :table_separator)) &&
|
81
|
+
(current_mode == :table)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Accumulate the string @str@.
|
85
|
+
def << (str)
|
86
|
+
@buffer << str
|
87
|
+
end
|
88
|
+
|
89
|
+
# Gets the current list indent level.
|
90
|
+
def list_indent_level
|
91
|
+
@list_indent_stack.length
|
92
|
+
end
|
93
|
+
|
94
|
+
# Test if we're in an output mode in which whitespace is significant.
|
95
|
+
def preserve_whitespace?
|
96
|
+
return current_mode == :code
|
97
|
+
end
|
98
|
+
|
99
|
+
######################################################################
|
100
|
+
private
|
101
|
+
|
102
|
+
def maintain_list_indent_stack(line)
|
103
|
+
if (line.plain_list?) then
|
104
|
+
while (not @list_indent_stack.empty? \
|
105
|
+
and (@list_indent_stack.last > line.indent))
|
106
|
+
@list_indent_stack.pop
|
107
|
+
pop_mode
|
108
|
+
end
|
109
|
+
if (@list_indent_stack.empty? \
|
110
|
+
or @list_indent_stack.last < line.indent)
|
111
|
+
@list_indent_stack.push(line.indent)
|
112
|
+
push_mode line.paragraph_type
|
113
|
+
end
|
114
|
+
else
|
115
|
+
@list_indent_stack = []
|
116
|
+
while ((current_mode == :ordered_list) or
|
117
|
+
(current_mode == :unordered_list))
|
118
|
+
pop_mode
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# Tests if the current line should be accumulated in the current
|
124
|
+
# output buffer. (Extraneous line breaks in the orgmode buffer
|
125
|
+
# are removed by accumulating lines in the output buffer without
|
126
|
+
# line breaks.)
|
127
|
+
def should_accumulate_output?(line)
|
128
|
+
|
129
|
+
# Special case: Preserve line breaks in block code mode.
|
130
|
+
return false if preserve_whitespace?
|
131
|
+
|
132
|
+
# Special case: Multiple blank lines get accumulated.
|
133
|
+
return true if line.paragraph_type == :blank and @output_type == :blank
|
134
|
+
|
135
|
+
# Currently only "paragraphs" get accumulated with previous output.
|
136
|
+
return false unless line.paragraph_type == :paragraph
|
137
|
+
if ((@output_type == :ordered_list) or
|
138
|
+
(@output_type == :unordered_list)) then
|
139
|
+
|
140
|
+
# If the previous output type was a list item, then we only put a paragraph in it
|
141
|
+
# if its indent level is greater than the list indent level.
|
142
|
+
|
143
|
+
return false unless line.indent > @list_indent_stack.last
|
144
|
+
end
|
145
|
+
|
146
|
+
# Only accumulate paragraphs with lists & paragraphs.
|
147
|
+
return false unless
|
148
|
+
((@output_type == :paragraph) or
|
149
|
+
(@output_type == :ordered_list) or
|
150
|
+
(@output_type == :unordered_list))
|
151
|
+
true
|
152
|
+
end
|
153
|
+
end # class OutputBuffer
|
154
|
+
end # module Orgmode
|
data/lib/org-ruby/parser.rb
CHANGED
@@ -1,72 +1,76 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
@lines = lines
|
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
|
-
|
72
|
-
|
1
|
+
require 'rubypants'
|
2
|
+
|
3
|
+
module Orgmode
|
4
|
+
|
5
|
+
##
|
6
|
+
## Simple routines for loading / saving an ORG file.
|
7
|
+
##
|
8
|
+
|
9
|
+
class Parser
|
10
|
+
|
11
|
+
# All of the lines of the orgmode file
|
12
|
+
attr_reader :lines
|
13
|
+
|
14
|
+
# All of the headlines in the org file
|
15
|
+
attr_reader :headlines
|
16
|
+
|
17
|
+
# These are any lines before the first headline
|
18
|
+
attr_reader :header_lines
|
19
|
+
|
20
|
+
# I can construct a parser object either with an array of lines
|
21
|
+
# or with a single string that I will split along \n boundaries.
|
22
|
+
def initialize(lines)
|
23
|
+
if lines.is_a? Array then
|
24
|
+
@lines = lines
|
25
|
+
elsif lines.is_a? String then
|
26
|
+
@lines = lines.split("\n")
|
27
|
+
else
|
28
|
+
raise "Unsupported type for +lines+: #{lines.class}"
|
29
|
+
end
|
30
|
+
|
31
|
+
@headlines = Array.new
|
32
|
+
@current_headline = nil
|
33
|
+
@header_lines = []
|
34
|
+
@lines.each do |line|
|
35
|
+
if (Headline.headline? line) then
|
36
|
+
@current_headline = Headline.new line
|
37
|
+
@headlines << @current_headline
|
38
|
+
else
|
39
|
+
line = Line.new line
|
40
|
+
if (@current_headline) then
|
41
|
+
@current_headline.body_lines << line
|
42
|
+
else
|
43
|
+
@header_lines << line
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end # initialize
|
48
|
+
|
49
|
+
# Creates a new parser from the data in a given file
|
50
|
+
def self.load(fname)
|
51
|
+
lines = IO.readlines(fname)
|
52
|
+
return self.new(lines)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Saves the loaded orgmode file as a textile file.
|
56
|
+
def to_textile
|
57
|
+
output = ""
|
58
|
+
output << Line.to_textile(@header_lines)
|
59
|
+
@headlines.each do |headline|
|
60
|
+
output << headline.to_textile
|
61
|
+
end
|
62
|
+
output
|
63
|
+
end
|
64
|
+
|
65
|
+
# Converts the loaded org-mode file to HTML.
|
66
|
+
def to_html
|
67
|
+
output = ""
|
68
|
+
output << Line.to_html(@header_lines)
|
69
|
+
@headlines.each do |headline|
|
70
|
+
output << headline.to_html
|
71
|
+
end
|
72
|
+
rp = RubyPants.new(output)
|
73
|
+
rp.to_html
|
74
|
+
end
|
75
|
+
end # class Parser
|
76
|
+
end # module Orgmode
|