Fixing block comment highlighting for block-only languages

Languages without single-line comments (CSS) explode when running
through `highlight`, as the `DIVIDER` mechanism doesn't deal well with
`nil` comment characters.  I've reworked the mechanism such that it
uses multi-line comments when single-line comments aren't available.
This commit is contained in:
Mike West 2010-11-25 16:08:31 +01:00
parent 1fa99adbda
commit 9d49139090
2 changed files with 48 additions and 5 deletions

View File

@ -348,9 +348,17 @@ class Rocco
to_html. to_html.
split(/\n*<h5>DIVIDER<\/h5>\n*/m) split(/\n*<h5>DIVIDER<\/h5>\n*/m)
# Combine all code blocks into a single big stream and run through either # Combine all code blocks into a single big stream with section dividers and
# `pygmentize(1)` or <http://pygments.appspot.com> # run through either `pygmentize(1)` or <http://pygments.appspot.com>
code_stream = code_blocks.join("\n\n#{@options[:comment_chars][:single]} DIVIDER\n\n") if not @options[:comment_chars][:single].nil?
divider_input = "\n\n#{@options[:comment_chars][:single]} DIVIDER\n\n"
divider_output = /\n*<span class="c.?">#{Regexp.escape(@options[:comment_chars][:single])} DIVIDER<\/span>\n*/m
else
divider_input = "\n\n#{@options[:comment_chars][:multi][:start]}\nDIVIDER\n#{@options[:comment_chars][:multi][:end]}\n\n"
divider_output = /\n*<span class="c.?">#{Regexp.escape(@options[:comment_chars][:multi][:start])}<\/span>\n<span class="c.?">DIVIDER<\/span>\n<span class="c.?">#{Regexp.escape(@options[:comment_chars][:multi][:end])}<\/span>\n*/m
end
code_stream = code_blocks.join( divider_input )
if pygmentize? if pygmentize?
code_html = highlight_pygmentize(code_stream) code_html = highlight_pygmentize(code_stream)
@ -361,7 +369,7 @@ class Rocco
# Do some post-processing on the pygments output to split things back # Do some post-processing on the pygments output to split things back
# into sections and remove partial `<pre>` blocks. # into sections and remove partial `<pre>` blocks.
code_html = code_html. code_html = code_html.
split(/\n*<span class="c.?">#{@options[:comment_chars][:single]} DIVIDER<\/span>\n*/m). split(divider_output).
map { |code| code.sub(/\n?<div class="highlight"><pre>/m, '') }. map { |code| code.sub(/\n?<div class="highlight"><pre>/m, '') }.
map { |code| code.sub(/\n?<\/pre><\/div>\n/m, '') } map { |code| code.sub(/\n?<\/pre><\/div>\n/m, '') }

View File

@ -50,7 +50,7 @@ class RoccoBlockCommentTest < Test::Unit::TestCase
r.parse( "\"\"\"\n Comment 1\n\"\"\"\ndef codeblock\nend\n\"\"\"\n Comment 2\n\"\"\"\nif false\nend" ) r.parse( "\"\"\"\n Comment 1\n\"\"\"\ndef codeblock\nend\n\"\"\"\n Comment 2\n\"\"\"\nif false\nend" )
) )
end end
def test_language_without_single_line_comments def test_language_without_single_line_comments_parse
r = Rocco.new( 'test', '', { :language => "css" } ) { "" } # Generate throwaway instance so I can test `parse` r = Rocco.new( 'test', '', { :language => "css" } ) { "" } # Generate throwaway instance so I can test `parse`
assert_equal( assert_equal(
[ [
@ -60,4 +60,39 @@ class RoccoBlockCommentTest < Test::Unit::TestCase
r.parse( "/**\n * Comment 1\n */\ndef codeblock\nend\n/**\n * Comment 2\n */\nif false\nend" ) r.parse( "/**\n * Comment 1\n */\ndef codeblock\nend\n/**\n * Comment 2\n */\nif false\nend" )
) )
end end
def test_language_without_single_line_comments_split
r = Rocco.new( 'test', '', { :language => "css" } ) { "" } # Generate throwaway instance so I can test `parse`
assert_equal(
[
[ "Comment 1", "Comment 2" ],
[ "def codeblock\nend", "if false\nend" ]
],
r.split( [
[ [ "Comment 1" ], [ "def codeblock", "end" ] ],
[ [ "Comment 2" ], [ "if false", "end" ] ]
] )
)
end
def test_language_without_single_line_comments_highlight
r = Rocco.new( 'test', '', { :language => "css" } ) { "" } # Generate throwaway instance so I can test `parse`
highlighted = r.highlight( r.split( r.parse( "/**\n * This is a comment!\n */\n.rule { goes: here; }\n/**\n * Comment 2\n */\n.rule2 { goes: here; }" ) ) )
assert_equal(
"<p>This is a comment!</p>",
highlighted[0][0]
);
assert_equal(
"<p>Comment 2</p>\n",
highlighted[1][0]
);
assert(
!highlighted[0][1].include?("DIVIDER") &&
!highlighted[1][1].include?("DIVIDER"),
"`DIVIDER` stripped successfully."
)
assert( true
);
end
end end