Stub out heredoc support. Needs more tests. (Issue #40)

This commit is contained in:
Mike West 2011-04-13 21:35:41 +02:00
parent e5e0d53f18
commit d0690e6269
2 changed files with 53 additions and 16 deletions

View File

@ -212,41 +212,50 @@ class Rocco
"bash" => { :single => "#", :multi => nil }, "bash" => { :single => "#", :multi => nil },
"c" => { "c" => {
:single => "//", :single => "//",
:multi => { :start => "/**", :middle => "*", :end => "*/" } :multi => { :start => "/**", :middle => "*", :end => "*/" },
:heredoc => nil
}, },
"coffee-script" => { "coffee-script" => {
:single => "#", :single => "#",
:multi => { :start => "###", :middle => nil, :end => "###" } :multi => { :start => "###", :middle => nil, :end => "###" },
:heredoc => nil
}, },
"cpp" => { "cpp" => {
:single => "//", :single => "//",
:multi => { :start => "/**", :middle => "*", :end => "*/" } :multi => { :start => "/**", :middle => "*", :end => "*/" },
:heredoc => nil
}, },
"css" => { "css" => {
:single => nil, :single => nil,
:multi => { :start => "/**", :middle => "*", :end => "*/" } :multi => { :start => "/**", :middle => "*", :end => "*/" },
:heredoc => nil
}, },
"java" => { "java" => {
:single => "//", :single => "//",
:multi => { :start => "/**", :middle => "*", :end => "*/" } :multi => { :start => "/**", :middle => "*", :end => "*/" },
:heredoc => nil
}, },
"js" => { "js" => {
:single => "//", :single => "//",
:multi => { :start => "/**", :middle => "*", :end => "*/" } :multi => { :start => "/**", :middle => "*", :end => "*/" },
:heredoc => nil
}, },
"lua" => { "lua" => {
:single => "--", :single => "--",
:multi => nil :multi => nil,
:heredoc => nil
}, },
"python" => { "python" => {
:single => "#", :single => "#",
:multi => { :start => '"""', :middle => nil, :end => '"""' } :multi => { :start => '"""', :middle => nil, :end => '"""' },
:heredoc => nil
}, },
"rb" => { "rb" => {
:single => "#", :single => "#",
:multi => { :start => '=begin', :middle => nil, :end => '=end' } :multi => { :start => '=begin', :middle => nil, :end => '=end' },
:heredoc => "<<-"
}, },
"scheme" => { :single => ";;", :multi => nil }, "scheme" => { :single => ";;", :multi => nil, :heredoc => nil },
} }
def generate_comment_chars def generate_comment_chars
@ -254,7 +263,7 @@ class Rocco
if COMMENT_STYLES[@options[:language]] if COMMENT_STYLES[@options[:language]]
COMMENT_STYLES[@options[:language]] COMMENT_STYLES[@options[:language]]
else else
{ :single => @options[:comment_chars], :multi => nil } { :single => @options[:comment_chars], :multi => nil, :heredoc => nil }
end end
end end
@ -279,8 +288,9 @@ class Rocco
# To detect both block comments and single-line comments, we'll set # To detect both block comments and single-line comments, we'll set
# up a tiny state machine, and loop through each line of the file. # up a tiny state machine, and loop through each line of the file.
# This requires an `in_comment_block` boolean, and a few regular # This requires an `in_comment_block` boolean, and a few regular
# expressions for line tests. # expressions for line tests. We'll do the same for fake heredoc parsing.
in_comment_block = false in_comment_block = false
in_heredoc = false
single_line_comment, block_comment_start, block_comment_mid, block_comment_end = single_line_comment, block_comment_start, block_comment_mid, block_comment_end =
nil, nil, nil, nil nil, nil, nil, nil
if not @options[:comment_chars][:single].nil? if not @options[:comment_chars][:single].nil?
@ -293,6 +303,9 @@ class Rocco
block_comment_mid = Regexp.new("^\\s*#{Regexp.escape(@options[:comment_chars][:multi][:middle])}\\s?") block_comment_mid = Regexp.new("^\\s*#{Regexp.escape(@options[:comment_chars][:multi][:middle])}\\s?")
end end
end end
if not @options[:comment_chars][:heredoc].nil?
heredoc_start = Regexp.new("#{Regexp.escape(@options[:comment_chars][:heredoc])}(\\S+)$")
end
lines.each do |line| lines.each do |line|
# If we're currently in a comment block, check whether the line matches # If we're currently in a comment block, check whether the line matches
# the _end_ of a comment block. # the _end_ of a comment block.
@ -302,11 +315,22 @@ class Rocco
else else
docs << line.sub( block_comment_mid || '', '' ) docs << line.sub( block_comment_mid || '', '' )
end end
# Otherwise, check whether the line matches the beginning of a block, or # If we're currently in a heredoc, we're looking for the end of the
# a single-line comment all on it's lonesome. In either case, if there's # heredoc, and everything it contains is code.
# code, start a new section elsif in_heredoc
if line.match(Regexp.new("^#{Regexp.escape(in_heredoc)}$"))
in_heredoc = false
end
code << line
# Otherwise, check whether the line starts a heredoc. If so, note the end
# pattern, and the line is code. Otherwise check whether the line matches
# the beginning of a block, or a single-line comment all on it's lonesome.
# In either case, if there's code, start a new section.
else else
if block_comment_start && line.match( block_comment_start ) if heredoc_start && line.match( heredoc_start )
in_heredoc = $1
code << line
elsif block_comment_start && line.match( block_comment_start )
in_comment_block = true in_comment_block = true
if code.any? if code.any?
sections << [docs, code] sections << [docs, code]

13
test/test_heredoc.rb Normal file
View File

@ -0,0 +1,13 @@
require File.expand_path('../helper', __FILE__)
class RoccoBlockCommentTest < Test::Unit::TestCase
def test_basics
r = Rocco.new( 'test', '', { :language => "rb" } ) { "" } # Generate throwaway instance so I can test `parse`
assert_equal(
[
[ [ "Comment 1" ], [ "heredoc <<-EOH", "#comment", "code", "EOH" ] ]
],
r.parse( "# Comment 1\nheredoc <<-EOH\n#comment\ncode\nEOH" )
)
end
end