rdoc 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rdoc might be problematic. Click here for more details.
- data/History.txt +13 -0
- data/Manifest.txt +61 -0
- data/README.txt +34 -0
- data/Rakefile +10 -0
- data/bin/rdoc +22 -0
- data/bin/ri +6 -0
- data/lib/rdoc.rb +277 -0
- data/lib/rdoc/code_objects.rb +776 -0
- data/lib/rdoc/diagram.rb +338 -0
- data/lib/rdoc/dot.rb +249 -0
- data/lib/rdoc/generator.rb +1048 -0
- data/lib/rdoc/generator/chm.rb +113 -0
- data/lib/rdoc/generator/chm/chm.rb +98 -0
- data/lib/rdoc/generator/html.rb +370 -0
- data/lib/rdoc/generator/html/hefss.rb +414 -0
- data/lib/rdoc/generator/html/html.rb +704 -0
- data/lib/rdoc/generator/html/kilmer.rb +418 -0
- data/lib/rdoc/generator/html/one_page_html.rb +121 -0
- data/lib/rdoc/generator/ri.rb +229 -0
- data/lib/rdoc/generator/xml.rb +120 -0
- data/lib/rdoc/generator/xml/rdf.rb +113 -0
- data/lib/rdoc/generator/xml/xml.rb +111 -0
- data/lib/rdoc/markup.rb +473 -0
- data/lib/rdoc/markup/attribute_manager.rb +274 -0
- data/lib/rdoc/markup/formatter.rb +14 -0
- data/lib/rdoc/markup/fragments.rb +337 -0
- data/lib/rdoc/markup/inline.rb +101 -0
- data/lib/rdoc/markup/lines.rb +152 -0
- data/lib/rdoc/markup/preprocess.rb +71 -0
- data/lib/rdoc/markup/to_flow.rb +185 -0
- data/lib/rdoc/markup/to_html.rb +353 -0
- data/lib/rdoc/markup/to_html_crossref.rb +86 -0
- data/lib/rdoc/markup/to_latex.rb +328 -0
- data/lib/rdoc/markup/to_test.rb +50 -0
- data/lib/rdoc/options.rb +616 -0
- data/lib/rdoc/parsers/parse_c.rb +775 -0
- data/lib/rdoc/parsers/parse_f95.rb +1841 -0
- data/lib/rdoc/parsers/parse_rb.rb +2584 -0
- data/lib/rdoc/parsers/parse_simple.rb +40 -0
- data/lib/rdoc/parsers/parserfactory.rb +99 -0
- data/lib/rdoc/rdoc.rb +277 -0
- data/lib/rdoc/ri.rb +4 -0
- data/lib/rdoc/ri/cache.rb +188 -0
- data/lib/rdoc/ri/descriptions.rb +150 -0
- data/lib/rdoc/ri/display.rb +274 -0
- data/lib/rdoc/ri/driver.rb +452 -0
- data/lib/rdoc/ri/formatter.rb +616 -0
- data/lib/rdoc/ri/paths.rb +102 -0
- data/lib/rdoc/ri/reader.rb +106 -0
- data/lib/rdoc/ri/util.rb +81 -0
- data/lib/rdoc/ri/writer.rb +68 -0
- data/lib/rdoc/stats.rb +25 -0
- data/lib/rdoc/template.rb +64 -0
- data/lib/rdoc/tokenstream.rb +33 -0
- data/test/test_rdoc_c_parser.rb +261 -0
- data/test/test_rdoc_markup.rb +613 -0
- data/test/test_rdoc_markup_attribute_manager.rb +224 -0
- data/test/test_rdoc_ri_attribute_formatter.rb +42 -0
- data/test/test_rdoc_ri_default_display.rb +295 -0
- data/test/test_rdoc_ri_formatter.rb +318 -0
- data/test/test_rdoc_ri_overstrike_formatter.rb +69 -0
- metadata +134 -0
@@ -0,0 +1,33 @@
|
|
1
|
+
module RDoc; end
|
2
|
+
|
3
|
+
##
|
4
|
+
# A TokenStream is a list of tokens, gathered during the parse of some entity
|
5
|
+
# (say a method). Entities populate these streams by being registered with the
|
6
|
+
# lexer. Any class can collect tokens by including TokenStream. From the
|
7
|
+
# outside, you use such an object by calling the start_collecting_tokens
|
8
|
+
# method, followed by calls to add_token and pop_token.
|
9
|
+
|
10
|
+
module RDoc::TokenStream
|
11
|
+
|
12
|
+
def token_stream
|
13
|
+
@token_stream
|
14
|
+
end
|
15
|
+
|
16
|
+
def start_collecting_tokens
|
17
|
+
@token_stream = []
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_token(tk)
|
21
|
+
@token_stream << tk
|
22
|
+
end
|
23
|
+
|
24
|
+
def add_tokens(tks)
|
25
|
+
tks.each {|tk| add_token(tk)}
|
26
|
+
end
|
27
|
+
|
28
|
+
def pop_token
|
29
|
+
@token_stream.pop
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
@@ -0,0 +1,261 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
require 'tempfile'
|
3
|
+
require 'test/unit'
|
4
|
+
require 'rdoc/parsers/parse_c'
|
5
|
+
|
6
|
+
class RDoc::C_Parser
|
7
|
+
attr_accessor :classes
|
8
|
+
|
9
|
+
public :do_classes, :do_constants
|
10
|
+
end
|
11
|
+
|
12
|
+
class TestRdocC_Parser < Test::Unit::TestCase
|
13
|
+
|
14
|
+
def setup
|
15
|
+
@tempfile = Tempfile.new self.class.name
|
16
|
+
filename = @tempfile.path
|
17
|
+
|
18
|
+
@top_level = RDoc::TopLevel.new filename
|
19
|
+
@fn = filename
|
20
|
+
@options = RDoc::Options.new Hash.new
|
21
|
+
@stats = RDoc::Stats.new
|
22
|
+
|
23
|
+
@progress = StringIO.new
|
24
|
+
end
|
25
|
+
|
26
|
+
def teardown
|
27
|
+
@tempfile.unlink
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_do_classes_boot_class
|
31
|
+
content = <<-EOF
|
32
|
+
/* Document-class: Foo
|
33
|
+
* this is the Foo boot class
|
34
|
+
*/
|
35
|
+
VALUE cFoo = boot_defclass("Foo", 0);
|
36
|
+
EOF
|
37
|
+
|
38
|
+
klass = util_get_class content, 'cFoo'
|
39
|
+
assert_equal " this is the Foo boot class\n ", klass.comment
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_do_classes_class
|
43
|
+
content = <<-EOF
|
44
|
+
/* Document-class: Foo
|
45
|
+
* this is the Foo class
|
46
|
+
*/
|
47
|
+
VALUE cFoo = rb_define_class("Foo", rb_cObject);
|
48
|
+
EOF
|
49
|
+
|
50
|
+
klass = util_get_class content, 'cFoo'
|
51
|
+
assert_equal " this is the Foo class\n ", klass.comment
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_do_classes_class_under
|
55
|
+
content = <<-EOF
|
56
|
+
/* Document-class: Kernel::Foo
|
57
|
+
* this is the Foo class under Kernel
|
58
|
+
*/
|
59
|
+
VALUE cFoo = rb_define_class_under(rb_mKernel, "Foo", rb_cObject);
|
60
|
+
EOF
|
61
|
+
|
62
|
+
klass = util_get_class content, 'cFoo'
|
63
|
+
assert_equal " this is the Foo class under Kernel\n ", klass.comment
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_do_classes_module
|
67
|
+
content = <<-EOF
|
68
|
+
/* Document-module: Foo
|
69
|
+
* this is the Foo module
|
70
|
+
*/
|
71
|
+
VALUE mFoo = rb_define_module("Foo");
|
72
|
+
EOF
|
73
|
+
|
74
|
+
klass = util_get_class content, 'mFoo'
|
75
|
+
assert_equal " this is the Foo module\n ", klass.comment
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_do_classes_module_under
|
79
|
+
content = <<-EOF
|
80
|
+
/* Document-module: Kernel::Foo
|
81
|
+
* this is the Foo module under Kernel
|
82
|
+
*/
|
83
|
+
VALUE mFoo = rb_define_module_under(rb_mKernel, "Foo");
|
84
|
+
EOF
|
85
|
+
|
86
|
+
klass = util_get_class content, 'mFoo'
|
87
|
+
assert_equal " this is the Foo module under Kernel\n ", klass.comment
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_do_constants
|
91
|
+
content = <<-EOF
|
92
|
+
#include <ruby.h>
|
93
|
+
|
94
|
+
void Init_foo(){
|
95
|
+
VALUE cFoo = rb_define_class("Foo", rb_cObject);
|
96
|
+
|
97
|
+
/* 300: The highest possible score in bowling */
|
98
|
+
rb_define_const(cFoo, "PERFECT", INT2FIX(300));
|
99
|
+
|
100
|
+
/* Huzzah!: What you cheer when you roll a perfect game */
|
101
|
+
rb_define_const(cFoo, "CHEER", rb_str_new2("Huzzah!"));
|
102
|
+
|
103
|
+
/* TEST\:TEST: Checking to see if escaped semicolon works */
|
104
|
+
rb_define_const(cFoo, "TEST", rb_str_new2("TEST:TEST"));
|
105
|
+
|
106
|
+
/* \\: The file separator on MS Windows */
|
107
|
+
rb_define_const(cFoo, "MSEPARATOR", rb_str_new2("\\"));
|
108
|
+
|
109
|
+
/* /: The file separator on Unix */
|
110
|
+
rb_define_const(cFoo, "SEPARATOR", rb_str_new2("/"));
|
111
|
+
|
112
|
+
/* C:\\Program Files\\Stuff: A directory on MS Windows */
|
113
|
+
rb_define_const(cFoo, "STUFF", rb_str_new2("C:\\Program Files\\Stuff"));
|
114
|
+
|
115
|
+
/* Default definition */
|
116
|
+
rb_define_const(cFoo, "NOSEMI", INT2FIX(99));
|
117
|
+
|
118
|
+
rb_define_const(cFoo, "NOCOMMENT", rb_str_new2("No comment"));
|
119
|
+
|
120
|
+
/*
|
121
|
+
* Multiline comment goes here because this comment spans multiple lines.
|
122
|
+
* Multiline comment goes here because this comment spans multiple lines.
|
123
|
+
*/
|
124
|
+
rb_define_const(cFoo, "MULTILINE", INT2FIX(1));
|
125
|
+
|
126
|
+
/*
|
127
|
+
* 1: Multiline comment goes here because this comment spans multiple lines.
|
128
|
+
* Multiline comment goes here because this comment spans multiple lines.
|
129
|
+
*/
|
130
|
+
rb_define_const(cFoo, "MULTILINE_VALUE", INT2FIX(1));
|
131
|
+
|
132
|
+
/* Multiline comment goes here because this comment spans multiple lines.
|
133
|
+
* Multiline comment goes here because this comment spans multiple lines.
|
134
|
+
*/
|
135
|
+
rb_define_const(cFoo, "MULTILINE_NOT_EMPTY", INT2FIX(1));
|
136
|
+
|
137
|
+
}
|
138
|
+
EOF
|
139
|
+
|
140
|
+
parser = util_parser content
|
141
|
+
|
142
|
+
parser.do_classes
|
143
|
+
parser.do_constants
|
144
|
+
|
145
|
+
klass = parser.classes['cFoo']
|
146
|
+
assert klass
|
147
|
+
|
148
|
+
constants = klass.constants
|
149
|
+
assert !klass.constants.empty?
|
150
|
+
|
151
|
+
constants = constants.map { |c| [c.name, c.value, c.comment] }
|
152
|
+
|
153
|
+
assert_equal ['PERFECT', '300',
|
154
|
+
"\n The highest possible score in bowling \n "],
|
155
|
+
constants.shift
|
156
|
+
assert_equal ['CHEER', 'Huzzah!',
|
157
|
+
"\n What you cheer when you roll a perfect game \n "],
|
158
|
+
constants.shift
|
159
|
+
assert_equal ['TEST', 'TEST:TEST',
|
160
|
+
"\n Checking to see if escaped semicolon works \n "],
|
161
|
+
constants.shift
|
162
|
+
assert_equal ['MSEPARATOR', '\\',
|
163
|
+
"\n The file separator on MS Windows \n "],
|
164
|
+
constants.shift
|
165
|
+
assert_equal ['SEPARATOR', '/',
|
166
|
+
"\n The file separator on Unix \n "],
|
167
|
+
constants.shift
|
168
|
+
assert_equal ['STUFF', 'C:\\Program Files\\Stuff',
|
169
|
+
"\n A directory on MS Windows \n "],
|
170
|
+
constants.shift
|
171
|
+
assert_equal ['NOSEMI', 'INT2FIX(99)',
|
172
|
+
"\n Default definition \n "],
|
173
|
+
constants.shift
|
174
|
+
assert_equal ['NOCOMMENT', 'rb_str_new2("No comment")', nil],
|
175
|
+
constants.shift
|
176
|
+
|
177
|
+
comment = <<-EOF.chomp
|
178
|
+
|
179
|
+
|
180
|
+
Multiline comment goes here because this comment spans multiple lines.
|
181
|
+
Multiline comment goes here because this comment spans multiple lines.
|
182
|
+
|
183
|
+
|
184
|
+
EOF
|
185
|
+
assert_equal ['MULTILINE', 'INT2FIX(1)', comment], constants.shift
|
186
|
+
assert_equal ['MULTILINE_VALUE', '1', comment], constants.shift
|
187
|
+
|
188
|
+
comment = <<-EOF.chomp
|
189
|
+
|
190
|
+
Multiline comment goes here because this comment spans multiple lines.
|
191
|
+
Multiline comment goes here because this comment spans multiple lines.
|
192
|
+
|
193
|
+
|
194
|
+
EOF
|
195
|
+
assert_equal ['MULTILINE_NOT_EMPTY', 'INT2FIX(1)', comment], constants.shift
|
196
|
+
|
197
|
+
assert constants.empty?, constants.inspect
|
198
|
+
end
|
199
|
+
|
200
|
+
def test_find_class_comment_init
|
201
|
+
content = <<-EOF
|
202
|
+
/*
|
203
|
+
* a comment for class Foo
|
204
|
+
*/
|
205
|
+
void
|
206
|
+
Init_Foo(void) {
|
207
|
+
VALUE foo = rb_define_class("Foo", rb_cObject);
|
208
|
+
}
|
209
|
+
EOF
|
210
|
+
|
211
|
+
klass = util_get_class content, 'foo'
|
212
|
+
|
213
|
+
assert_equal " \n a comment for class Foo\n \n", klass.comment
|
214
|
+
end
|
215
|
+
|
216
|
+
def test_find_class_comment_define_class
|
217
|
+
content = <<-EOF
|
218
|
+
/*
|
219
|
+
* a comment for class Foo
|
220
|
+
*/
|
221
|
+
VALUE foo = rb_define_class("Foo", rb_cObject);
|
222
|
+
EOF
|
223
|
+
|
224
|
+
klass = util_get_class content, 'foo'
|
225
|
+
|
226
|
+
assert_equal " \n a comment for class Foo\n ", klass.comment
|
227
|
+
end
|
228
|
+
|
229
|
+
def test_find_class_comment_define_class_Init_Foo
|
230
|
+
content = <<-EOF
|
231
|
+
/*
|
232
|
+
* a comment for class Foo on Init
|
233
|
+
*/
|
234
|
+
void
|
235
|
+
Init_Foo(void) {
|
236
|
+
/*
|
237
|
+
* a comment for class Foo on rb_define_class
|
238
|
+
*/
|
239
|
+
VALUE foo = rb_define_class("Foo", rb_cObject);
|
240
|
+
}
|
241
|
+
EOF
|
242
|
+
|
243
|
+
klass = util_get_class content, 'foo'
|
244
|
+
|
245
|
+
assert_equal " \n a comment for class Foo on Init\n \n", klass.comment
|
246
|
+
end
|
247
|
+
|
248
|
+
def util_get_class(content, name)
|
249
|
+
parser = util_parser content
|
250
|
+
parser.do_classes
|
251
|
+
parser.classes[name]
|
252
|
+
end
|
253
|
+
|
254
|
+
def util_parser(content)
|
255
|
+
parser = RDoc::C_Parser.new @top_level, @fn, content, @options, @stats
|
256
|
+
parser.progress = @progress
|
257
|
+
parser
|
258
|
+
end
|
259
|
+
|
260
|
+
end
|
261
|
+
|
@@ -0,0 +1,613 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'rdoc/markup'
|
3
|
+
require 'rdoc/markup/to_test'
|
4
|
+
|
5
|
+
class TestRDocMarkup < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def basic_conv(str)
|
8
|
+
sm = RDoc::Markup.new
|
9
|
+
mock = RDoc::Markup::ToTest.new
|
10
|
+
sm.convert(str, mock)
|
11
|
+
sm.content
|
12
|
+
end
|
13
|
+
|
14
|
+
def line_groups(str, expected)
|
15
|
+
m = RDoc::Markup.new
|
16
|
+
mock = RDoc::Markup::ToTest.new
|
17
|
+
|
18
|
+
block = m.convert(str, mock)
|
19
|
+
|
20
|
+
if block != expected
|
21
|
+
rows = (0...([expected.size, block.size].max)).collect{|i|
|
22
|
+
[expected[i]||"nil", block[i]||"nil"]
|
23
|
+
}
|
24
|
+
printf "\n\n%35s %35s\n", "Expected", "Got"
|
25
|
+
rows.each {|e,g| printf "%35s %35s\n", e.dump, g.dump }
|
26
|
+
end
|
27
|
+
|
28
|
+
assert_equal(expected, block)
|
29
|
+
end
|
30
|
+
|
31
|
+
def line_types(str, expected)
|
32
|
+
m = RDoc::Markup.new
|
33
|
+
mock = RDoc::Markup::ToTest.new
|
34
|
+
m.convert(str, mock)
|
35
|
+
assert_equal(expected, m.get_line_types.map{|type| type.to_s[0,1]}.join(''))
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_groups
|
39
|
+
str = "now is the time"
|
40
|
+
line_groups(str, ["L0: Paragraph\nnow is the time"] )
|
41
|
+
|
42
|
+
str = "now is the time\nfor all good men"
|
43
|
+
line_groups(str, ["L0: Paragraph\nnow is the time for all good men"] )
|
44
|
+
|
45
|
+
str = %{\
|
46
|
+
now is the time
|
47
|
+
code _line_ here
|
48
|
+
for all good men}
|
49
|
+
|
50
|
+
line_groups(str,
|
51
|
+
[ "L0: Paragraph\nnow is the time",
|
52
|
+
"L0: Verbatim\n code _line_ here\n",
|
53
|
+
"L0: Paragraph\nfor all good men"
|
54
|
+
] )
|
55
|
+
|
56
|
+
str = "now is the time\n code\n more code\nfor all good men"
|
57
|
+
line_groups(str,
|
58
|
+
[ "L0: Paragraph\nnow is the time",
|
59
|
+
"L0: Verbatim\n code\n more code\n",
|
60
|
+
"L0: Paragraph\nfor all good men"
|
61
|
+
] )
|
62
|
+
|
63
|
+
str = %{\
|
64
|
+
now is
|
65
|
+
* l1
|
66
|
+
* l2
|
67
|
+
the time}
|
68
|
+
line_groups(str,
|
69
|
+
[ "L0: Paragraph\nnow is",
|
70
|
+
"L1: ListStart\n",
|
71
|
+
"L1: BULLET ListItem\nl1",
|
72
|
+
"L1: BULLET ListItem\nl2",
|
73
|
+
"L1: ListEnd\n",
|
74
|
+
"L0: Paragraph\nthe time"
|
75
|
+
])
|
76
|
+
|
77
|
+
str = %{\
|
78
|
+
now is
|
79
|
+
* l1
|
80
|
+
l1+
|
81
|
+
* l2
|
82
|
+
the time}
|
83
|
+
line_groups(str,
|
84
|
+
[ "L0: Paragraph\nnow is",
|
85
|
+
"L1: ListStart\n",
|
86
|
+
"L1: BULLET ListItem\nl1 l1+",
|
87
|
+
"L1: BULLET ListItem\nl2",
|
88
|
+
"L1: ListEnd\n",
|
89
|
+
"L0: Paragraph\nthe time"
|
90
|
+
])
|
91
|
+
|
92
|
+
str = %{\
|
93
|
+
now is
|
94
|
+
* l1
|
95
|
+
* l1.1
|
96
|
+
* l2
|
97
|
+
the time}
|
98
|
+
line_groups(str,
|
99
|
+
[ "L0: Paragraph\nnow is",
|
100
|
+
"L1: ListStart\n",
|
101
|
+
"L1: BULLET ListItem\nl1",
|
102
|
+
"L2: ListStart\n",
|
103
|
+
"L2: BULLET ListItem\nl1.1",
|
104
|
+
"L2: ListEnd\n",
|
105
|
+
"L1: BULLET ListItem\nl2",
|
106
|
+
"L1: ListEnd\n",
|
107
|
+
"L0: Paragraph\nthe time"
|
108
|
+
])
|
109
|
+
|
110
|
+
|
111
|
+
str = %{\
|
112
|
+
now is
|
113
|
+
* l1
|
114
|
+
* l1.1
|
115
|
+
text
|
116
|
+
code
|
117
|
+
code
|
118
|
+
|
119
|
+
text
|
120
|
+
* l2
|
121
|
+
the time}
|
122
|
+
line_groups(str,
|
123
|
+
[ "L0: Paragraph\nnow is",
|
124
|
+
"L1: ListStart\n",
|
125
|
+
"L1: BULLET ListItem\nl1",
|
126
|
+
"L2: ListStart\n",
|
127
|
+
"L2: BULLET ListItem\nl1.1 text",
|
128
|
+
"L2: Verbatim\n code\n code\n",
|
129
|
+
"L2: Paragraph\ntext",
|
130
|
+
"L2: ListEnd\n",
|
131
|
+
"L1: BULLET ListItem\nl2",
|
132
|
+
"L1: ListEnd\n",
|
133
|
+
"L0: Paragraph\nthe time"
|
134
|
+
])
|
135
|
+
|
136
|
+
|
137
|
+
str = %{\
|
138
|
+
now is
|
139
|
+
1. l1
|
140
|
+
* l1.1
|
141
|
+
2. l2
|
142
|
+
the time}
|
143
|
+
line_groups(str,
|
144
|
+
[ "L0: Paragraph\nnow is",
|
145
|
+
"L1: ListStart\n",
|
146
|
+
"L1: NUMBER ListItem\nl1",
|
147
|
+
"L2: ListStart\n",
|
148
|
+
"L2: BULLET ListItem\nl1.1",
|
149
|
+
"L2: ListEnd\n",
|
150
|
+
"L1: NUMBER ListItem\nl2",
|
151
|
+
"L1: ListEnd\n",
|
152
|
+
"L0: Paragraph\nthe time"
|
153
|
+
])
|
154
|
+
|
155
|
+
str = %{\
|
156
|
+
now is
|
157
|
+
[cat] l1
|
158
|
+
* l1.1
|
159
|
+
[dog] l2
|
160
|
+
the time}
|
161
|
+
line_groups(str,
|
162
|
+
[ "L0: Paragraph\nnow is",
|
163
|
+
"L1: ListStart\n",
|
164
|
+
"L1: LABELED ListItem\ncat: l1",
|
165
|
+
"L2: ListStart\n",
|
166
|
+
"L2: BULLET ListItem\nl1.1",
|
167
|
+
"L2: ListEnd\n",
|
168
|
+
"L1: LABELED ListItem\ndog: l2",
|
169
|
+
"L1: ListEnd\n",
|
170
|
+
"L0: Paragraph\nthe time"
|
171
|
+
])
|
172
|
+
|
173
|
+
str = %{\
|
174
|
+
now is
|
175
|
+
[cat] l1
|
176
|
+
continuation
|
177
|
+
[dog] l2
|
178
|
+
the time}
|
179
|
+
line_groups(str,
|
180
|
+
[ "L0: Paragraph\nnow is",
|
181
|
+
"L1: ListStart\n",
|
182
|
+
"L1: LABELED ListItem\ncat: l1 continuation",
|
183
|
+
"L1: LABELED ListItem\ndog: l2",
|
184
|
+
"L1: ListEnd\n",
|
185
|
+
"L0: Paragraph\nthe time"
|
186
|
+
])
|
187
|
+
end
|
188
|
+
|
189
|
+
def test_headings
|
190
|
+
str = "= heading one"
|
191
|
+
line_groups(str,
|
192
|
+
[ "L0: Heading\nheading one"
|
193
|
+
])
|
194
|
+
|
195
|
+
str = "=== heading three"
|
196
|
+
line_groups(str,
|
197
|
+
[ "L0: Heading\nheading three"
|
198
|
+
])
|
199
|
+
|
200
|
+
str = "text\n === heading three"
|
201
|
+
line_groups(str,
|
202
|
+
[ "L0: Paragraph\ntext",
|
203
|
+
"L0: Verbatim\n === heading three\n"
|
204
|
+
])
|
205
|
+
|
206
|
+
str = "text\n code\n === heading three"
|
207
|
+
line_groups(str,
|
208
|
+
[ "L0: Paragraph\ntext",
|
209
|
+
"L0: Verbatim\n code\n === heading three\n"
|
210
|
+
])
|
211
|
+
|
212
|
+
str = "text\n code\n=== heading three"
|
213
|
+
line_groups(str,
|
214
|
+
[ "L0: Paragraph\ntext",
|
215
|
+
"L0: Verbatim\n code\n",
|
216
|
+
"L0: Heading\nheading three"
|
217
|
+
])
|
218
|
+
|
219
|
+
end
|
220
|
+
|
221
|
+
def test_list_alpha
|
222
|
+
str = "a. alpha\nb. baker\nB. ALPHA\nA. BAKER"
|
223
|
+
|
224
|
+
line_groups(str,
|
225
|
+
[ "L1: ListStart\n",
|
226
|
+
"L1: LOWERALPHA ListItem\nalpha",
|
227
|
+
"L1: LOWERALPHA ListItem\nbaker",
|
228
|
+
"L1: ListEnd\n",
|
229
|
+
"L1: ListStart\n",
|
230
|
+
"L1: UPPERALPHA ListItem\nALPHA",
|
231
|
+
"L1: UPPERALPHA ListItem\nBAKER",
|
232
|
+
"L1: ListEnd\n" ])
|
233
|
+
end
|
234
|
+
|
235
|
+
def test_list_bullet_dash
|
236
|
+
str = "- one\n- two\n"
|
237
|
+
|
238
|
+
line_groups(str,
|
239
|
+
[ "L1: ListStart\n",
|
240
|
+
"L1: BULLET ListItem\none",
|
241
|
+
"L1: BULLET ListItem\ntwo",
|
242
|
+
"L1: ListEnd\n" ])
|
243
|
+
end
|
244
|
+
|
245
|
+
def test_list_bullet_star
|
246
|
+
str = "* one\n* two\n"
|
247
|
+
|
248
|
+
line_groups(str,
|
249
|
+
[ "L1: ListStart\n",
|
250
|
+
"L1: BULLET ListItem\none",
|
251
|
+
"L1: BULLET ListItem\ntwo",
|
252
|
+
"L1: ListEnd\n" ])
|
253
|
+
end
|
254
|
+
|
255
|
+
def test_list_labeled_bracket
|
256
|
+
str = "[one] item one\n[two] item two"
|
257
|
+
|
258
|
+
line_groups(str,
|
259
|
+
[ "L1: ListStart\n",
|
260
|
+
"L1: LABELED ListItem\none: item one",
|
261
|
+
"L1: LABELED ListItem\ntwo: item two",
|
262
|
+
"L1: ListEnd\n" ])
|
263
|
+
end
|
264
|
+
|
265
|
+
def test_list_labeled_bracket_continued
|
266
|
+
str = "[one]\n item one\n[two]\n item two"
|
267
|
+
|
268
|
+
line_groups(str,
|
269
|
+
[ "L1: ListStart\n",
|
270
|
+
"L1: LABELED ListItem\none: item one",
|
271
|
+
"L1: LABELED ListItem\ntwo: item two",
|
272
|
+
"L1: ListEnd\n" ])
|
273
|
+
end
|
274
|
+
|
275
|
+
def test_list_labeled_colon
|
276
|
+
str = "one:: item one\ntwo:: item two"
|
277
|
+
|
278
|
+
line_groups(str,
|
279
|
+
[ "L1: ListStart\n",
|
280
|
+
"L1: NOTE ListItem\none:: item one",
|
281
|
+
"L1: NOTE ListItem\ntwo:: item two",
|
282
|
+
"L1: ListEnd\n" ])
|
283
|
+
end
|
284
|
+
|
285
|
+
def test_list_labeled_colon_continued
|
286
|
+
str = "one::\n item one\ntwo::\n item two"
|
287
|
+
|
288
|
+
line_groups(str,
|
289
|
+
[ "L1: ListStart\n",
|
290
|
+
"L1: NOTE ListItem\none:: item one",
|
291
|
+
"L1: NOTE ListItem\ntwo:: item two",
|
292
|
+
"L1: ListEnd\n" ])
|
293
|
+
end
|
294
|
+
|
295
|
+
def test_list_nested_bullet_bullet
|
296
|
+
str = "* one\n* two\n * cat\n * dog"
|
297
|
+
|
298
|
+
line_groups(str,
|
299
|
+
[ "L1: ListStart\n",
|
300
|
+
"L1: BULLET ListItem\none",
|
301
|
+
"L1: BULLET ListItem\ntwo",
|
302
|
+
"L2: ListStart\n",
|
303
|
+
"L2: BULLET ListItem\ncat",
|
304
|
+
"L2: BULLET ListItem\ndog",
|
305
|
+
"L2: ListEnd\n",
|
306
|
+
"L1: ListEnd\n" ])
|
307
|
+
end
|
308
|
+
|
309
|
+
def test_list_nested_labeled_bullet
|
310
|
+
str = "[one]\n * cat\n * dog"
|
311
|
+
|
312
|
+
line_groups(str,
|
313
|
+
[ "L1: ListStart\n",
|
314
|
+
"L1: LABELED ListItem\none: ",
|
315
|
+
"L2: ListStart\n",
|
316
|
+
"L2: BULLET ListItem\ncat",
|
317
|
+
"L2: BULLET ListItem\ndog",
|
318
|
+
"L2: ListEnd\n",
|
319
|
+
"L1: ListEnd\n" ])
|
320
|
+
end
|
321
|
+
|
322
|
+
def test_list_nested_labeled_bullet_bullet
|
323
|
+
str = "[one]\n * cat\n * dog"
|
324
|
+
|
325
|
+
line_groups(str,
|
326
|
+
[ "L1: ListStart\n",
|
327
|
+
"L1: LABELED ListItem\none: ",
|
328
|
+
"L2: ListStart\n",
|
329
|
+
"L2: BULLET ListItem\ncat",
|
330
|
+
"L3: ListStart\n",
|
331
|
+
"L3: BULLET ListItem\ndog",
|
332
|
+
"L3: ListEnd\n",
|
333
|
+
"L2: ListEnd\n",
|
334
|
+
"L1: ListEnd\n" ])
|
335
|
+
end
|
336
|
+
|
337
|
+
def test_list_nested_number_number
|
338
|
+
str = "1. one\n1. two\n 1. cat\n 1. dog"
|
339
|
+
|
340
|
+
line_groups(str,
|
341
|
+
[ "L1: ListStart\n",
|
342
|
+
"L1: NUMBER ListItem\none",
|
343
|
+
"L1: NUMBER ListItem\ntwo",
|
344
|
+
"L2: ListStart\n",
|
345
|
+
"L2: NUMBER ListItem\ncat",
|
346
|
+
"L2: NUMBER ListItem\ndog",
|
347
|
+
"L2: ListEnd\n",
|
348
|
+
"L1: ListEnd\n" ])
|
349
|
+
end
|
350
|
+
|
351
|
+
def test_list_number
|
352
|
+
str = "1. one\n2. two\n1. three"
|
353
|
+
|
354
|
+
line_groups(str,
|
355
|
+
[ "L1: ListStart\n",
|
356
|
+
"L1: NUMBER ListItem\none",
|
357
|
+
"L1: NUMBER ListItem\ntwo",
|
358
|
+
"L1: NUMBER ListItem\nthree",
|
359
|
+
"L1: ListEnd\n" ])
|
360
|
+
end
|
361
|
+
|
362
|
+
def test_list_split
|
363
|
+
str = %{\
|
364
|
+
now is
|
365
|
+
* l1
|
366
|
+
1. n1
|
367
|
+
2. n2
|
368
|
+
* l2
|
369
|
+
the time}
|
370
|
+
line_groups(str,
|
371
|
+
[ "L0: Paragraph\nnow is",
|
372
|
+
"L1: ListStart\n",
|
373
|
+
"L1: BULLET ListItem\nl1",
|
374
|
+
"L1: ListEnd\n",
|
375
|
+
"L1: ListStart\n",
|
376
|
+
"L1: NUMBER ListItem\nn1",
|
377
|
+
"L1: NUMBER ListItem\nn2",
|
378
|
+
"L1: ListEnd\n",
|
379
|
+
"L1: ListStart\n",
|
380
|
+
"L1: BULLET ListItem\nl2",
|
381
|
+
"L1: ListEnd\n",
|
382
|
+
"L0: Paragraph\nthe time"
|
383
|
+
])
|
384
|
+
|
385
|
+
end
|
386
|
+
|
387
|
+
def test_paragraph
|
388
|
+
str = "paragraph\n\n*bold* paragraph\n"
|
389
|
+
|
390
|
+
line_groups str, [
|
391
|
+
"L0: Paragraph\nparagraph",
|
392
|
+
"L0: BlankLine\n",
|
393
|
+
"L0: Paragraph\n*bold* paragraph"
|
394
|
+
]
|
395
|
+
end
|
396
|
+
|
397
|
+
def test_tabs
|
398
|
+
str = "hello\n dave"
|
399
|
+
assert_equal(str, basic_conv(str))
|
400
|
+
str = "hello\n\tdave"
|
401
|
+
assert_equal("hello\n dave", basic_conv(str))
|
402
|
+
str = "hello\n \tdave"
|
403
|
+
assert_equal("hello\n dave", basic_conv(str))
|
404
|
+
str = "hello\n \tdave"
|
405
|
+
assert_equal("hello\n dave", basic_conv(str))
|
406
|
+
str = "hello\n \tdave"
|
407
|
+
assert_equal("hello\n dave", basic_conv(str))
|
408
|
+
str = "hello\n \tdave"
|
409
|
+
assert_equal("hello\n dave", basic_conv(str))
|
410
|
+
str = "hello\n \tdave"
|
411
|
+
assert_equal("hello\n dave", basic_conv(str))
|
412
|
+
str = "hello\n \tdave"
|
413
|
+
assert_equal("hello\n dave", basic_conv(str))
|
414
|
+
str = "hello\n \tdave"
|
415
|
+
assert_equal("hello\n dave", basic_conv(str))
|
416
|
+
str = "hello\n \tdave"
|
417
|
+
assert_equal("hello\n dave", basic_conv(str))
|
418
|
+
str = ".\t\t."
|
419
|
+
assert_equal(". .", basic_conv(str))
|
420
|
+
end
|
421
|
+
|
422
|
+
def test_types
|
423
|
+
str = "now is the time"
|
424
|
+
line_types(str, 'P')
|
425
|
+
|
426
|
+
str = "now is the time\nfor all good men"
|
427
|
+
line_types(str, 'PP')
|
428
|
+
|
429
|
+
str = "now is the time\n code\nfor all good men"
|
430
|
+
line_types(str, 'PVP')
|
431
|
+
|
432
|
+
str = "now is the time\n code\n more code\nfor all good men"
|
433
|
+
line_types(str, 'PVVP')
|
434
|
+
|
435
|
+
str = "now is\n---\nthe time"
|
436
|
+
line_types(str, 'PRP')
|
437
|
+
|
438
|
+
str = %{\
|
439
|
+
now is
|
440
|
+
* l1
|
441
|
+
* l2
|
442
|
+
the time}
|
443
|
+
line_types(str, 'PLLP')
|
444
|
+
|
445
|
+
str = %{\
|
446
|
+
now is
|
447
|
+
* l1
|
448
|
+
l1+
|
449
|
+
* l2
|
450
|
+
the time}
|
451
|
+
line_types(str, 'PLPLP')
|
452
|
+
|
453
|
+
str = %{\
|
454
|
+
now is
|
455
|
+
* l1
|
456
|
+
* l1.1
|
457
|
+
* l2
|
458
|
+
the time}
|
459
|
+
line_types(str, 'PLLLP')
|
460
|
+
|
461
|
+
str = %{\
|
462
|
+
now is
|
463
|
+
* l1
|
464
|
+
* l1.1
|
465
|
+
text
|
466
|
+
code
|
467
|
+
code
|
468
|
+
|
469
|
+
text
|
470
|
+
* l2
|
471
|
+
the time}
|
472
|
+
line_types(str, 'PLLPVVBPLP')
|
473
|
+
|
474
|
+
str = %{\
|
475
|
+
now is
|
476
|
+
1. l1
|
477
|
+
* l1.1
|
478
|
+
2. l2
|
479
|
+
the time}
|
480
|
+
line_types(str, 'PLLLP')
|
481
|
+
|
482
|
+
str = %{\
|
483
|
+
now is
|
484
|
+
[cat] l1
|
485
|
+
* l1.1
|
486
|
+
[dog] l2
|
487
|
+
the time}
|
488
|
+
line_types(str, 'PLLLP')
|
489
|
+
|
490
|
+
str = %{\
|
491
|
+
now is
|
492
|
+
[cat] l1
|
493
|
+
continuation
|
494
|
+
[dog] l2
|
495
|
+
the time}
|
496
|
+
line_types(str, 'PLPLP')
|
497
|
+
end
|
498
|
+
|
499
|
+
def test_verbatim
|
500
|
+
str = "paragraph\n *bold* verbatim\n"
|
501
|
+
|
502
|
+
line_groups str, [
|
503
|
+
"L0: Paragraph\nparagraph",
|
504
|
+
"L0: Verbatim\n *bold* verbatim\n"
|
505
|
+
]
|
506
|
+
end
|
507
|
+
|
508
|
+
def test_verbatim_merge
|
509
|
+
str = %{\
|
510
|
+
now is
|
511
|
+
code
|
512
|
+
the time}
|
513
|
+
|
514
|
+
line_groups(str,
|
515
|
+
[ "L0: Paragraph\nnow is",
|
516
|
+
"L0: Verbatim\n code\n",
|
517
|
+
"L0: Paragraph\nthe time"
|
518
|
+
])
|
519
|
+
|
520
|
+
|
521
|
+
str = %{\
|
522
|
+
now is
|
523
|
+
code
|
524
|
+
code1
|
525
|
+
the time}
|
526
|
+
|
527
|
+
line_groups(str,
|
528
|
+
[ "L0: Paragraph\nnow is",
|
529
|
+
"L0: Verbatim\n code\n code1\n",
|
530
|
+
"L0: Paragraph\nthe time"
|
531
|
+
])
|
532
|
+
|
533
|
+
|
534
|
+
str = %{\
|
535
|
+
now is
|
536
|
+
code
|
537
|
+
|
538
|
+
code1
|
539
|
+
the time}
|
540
|
+
|
541
|
+
line_groups(str,
|
542
|
+
[ "L0: Paragraph\nnow is",
|
543
|
+
"L0: Verbatim\n code\n\n code1\n",
|
544
|
+
"L0: Paragraph\nthe time"
|
545
|
+
])
|
546
|
+
|
547
|
+
|
548
|
+
str = %{\
|
549
|
+
now is
|
550
|
+
code
|
551
|
+
|
552
|
+
code1
|
553
|
+
|
554
|
+
the time}
|
555
|
+
|
556
|
+
line_groups(str,
|
557
|
+
[ "L0: Paragraph\nnow is",
|
558
|
+
"L0: Verbatim\n code\n\n code1\n",
|
559
|
+
"L0: Paragraph\nthe time"
|
560
|
+
])
|
561
|
+
|
562
|
+
|
563
|
+
str = %{\
|
564
|
+
now is
|
565
|
+
code
|
566
|
+
|
567
|
+
code1
|
568
|
+
|
569
|
+
code2
|
570
|
+
the time}
|
571
|
+
|
572
|
+
line_groups(str,
|
573
|
+
[ "L0: Paragraph\nnow is",
|
574
|
+
"L0: Verbatim\n code\n\n code1\n\n code2\n",
|
575
|
+
"L0: Paragraph\nthe time"
|
576
|
+
])
|
577
|
+
|
578
|
+
|
579
|
+
# Folds multiple blank lines
|
580
|
+
str = %{\
|
581
|
+
now is
|
582
|
+
code
|
583
|
+
|
584
|
+
|
585
|
+
code1
|
586
|
+
|
587
|
+
the time}
|
588
|
+
|
589
|
+
line_groups(str,
|
590
|
+
[ "L0: Paragraph\nnow is",
|
591
|
+
"L0: Verbatim\n code\n\n code1\n",
|
592
|
+
"L0: Paragraph\nthe time"
|
593
|
+
])
|
594
|
+
|
595
|
+
|
596
|
+
end
|
597
|
+
|
598
|
+
def test_whitespace
|
599
|
+
assert_equal("hello", basic_conv("hello"))
|
600
|
+
assert_equal("hello", basic_conv(" hello "))
|
601
|
+
assert_equal("hello", basic_conv(" \t \t hello\t\t"))
|
602
|
+
|
603
|
+
assert_equal("1\n 2\n 3", basic_conv("1\n 2\n 3"))
|
604
|
+
assert_equal("1\n 2\n 3", basic_conv(" 1\n 2\n 3"))
|
605
|
+
|
606
|
+
assert_equal("1\n 2\n 3\n1\n 2", basic_conv("1\n 2\n 3\n1\n 2"))
|
607
|
+
assert_equal("1\n 2\n 3\n1\n 2", basic_conv(" 1\n 2\n 3\n 1\n 2"))
|
608
|
+
|
609
|
+
assert_equal("1\n 2\n\n 3", basic_conv(" 1\n 2\n\n 3"))
|
610
|
+
end
|
611
|
+
|
612
|
+
end
|
613
|
+
|