diff --git a/lib/rdoc/markdown.kpeg b/lib/rdoc/markdown.kpeg index cde3e927f4..d95a88a823 100644 --- a/lib/rdoc/markdown.kpeg +++ b/lib/rdoc/markdown.kpeg @@ -1270,13 +1270,13 @@ Table = &{ github? } TableHead = TableItem2+:items "|"? @Newline { items } -TableRow = ( ( TableItem:item1 TableItem2*:items { [item1, *items] } ):row | TableItem2+:row ) "|"? @Newline +TableRow = ( ( TableItem:item1 TableItem2+:items { [item1, *items] } ):row | TableItem2+:row ) "|"? @Newline { row } TableItem2 = "|" TableItem TableItem = < /(?:\\.|[^|\n])+/ > { text.strip.gsub(/\\([|])/, '\1') } -TableLine = ( ( TableAlign:align1 TableAlign2*:aligns {[align1, *aligns] } ):line | TableAlign2+:line ) "|"? @Newline +TableLine = ( ( TableAlign:align1 TableAlign2+:aligns {[align1, *aligns] } ):line | TableAlign2+:line ) "|"? @Newline { line } TableAlign2 = "|" @Sp TableAlign TableAlign = < /:?-+:?/ > @Sp diff --git a/lib/rdoc/markdown.rb b/lib/rdoc/markdown.rb index 7e4adcefc3..e4d0ae9ff6 100644 --- a/lib/rdoc/markdown.rb +++ b/lib/rdoc/markdown.rb @@ -15937,7 +15937,7 @@ def _TableHead return _tmp end - # TableRow = ((TableItem:item1 TableItem2*:items { [item1, *items] }):row | TableItem2+:row) "|"? @Newline { row } + # TableRow = ((TableItem:item1 TableItem2+:items { [item1, *items] }):row | TableItem2+:row) "|"? @Newline { row } def _TableRow _save = self.pos @@ -15954,14 +15954,21 @@ def _TableRow self.pos = _save2 break end + _save3 = self.pos _ary = [] - while true - _tmp = apply(:_TableItem2) - _ary << @result if _tmp - break unless _tmp + _tmp = apply(:_TableItem2) + if _tmp + _ary << @result + while true + _tmp = apply(:_TableItem2) + _ary << @result if _tmp + break unless _tmp + end + _tmp = true + @result = _ary + else + self.pos = _save3 end - _tmp = true - @result = _ary items = @result unless _tmp self.pos = _save2 @@ -16077,7 +16084,7 @@ def _TableItem return _tmp end - # TableLine = ((TableAlign:align1 TableAlign2*:aligns {[align1, *aligns] }):line | TableAlign2+:line) "|"? @Newline { line } + # TableLine = ((TableAlign:align1 TableAlign2+:aligns {[align1, *aligns] }):line | TableAlign2+:line) "|"? @Newline { line } def _TableLine _save = self.pos @@ -16094,14 +16101,21 @@ def _TableLine self.pos = _save2 break end + _save3 = self.pos _ary = [] - while true - _tmp = apply(:_TableAlign2) - _ary << @result if _tmp - break unless _tmp + _tmp = apply(:_TableAlign2) + if _tmp + _ary << @result + while true + _tmp = apply(:_TableAlign2) + _ary << @result if _tmp + break unless _tmp + end + _tmp = true + @result = _ary + else + self.pos = _save3 end - _tmp = true - @result = _ary aligns = @result unless _tmp self.pos = _save2 @@ -16666,10 +16680,10 @@ def _DefinitionListDefinition Rules[:_CodeFence] = rule_info("CodeFence", "&{ github? } Ticks3 (@Sp StrChunk:format)? Spnl < ((!\"`\" Nonspacechar)+ | !Ticks3 /`+/ | Spacechar | @Newline)+ > Ticks3 @Sp @Newline* { verbatim = RDoc::Markup::Verbatim.new text verbatim.format = format.intern if format.instance_of?(String) verbatim }") Rules[:_Table] = rule_info("Table", "&{ github? } TableHead:header TableLine:line TableRow+:body { table = RDoc::Markup::Table.new(header, line, body) parse_table_cells(table) }") Rules[:_TableHead] = rule_info("TableHead", "TableItem2+:items \"|\"? @Newline { items }") - Rules[:_TableRow] = rule_info("TableRow", "((TableItem:item1 TableItem2*:items { [item1, *items] }):row | TableItem2+:row) \"|\"? @Newline { row }") + Rules[:_TableRow] = rule_info("TableRow", "((TableItem:item1 TableItem2+:items { [item1, *items] }):row | TableItem2+:row) \"|\"? @Newline { row }") Rules[:_TableItem2] = rule_info("TableItem2", "\"|\" TableItem") Rules[:_TableItem] = rule_info("TableItem", "< /(?:\\\\.|[^|\\n])+/ > { text.strip.gsub(/\\\\([|])/, '\\1') }") - Rules[:_TableLine] = rule_info("TableLine", "((TableAlign:align1 TableAlign2*:aligns {[align1, *aligns] }):line | TableAlign2+:line) \"|\"? @Newline { line }") + Rules[:_TableLine] = rule_info("TableLine", "((TableAlign:align1 TableAlign2+:aligns {[align1, *aligns] }):line | TableAlign2+:line) \"|\"? @Newline { line }") Rules[:_TableAlign2] = rule_info("TableAlign2", "\"|\" @Sp TableAlign") Rules[:_TableAlign] = rule_info("TableAlign", "< /:?-+:?/ > @Sp { text.start_with?(\":\") ? (text.end_with?(\":\") ? :center : :left) : (text.end_with?(\":\") ? :right : nil) }") Rules[:_DefinitionList] = rule_info("DefinitionList", "&{ definition_lists? } DefinitionListItem+:list { RDoc::Markup::List.new :NOTE, *list.flatten }") diff --git a/test/rdoc/rdoc_markdown_test.rb b/test/rdoc/rdoc_markdown_test.rb index eb7c487f27..608974d7c9 100644 --- a/test/rdoc/rdoc_markdown_test.rb +++ b/test/rdoc/rdoc_markdown_test.rb @@ -1310,6 +1310,43 @@ def test_gfm_table_with_links_and_code assert_equal expected, doc end + def test_gfm_table_does_not_consume_following_line_without_pipe + doc = parse <<~MD + | Command | Shows | + |---------|-------| + | ri File | Document for Ruby class File. | +
+ + Following paragraph. + MD + + head = %w[Command Shows] + align = [nil, nil] + body = [ + ['ri File', 'Document for Ruby class File.'], + ] + expected = doc( + @RM::Table.new(head, align, body), + para('
'), + para('Following paragraph.') + ) + + assert_equal expected, doc + end + + def test_gfm_table_separator_without_pipe_does_not_form_table + doc = parse <<~MD + | Command | Shows | + --------- + | ri File | Document for Ruby class File. | + MD + + # The separator line has no pipe, so this should NOT parse as a table. + # "| Command | Shows |" becomes a paragraph, "---" becomes a paragraph, + # and "| ri File | ..." becomes a paragraph. + assert(doc.parts.none? { |part| part.is_a?(@RM::Table) }) + end + def test_gfm_table_with_backslashes_in_code_spans doc = parse <<~MD Plain text: `$\\\\` and `$\\\\ ` should work.