Fix PRE_START and BLOCKQUOTE_START following shorthand
authorWincent Colaiuta <win@wincent.com>
Fri, 27 Mar 2009 12:42:49 +0000 (13:42 +0100)
committerWincent Colaiuta <win@wincent.com>
Fri, 27 Mar 2009 12:42:49 +0000 (13:42 +0100)
This adds a special case for PRE_START and
BLOCKQUOTE_START tokens which immediately follow
PRE and BLOCKQUOTE shorthand lines.

Basically, if they appear in the first column
then they are valid, because they close the old
(shorthand) blocks and open a new block. Anywhere
other than the first column they are considered
illegal.

See:
  https://wincent.com/issues/818

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

index f4bb04c..240f7a4 100644 (file)
@@ -1129,11 +1129,23 @@ VALUE Wikitext_parser_parse(int argc, VALUE *argv, VALUE self)
                 }
                 else if (IN(BLOCKQUOTE))
                 {
-                    // PRE_START is illegal
-                    i = NIL_P(parser->capture) ? parser->output : parser->capture;
-                    _Wikitext_pop_excess_elements(parser);
-                    _Wikitext_start_para_if_necessary(parser);
-                    rb_str_cat(i, escaped_pre_start, sizeof(escaped_pre_start) - 1);
+                    if (token->column_start == 1) // only allowed in first column
+                    {
+                        _Wikitext_rollback_failed_link(parser);             // if any
+                        _Wikitext_rollback_failed_external_link(parser);    // if any
+                        _Wikitext_pop_from_stack_up_to(parser, Qnil, BLOCKQUOTE, Qtrue);
+                        _Wikitext_indent(parser);
+                        rb_str_cat(parser->output, pre_start, sizeof(pre_start) - 1);
+                        ary_push(parser->scope, PRE_START);
+                        ary_push(parser->line, PRE_START);
+                    }
+                    else // PRE_START illegal here
+                    {
+                        i = NIL_P(parser->capture) ? parser->output : parser->capture;
+                        _Wikitext_pop_excess_elements(parser);
+                        _Wikitext_start_para_if_necessary(parser);
+                        rb_str_cat(i, escaped_pre_start, sizeof(escaped_pre_start) - 1);
+                    }
                 }
                 else
                 {
@@ -1240,11 +1252,24 @@ VALUE Wikitext_parser_parse(int argc, VALUE *argv, VALUE self)
                 }
                 else if (IN(BLOCKQUOTE))
                 {
-                    // illegal here
-                    i = NIL_P(parser->capture) ? parser->output : parser->capture;
-                    _Wikitext_pop_excess_elements(parser);
-                    _Wikitext_start_para_if_necessary(parser);
-                    rb_str_cat(i, escaped_blockquote_start, sizeof(escaped_blockquote_start) - 1);
+                    if (token->column_start == 1) // only allowed in first column
+                    {
+                        _Wikitext_rollback_failed_link(parser);             // if any
+                        _Wikitext_rollback_failed_external_link(parser);    // if any
+                        _Wikitext_pop_from_stack_up_to(parser, Qnil, BLOCKQUOTE, Qtrue);
+                        _Wikitext_indent(parser);
+                        rb_str_cat(parser->output, blockquote_start, sizeof(blockquote_start) - 1);
+                        rb_str_cat(parser->output, parser->line_ending->ptr, parser->line_ending->len);
+                        ary_push(parser->scope, BLOCKQUOTE_START);
+                        ary_push(parser->line, BLOCKQUOTE_START);
+                    }
+                    else // BLOCKQUOTE_START illegal here
+                    {
+                        i = NIL_P(parser->capture) ? parser->output : parser->capture;
+                        _Wikitext_pop_excess_elements(parser);
+                        _Wikitext_start_para_if_necessary(parser);
+                        rb_str_cat(i, escaped_blockquote_start, sizeof(escaped_blockquote_start) - 1);
+                    }
                 }
                 else
                 {
index 0f39d6e..2f08bea 100755 (executable)
@@ -763,4 +763,36 @@ describe Wikitext::Parser, 'regressions' do
     END
     @parser.parse(input).should == expected
   end
+
+  # https://wincent.com/issues/818
+  it 'should handle BLOCKQUOTE_START blocks which follow BLOCKQUOTE shorthand' do
+    input = dedent <<-END
+      > foo
+      <blockquote>bar</blockquote>
+    END
+    expected = dedent <<-END
+      <blockquote>
+        <p>foo</p>
+      </blockquote>
+      <blockquote>
+        <p>bar</p>
+      </blockquote>
+    END
+    @parser.parse(input).should == expected
+  end
+
+  # https://wincent.com/issues/818
+  it 'should handle PRE_START blocks which follow BLOCKQUOTE shorthand' do
+    input = dedent <<-END
+      > foo
+      <pre>bar</pre>
+    END
+    expected = dedent <<-END
+      <blockquote>
+        <p>foo</p>
+      </blockquote>
+      <pre>bar</pre>
+    END
+    @parser.parse(input).should == expected
+  end
 end