]> git.wincent.com - wikitext.git/commitdiff
Fix non-indentation inside PRE blocks
authorWincent Colaiuta <win@wincent.com>
Sun, 23 Mar 2008 17:23:33 +0000 (18:23 +0100)
committerWincent Colaiuta <win@wincent.com>
Sun, 23 Mar 2008 17:23:33 +0000 (18:23 +0100)
If you try to indent material inside a PRE block you'll find that it
doesn't work. What's actually happening is that the inital spaces are
getting emitted on the previous line, _before_ the CRLF. The problem
therefore shows up as missing indentation, but the reality is that the
spaces _are_ being emitted, only in the wrong place.

This commit applies the minimal fix for the issue, but there is more to
come. I noticed the issue with spaces but it could happen with any
token. The only reason I hadn't noticed up until now is that the most
common case (the PRINTABLE token) is correctly handled because that rule
calls the "start_para_if_necessary" function, and that emits any pending
CRLFs that might be needed.

The next commit will generalize this fix to other token types and add
specs for them.

Signed-off-by: Wincent Colaiuta <win@wincent.com>
ext/parser.c
spec/regressions_spec.rb

index 9c200495006a8a87ac0ca636337aad72a368ae9f..99cacb562383f433ab6b1489489a58498bbf3bf8 100644 (file)
@@ -420,6 +420,15 @@ void _Wikitext_start_para_if_necessary(parser_t *parser)
     parser->pending_crlf = Qfalse;
 }
 
+void _Wikitext_emit_pending_crlf_if_necessary(parser_t *parser)
+{
+    if (parser->pending_crlf == Qtrue)
+    {
+        rb_str_cat(parser->output, parser->line_ending->ptr, parser->line_ending->len);
+        parser->pending_crlf = Qfalse;
+    }
+}
+
 // Helper function that pops any excess elements off scope (pushing is already handled in the respective rules).
 // For example, given input like:
 //
@@ -2037,7 +2046,10 @@ VALUE Wikitext_parser_parse(int argc, VALUE *argv, VALUE self)
             case SPACE:
                 i = NIL_P(parser->capture) ? parser->output : parser->capture;
                 if (IN(NO_WIKI_START) || IN(PRE) || IN(PRE_START))
+                {
+                    _Wikitext_emit_pending_crlf_if_necessary(parser);
                     rb_str_cat(i, token->start, TOKEN_LEN(token));
+                }
                 else
                 {
                     // peek ahead to see next token
index c55374807c1221e9680f84f46338e1e85173498a..5f0692afc9dc445b3307e5ae66f272b97591a024 100755 (executable)
@@ -104,20 +104,22 @@ describe Wikitext::Parser, 'regressions' do
   # discovered at: http://rails.wincent.com/wiki/Movable_Type_security_notes
   # fixed by ?
   it 'should respect additional indentation found inside PRE blocks' do
-    pending
-
     # note the two extra spaces on each line
     input = dedent <<-END
-        <input type="text" name="q" size="20" maxlength="255" value="" />
-        <input type="hidden" name="hl" value="en" />
+         <input type="text" name="q" size="20" maxlength="255" value="" />
+         <input type="hidden" name="hl" value="en" />
     END
 
-    # first line had only one additional space
-    # second line had no additional spaces at all
+    # problem is the spaces were being emitted _before_ the CRLF
     expected = dedent <<-END
-      <pre>  &lt;input type="text" name="q" size="20" maxlength="255" value="" /&gt;
-        &lt;input type="hidden" name="hl" value="en" /&gt;</pre>
+      <pre>  &lt;input type=&quot;text&quot; name=&quot;q&quot; size=&quot;20&quot; maxlength=&quot;255&quot; value=&quot;&quot; /&gt;
+        &lt;input type=&quot;hidden&quot; name=&quot;hl&quot; value=&quot;en&quot; /&gt;</pre>
     END
     @parser.parse(input).should == expected
   end
+
+  # this is the general case of the bug covered in the previous spec
+  # any token that appears as the first token after a PRE token can manifest this bug
+  # PRINTABLE didn't only because it called _Wikitext_start_para_if_necessary(), which handled the pending CRLF
+  it 'should emit pending newlines for all token types found inside PRE blocks'
 end