rocco 0.6 → 0.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|