rocco 0.6 → 0.7
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/bin/rocco +2 -0
- data/lib/rocco.rb +105 -45
- data/lib/rocco/layout.mustache +1 -1
- data/rocco.gemspec +5 -2
- data/test/test_block_comment_styles.rb +64 -0
- data/test/test_docblock_annotations.rb +22 -0
- data/test/test_heredoc.rb +13 -0
- metadata +7 -4
data/bin/rocco
CHANGED
@@ -8,6 +8,7 @@
|
|
8
8
|
#/ The string to recognize as a comment marker
|
9
9
|
#/ -o, --output=<dir> Directory where generated HTML files are written
|
10
10
|
#/ -t, --template=<path> The file to use as template when rendering HTML
|
11
|
+
#/ -d, --docblocks Parse Docblock @annotations in comments
|
11
12
|
#/ --help Show this help message
|
12
13
|
|
13
14
|
require 'optparse'
|
@@ -39,6 +40,7 @@ ARGV.options { |o|
|
|
39
40
|
o.on("-l", "--language=LANG") { |lang| options[:language] = lang }
|
40
41
|
o.on("-c", "--comment-chars=CHARS") { |chars| options[:comment_chars] = Regexp.escape(chars) }
|
41
42
|
o.on("-t", "--template=TEMPLATE") { |template| options[:template_file] = template }
|
43
|
+
o.on("-d", "--docblocks") { options[:docblocks] = true }
|
42
44
|
o.on_tail("-h", "--help") { usage($stdout, 0) }
|
43
45
|
o.parse!
|
44
46
|
} or abort_with_note
|
data/lib/rocco.rb
CHANGED
@@ -52,8 +52,7 @@ require 'net/http'
|
|
52
52
|
|
53
53
|
# Code is run through [Pygments](http://pygments.org/) for syntax
|
54
54
|
# highlighting. If it's not installed, locally, use a webservice.
|
55
|
-
|
56
|
-
if !ENV['PATH'].split(':').any? { |dir| executable?("#{dir}/pygmentize") }
|
55
|
+
if !ENV['PATH'].split(':').any? { |dir| File.executable?("#{dir}/pygmentize") }
|
57
56
|
warn "WARNING: Pygments not found. Using webservice."
|
58
57
|
end
|
59
58
|
|
@@ -74,7 +73,7 @@ end
|
|
74
73
|
# to `nil` (that is, Mustache will use `./lib/rocco/layout.mustache`)_.
|
75
74
|
#
|
76
75
|
class Rocco
|
77
|
-
VERSION = '0.
|
76
|
+
VERSION = '0.7'
|
78
77
|
|
79
78
|
def initialize(filename, sources=[], options={}, &block)
|
80
79
|
@file = filename
|
@@ -159,7 +158,7 @@ class Rocco
|
|
159
158
|
# Returns `true` if `pygmentize` is available locally, `false` otherwise.
|
160
159
|
def pygmentize?
|
161
160
|
@_pygmentize ||= ENV['PATH'].split(':').
|
162
|
-
any? { |dir| executable?("#{dir}/pygmentize") }
|
161
|
+
any? { |dir| File.executable?("#{dir}/pygmentize") }
|
163
162
|
end
|
164
163
|
|
165
164
|
# If `pygmentize` is available, we can use it to autodetect a file's
|
@@ -171,7 +170,7 @@ class Rocco
|
|
171
170
|
def detect_language
|
172
171
|
@_language ||=
|
173
172
|
if pygmentize?
|
174
|
-
%x[pygmentize -N #{@file}].strip
|
173
|
+
%x[pygmentize -N #{@file}].strip.split('+').first
|
175
174
|
else
|
176
175
|
"text"
|
177
176
|
end
|
@@ -208,45 +207,55 @@ class Rocco
|
|
208
207
|
#
|
209
208
|
# At the moment, we're only returning `:single`. Consider this
|
210
209
|
# groundwork for block comment parsing.
|
210
|
+
C_STYLE_COMMENTS = {
|
211
|
+
:single => "//",
|
212
|
+
:multi => { :start => "/**", :middle => "*", :end => "*/" },
|
213
|
+
:heredoc => nil
|
214
|
+
}
|
211
215
|
COMMENT_STYLES = {
|
212
216
|
"bash" => { :single => "#", :multi => nil },
|
213
|
-
"c" =>
|
214
|
-
:single => "//",
|
215
|
-
:multi => { :start => "/**", :middle => "*", :end => "*/" }
|
216
|
-
},
|
217
|
+
"c" => C_STYLE_COMMENTS,
|
217
218
|
"coffee-script" => {
|
218
219
|
:single => "#",
|
219
|
-
:multi => { :start => "###", :middle => nil, :end => "###" }
|
220
|
-
|
221
|
-
"cpp" => {
|
222
|
-
:single => "//",
|
223
|
-
:multi => { :start => "/**", :middle => "*", :end => "*/" }
|
220
|
+
:multi => { :start => "###", :middle => nil, :end => "###" },
|
221
|
+
:heredoc => nil
|
224
222
|
},
|
223
|
+
"cpp" => C_STYLE_COMMENTS,
|
224
|
+
"csharp" => C_STYLE_COMMENTS,
|
225
225
|
"css" => {
|
226
226
|
:single => nil,
|
227
|
-
:multi => { :start => "/**", :middle => "*", :end => "*/" }
|
228
|
-
|
229
|
-
"java" => {
|
230
|
-
:single => "//",
|
231
|
-
:multi => { :start => "/**", :middle => "*", :end => "*/" }
|
227
|
+
:multi => { :start => "/**", :middle => "*", :end => "*/" },
|
228
|
+
:heredoc => nil
|
232
229
|
},
|
233
|
-
"
|
234
|
-
:single =>
|
235
|
-
:multi
|
230
|
+
"html" => {
|
231
|
+
:single => nil,
|
232
|
+
:multi => { :start => '<!--', :middle => nil, :end => '-->' },
|
233
|
+
:heredoc => nil
|
236
234
|
},
|
235
|
+
"java" => C_STYLE_COMMENTS,
|
236
|
+
"js" => C_STYLE_COMMENTS,
|
237
237
|
"lua" => {
|
238
238
|
:single => "--",
|
239
|
-
:multi => nil
|
239
|
+
:multi => nil,
|
240
|
+
:heredoc => nil
|
240
241
|
},
|
242
|
+
"php" => C_STYLE_COMMENTS,
|
241
243
|
"python" => {
|
242
244
|
:single => "#",
|
243
|
-
:multi => { :start => '"""', :middle => nil, :end => '"""' }
|
245
|
+
:multi => { :start => '"""', :middle => nil, :end => '"""' },
|
246
|
+
:heredoc => nil
|
244
247
|
},
|
245
248
|
"rb" => {
|
246
249
|
:single => "#",
|
247
|
-
:multi => { :start => '=begin', :middle => nil, :end => '=end' }
|
250
|
+
:multi => { :start => '=begin', :middle => nil, :end => '=end' },
|
251
|
+
:heredoc => "<<-"
|
252
|
+
},
|
253
|
+
"scheme" => { :single => ";;", :multi => nil, :heredoc => nil },
|
254
|
+
"xml" => {
|
255
|
+
:single => nil,
|
256
|
+
:multi => { :start => '<!--', :middle => nil, :end => '-->' },
|
257
|
+
:heredoc => nil
|
248
258
|
},
|
249
|
-
"scheme" => { :single => ";;", :multi => nil },
|
250
259
|
}
|
251
260
|
|
252
261
|
def generate_comment_chars
|
@@ -254,7 +263,7 @@ class Rocco
|
|
254
263
|
if COMMENT_STYLES[@options[:language]]
|
255
264
|
COMMENT_STYLES[@options[:language]]
|
256
265
|
else
|
257
|
-
{ :single => @options[:comment_chars], :multi => nil }
|
266
|
+
{ :single => @options[:comment_chars], :multi => nil, :heredoc => nil }
|
258
267
|
end
|
259
268
|
end
|
260
269
|
|
@@ -279,8 +288,9 @@ class Rocco
|
|
279
288
|
# To detect both block comments and single-line comments, we'll set
|
280
289
|
# up a tiny state machine, and loop through each line of the file.
|
281
290
|
# This requires an `in_comment_block` boolean, and a few regular
|
282
|
-
# expressions for line tests.
|
291
|
+
# expressions for line tests. We'll do the same for fake heredoc parsing.
|
283
292
|
in_comment_block = false
|
293
|
+
in_heredoc = false
|
284
294
|
single_line_comment, block_comment_start, block_comment_mid, block_comment_end =
|
285
295
|
nil, nil, nil, nil
|
286
296
|
if not @options[:comment_chars][:single].nil?
|
@@ -289,42 +299,77 @@ class Rocco
|
|
289
299
|
if not @options[:comment_chars][:multi].nil?
|
290
300
|
block_comment_start = Regexp.new("^\\s*#{Regexp.escape(@options[:comment_chars][:multi][:start])}\\s*$")
|
291
301
|
block_comment_end = Regexp.new("^\\s*#{Regexp.escape(@options[:comment_chars][:multi][:end])}\\s*$")
|
302
|
+
block_comment_one_liner = Regexp.new("^\\s*#{Regexp.escape(@options[:comment_chars][:multi][:start])}\\s*(.*?)\\s*#{Regexp.escape(@options[:comment_chars][:multi][:end])}\\s*$")
|
303
|
+
block_comment_start_with = Regexp.new("^\\s*#{Regexp.escape(@options[:comment_chars][:multi][:start])}\\s*(.*?)$")
|
304
|
+
block_comment_end_with = Regexp.new("\\s*(.*?)\\s*#{Regexp.escape(@options[:comment_chars][:multi][:end])}\\s*$")
|
292
305
|
if @options[:comment_chars][:multi][:middle]
|
293
306
|
block_comment_mid = Regexp.new("^\\s*#{Regexp.escape(@options[:comment_chars][:multi][:middle])}\\s?")
|
294
307
|
end
|
295
308
|
end
|
309
|
+
if not @options[:comment_chars][:heredoc].nil?
|
310
|
+
heredoc_start = Regexp.new("#{Regexp.escape(@options[:comment_chars][:heredoc])}(\\S+)$")
|
311
|
+
end
|
296
312
|
lines.each do |line|
|
297
313
|
# If we're currently in a comment block, check whether the line matches
|
298
|
-
# the _end_ of a comment block
|
314
|
+
# the _end_ of a comment block or the _end_ of a comment block with a
|
315
|
+
# comment.
|
299
316
|
if in_comment_block
|
300
|
-
if block_comment_end && line.match(
|
317
|
+
if block_comment_end && line.match(block_comment_end)
|
318
|
+
in_comment_block = false
|
319
|
+
elsif block_comment_end_with && line.match(block_comment_end_with)
|
301
320
|
in_comment_block = false
|
321
|
+
docs << line.match(block_comment_end_with).captures.first.
|
322
|
+
sub(block_comment_mid || '', '')
|
302
323
|
else
|
303
|
-
docs << line.sub(
|
324
|
+
docs << line.sub(block_comment_mid || '', '')
|
325
|
+
end
|
326
|
+
# If we're currently in a heredoc, we're looking for the end of the
|
327
|
+
# heredoc, and everything it contains is code.
|
328
|
+
elsif in_heredoc
|
329
|
+
if line.match(Regexp.new("^#{Regexp.escape(in_heredoc)}$"))
|
330
|
+
in_heredoc = false
|
304
331
|
end
|
305
|
-
|
306
|
-
#
|
307
|
-
#
|
332
|
+
code << line
|
333
|
+
# Otherwise, check whether the line starts a heredoc. If so, note the end
|
334
|
+
# pattern, and the line is code. Otherwise check whether the line matches
|
335
|
+
# the beginning of a block, or a single-line comment all on it's lonesome.
|
336
|
+
# In either case, if there's code, start a new section.
|
308
337
|
else
|
309
|
-
if
|
338
|
+
if heredoc_start && line.match(heredoc_start)
|
339
|
+
in_heredoc = $1
|
340
|
+
code << line
|
341
|
+
elsif block_comment_one_liner && line.match(block_comment_one_liner)
|
342
|
+
if code.any?
|
343
|
+
sections << [docs, code]
|
344
|
+
docs, code = [], []
|
345
|
+
end
|
346
|
+
docs << line.match(block_comment_one_liner).captures.first
|
347
|
+
elsif block_comment_start && line.match(block_comment_start)
|
348
|
+
in_comment_block = true
|
349
|
+
if code.any?
|
350
|
+
sections << [docs, code]
|
351
|
+
docs, code = [], []
|
352
|
+
end
|
353
|
+
elsif block_comment_start_with && line.match(block_comment_start_with)
|
310
354
|
in_comment_block = true
|
311
355
|
if code.any?
|
312
356
|
sections << [docs, code]
|
313
357
|
docs, code = [], []
|
314
358
|
end
|
315
|
-
|
359
|
+
docs << line.match(block_comment_start_with).captures.first
|
360
|
+
elsif single_line_comment && line.match(single_line_comment)
|
316
361
|
if code.any?
|
317
362
|
sections << [docs, code]
|
318
363
|
docs, code = [], []
|
319
364
|
end
|
320
|
-
docs << line.sub(
|
365
|
+
docs << line.sub(single_line_comment || '', '')
|
321
366
|
else
|
322
367
|
code << line
|
323
368
|
end
|
324
369
|
end
|
325
370
|
end
|
326
371
|
sections << [docs, code] if docs.any? || code.any?
|
327
|
-
normalize_leading_spaces(
|
372
|
+
normalize_leading_spaces(sections)
|
328
373
|
end
|
329
374
|
|
330
375
|
# Normalizes documentation whitespace by checking for leading whitespace,
|
@@ -340,13 +385,13 @@ class Rocco
|
|
340
385
|
#
|
341
386
|
# should yield a comment block of `Comment 1\nComment 2` and code of
|
342
387
|
# `def func():\n print "omg!"`
|
343
|
-
def normalize_leading_spaces(
|
388
|
+
def normalize_leading_spaces(sections)
|
344
389
|
sections.map do |section|
|
345
390
|
if section.any? && section[0].any?
|
346
|
-
leading_space = section[0][0].match(
|
391
|
+
leading_space = section[0][0].match("^\s+")
|
347
392
|
if leading_space
|
348
393
|
section[0] =
|
349
|
-
section[0].map{ |line| line.sub(
|
394
|
+
section[0].map{ |line| line.sub(/^#{leading_space.to_s}/, '') }
|
350
395
|
end
|
351
396
|
end
|
352
397
|
section
|
@@ -368,11 +413,26 @@ class Rocco
|
|
368
413
|
[docs_blocks, code_blocks]
|
369
414
|
end
|
370
415
|
|
416
|
+
# Take a list of block comments and convert Docblock @annotations to
|
417
|
+
# Markdown syntax.
|
418
|
+
def docblock(docs)
|
419
|
+
docs.map do |doc|
|
420
|
+
doc.split("\n").map do |line|
|
421
|
+
line.match(/^@\w+/) ? line.sub(/^@(\w+)\s+/, '> **\1** ')+" " : line
|
422
|
+
end.join("\n")
|
423
|
+
end
|
424
|
+
end
|
425
|
+
|
371
426
|
# Take the result of `split` and apply Markdown formatting to comments and
|
372
427
|
# syntax highlighting to source code.
|
373
428
|
def highlight(blocks)
|
374
429
|
docs_blocks, code_blocks = blocks
|
375
430
|
|
431
|
+
# Pre-process Docblock @annotations.
|
432
|
+
if @options[:docblocks]
|
433
|
+
docs_blocks = docblock(docs_blocks)
|
434
|
+
end
|
435
|
+
|
376
436
|
# Combine all docs blocks into a single big markdown document with section
|
377
437
|
# dividers and run through the Markdown processor. Then split it back out
|
378
438
|
# into separate sections.
|
@@ -390,7 +450,7 @@ class Rocco
|
|
390
450
|
divider_output = Regexp.new(
|
391
451
|
[ "\\n*",
|
392
452
|
span,
|
393
|
-
Regexp.escape(front),
|
453
|
+
Regexp.escape(CGI.escapeHTML(front)),
|
394
454
|
' DIVIDER',
|
395
455
|
espan,
|
396
456
|
"\\n*"
|
@@ -402,17 +462,17 @@ class Rocco
|
|
402
462
|
divider_input = "\n\n#{front}\nDIVIDER\n#{back}\n\n"
|
403
463
|
divider_output = Regexp.new(
|
404
464
|
[ "\\n*",
|
405
|
-
span, Regexp.escape(front), espan,
|
465
|
+
span, Regexp.escape(CGI.escapeHTML(front)), espan,
|
406
466
|
"\\n",
|
407
467
|
span, "DIVIDER", espan,
|
408
468
|
"\\n",
|
409
|
-
span, Regexp.escape(back), espan,
|
469
|
+
span, Regexp.escape(CGI.escapeHTML(back)), espan,
|
410
470
|
"\\n*"
|
411
471
|
].join, Regexp::MULTILINE
|
412
472
|
)
|
413
473
|
end
|
414
474
|
|
415
|
-
code_stream = code_blocks.join(
|
475
|
+
code_stream = code_blocks.join(divider_input)
|
416
476
|
|
417
477
|
code_html =
|
418
478
|
if pygmentize?
|
data/lib/rocco/layout.mustache
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
<head>
|
4
4
|
<meta http-equiv="content-type" content="text/html;charset=utf-8">
|
5
5
|
<title>{{ title }}</title>
|
6
|
-
<link rel="stylesheet" href="http://github.com/
|
6
|
+
<link rel="stylesheet" href="http://jashkenas.github.com/docco/resources/docco.css">
|
7
7
|
</head>
|
8
8
|
<body>
|
9
9
|
<div id='container'>
|
data/rocco.gemspec
CHANGED
@@ -3,8 +3,8 @@ Gem::Specification.new do |s|
|
|
3
3
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
4
4
|
|
5
5
|
s.name = 'rocco'
|
6
|
-
s.version = '0.
|
7
|
-
s.date = '2011-
|
6
|
+
s.version = '0.7'
|
7
|
+
s.date = '2011-05-22'
|
8
8
|
|
9
9
|
s.description = "Docco in Ruby"
|
10
10
|
s.summary = s.description
|
@@ -29,10 +29,13 @@ Gem::Specification.new do |s|
|
|
29
29
|
test/helper.rb
|
30
30
|
test/suite.rb
|
31
31
|
test/test_basics.rb
|
32
|
+
test/test_block_comment_styles.rb
|
32
33
|
test/test_block_comments.rb
|
33
34
|
test/test_comment_normalization.rb
|
34
35
|
test/test_commentchar_detection.rb
|
35
36
|
test/test_descriptive_section_names.rb
|
37
|
+
test/test_docblock_annotations.rb
|
38
|
+
test/test_heredoc.rb
|
36
39
|
test/test_language_detection.rb
|
37
40
|
test/test_reported_issues.rb
|
38
41
|
test/test_skippable_lines.rb
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require File.expand_path('../helper', __FILE__)
|
2
|
+
|
3
|
+
class RoccoBlockCommentTest < Test::Unit::TestCase
|
4
|
+
def test_one_liner
|
5
|
+
r = Rocco.new( 'test', '', { :language => "c" } ) { "" } # Generate throwaway instance so I can test `parse`
|
6
|
+
assert_equal(
|
7
|
+
[
|
8
|
+
[ [ "Comment 1" ], [ "def codeblock", "end" ] ]
|
9
|
+
],
|
10
|
+
r.parse( "/** Comment 1 */\ndef codeblock\nend\n" )
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_block_start_with_comment
|
15
|
+
r = Rocco.new( 'test', '', { :language => "c" } ) { "" } # Generate throwaway instance so I can test `parse`
|
16
|
+
assert_equal(
|
17
|
+
[
|
18
|
+
[ [ "Comment 1a", "Comment 1b" ], [ "def codeblock", "end" ] ]
|
19
|
+
],
|
20
|
+
r.parse( "/** Comment 1a\n * Comment 1b\n */\ndef codeblock\nend\n" )
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_block_end_with_comment
|
25
|
+
r = Rocco.new( 'test', '', { :language => "c" } ) { "" } # Generate throwaway instance so I can test `parse`
|
26
|
+
assert_equal(
|
27
|
+
[
|
28
|
+
[ [ "Comment 1a", "Comment 1b" ], [ "def codeblock", "end" ] ]
|
29
|
+
],
|
30
|
+
r.parse( "/**\n * Comment 1a\n Comment 1b */\ndef codeblock\nend\n" )
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_block_end_with_comment_and_middle
|
35
|
+
r = Rocco.new( 'test', '', { :language => "c" } ) { "" } # Generate throwaway instance so I can test `parse`
|
36
|
+
assert_equal(
|
37
|
+
[
|
38
|
+
[ [ "Comment 1a", "Comment 1b" ], [ "def codeblock", "end" ] ]
|
39
|
+
],
|
40
|
+
r.parse( "/**\n * Comment 1a\n * Comment 1b */\ndef codeblock\nend\n" )
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_block_start_with_comment_and_end_with_comment
|
45
|
+
r = Rocco.new( 'test', '', { :language => "c" } ) { "" } # Generate throwaway instance so I can test `parse`
|
46
|
+
assert_equal(
|
47
|
+
[
|
48
|
+
[ [ "Comment 1a", "Comment 1b" ], [ "def codeblock", "end" ] ]
|
49
|
+
],
|
50
|
+
r.parse( "/** Comment 1a\n Comment 1b */\ndef codeblock\nend\n" )
|
51
|
+
)
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_block_start_with_comment_and_end_with_comment_and_middle
|
55
|
+
r = Rocco.new( 'test', '', { :language => "c" } ) { "" } # Generate throwaway instance so I can test `parse`
|
56
|
+
assert_equal(
|
57
|
+
[
|
58
|
+
[ [ "Comment 1a", "Comment 1b" ], [ "def codeblock", "end" ] ]
|
59
|
+
],
|
60
|
+
r.parse( "/** Comment 1a\n * Comment 1b */\ndef codeblock\nend\n" )
|
61
|
+
)
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.expand_path('../helper', __FILE__)
|
2
|
+
|
3
|
+
class RoccoDocblockAnnotationsTest < Test::Unit::TestCase
|
4
|
+
def test_basics
|
5
|
+
r = Rocco.new( 'test', '', { :language => "c", :docblocks => true } ) { "" } # Generate throwaway instance so I can test `parse`
|
6
|
+
assert_equal(
|
7
|
+
[
|
8
|
+
"Comment\n\n> **param** mixed foo \n> **return** void "
|
9
|
+
],
|
10
|
+
r.docblock( ["Comment\n\n@param mixed foo\n@return void"] )
|
11
|
+
)
|
12
|
+
end
|
13
|
+
def test_highlighted_in_blocks
|
14
|
+
r = Rocco.new( 'test', '', { :language => "c", :docblocks => true } ) { "" } # Generate throwaway instance so I can test `parse`
|
15
|
+
highlighted = r.highlight( r.split( r.parse( "/**\n * Comment\n * @param type name\n */\ndef codeblock\nend\n" ) ) )
|
16
|
+
|
17
|
+
assert_equal(
|
18
|
+
"<p>Comment</p>\n\n<blockquote><p><strong>param</strong> type name</p></blockquote>\n",
|
19
|
+
highlighted[0][0]
|
20
|
+
)
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require File.expand_path('../helper', __FILE__)
|
2
|
+
|
3
|
+
class RoccoHeredocTest < Test::Unit::TestCase
|
4
|
+
def test_basics
|
5
|
+
r = Rocco.new( 'test', '', { :language => "rb" } ) { "" } # Generate throwaway instance so I can test `parse`
|
6
|
+
assert_equal(
|
7
|
+
[
|
8
|
+
[ [ "Comment 1" ], [ "heredoc <<-EOH", "#comment", "code", "EOH" ] ]
|
9
|
+
],
|
10
|
+
r.parse( "# Comment 1\nheredoc <<-EOH\n#comment\ncode\nEOH" )
|
11
|
+
)
|
12
|
+
end
|
13
|
+
end
|
metadata
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rocco
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 5
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: "0.
|
8
|
+
- 7
|
9
|
+
version: "0.7"
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Ryan Tomayko
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-05-22 00:00:00 -07:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -72,10 +72,13 @@ files:
|
|
72
72
|
- test/helper.rb
|
73
73
|
- test/suite.rb
|
74
74
|
- test/test_basics.rb
|
75
|
+
- test/test_block_comment_styles.rb
|
75
76
|
- test/test_block_comments.rb
|
76
77
|
- test/test_comment_normalization.rb
|
77
78
|
- test/test_commentchar_detection.rb
|
78
79
|
- test/test_descriptive_section_names.rb
|
80
|
+
- test/test_docblock_annotations.rb
|
81
|
+
- test/test_heredoc.rb
|
79
82
|
- test/test_language_detection.rb
|
80
83
|
- test/test_reported_issues.rb
|
81
84
|
- test/test_skippable_lines.rb
|