From 9d491390902d9f9dc2445f05a6103a10b1ac4156 Mon Sep 17 00:00:00 2001 From: Mike West Date: Thu, 25 Nov 2010 16:08:31 +0100 Subject: [PATCH] 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. --- lib/rocco.rb | 16 ++++++++++++---- test/test_block_comments.rb | 37 ++++++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/lib/rocco.rb b/lib/rocco.rb index a480366..f6eefa0 100644 --- a/lib/rocco.rb +++ b/lib/rocco.rb @@ -348,9 +348,17 @@ class Rocco to_html. split(/\n*
DIVIDER<\/h5>\n*/m) - # Combine all code blocks into a single big stream and run through either - # `pygmentize(1)` or - code_stream = code_blocks.join("\n\n#{@options[:comment_chars][:single]} DIVIDER\n\n") + # Combine all code blocks into a single big stream with section dividers and + # run through either `pygmentize(1)` or + if not @options[:comment_chars][:single].nil? + divider_input = "\n\n#{@options[:comment_chars][:single]} DIVIDER\n\n" + divider_output = /\n*#{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*#{Regexp.escape(@options[:comment_chars][:multi][:start])}<\/span>\nDIVIDER<\/span>\n#{Regexp.escape(@options[:comment_chars][:multi][:end])}<\/span>\n*/m + end + + code_stream = code_blocks.join( divider_input ) if pygmentize? code_html = highlight_pygmentize(code_stream) @@ -361,7 +369,7 @@ class Rocco # Do some post-processing on the pygments output to split things back # into sections and remove partial `
` blocks.
     code_html = code_html.
-      split(/\n*#{@options[:comment_chars][:single]} DIVIDER<\/span>\n*/m).
+      split(divider_output).
       map { |code| code.sub(/\n?
/m, '') }.
       map { |code| code.sub(/\n?<\/pre><\/div>\n/m, '') }
 
diff --git a/test/test_block_comments.rb b/test/test_block_comments.rb
index f814a49..408aff4 100644
--- a/test/test_block_comments.rb
+++ b/test/test_block_comments.rb
@@ -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" )
         )
     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`
         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" )
         )
     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(
+          "

This is a comment!

", + highlighted[0][0] + ); + assert_equal( + "

Comment 2

\n", + highlighted[1][0] + ); + assert( + !highlighted[0][1].include?("DIVIDER") && + !highlighted[1][1].include?("DIVIDER"), + "`DIVIDER` stripped successfully." + ) + + assert( true + ); + end + end