Skip to content

Commit 958470d

Browse files
committed
Fix blockquote parsing to match GFM behavior
Two changes to the BlockQuoteRaw rule in the PEG grammar: 1. Stop lazy continuation from consuming block-level elements by adding negative lookaheads for headings, list markers, and code fences. 2. End blockquotes at unquoted blank lines. Previously, all blank lines were consumed and the parser continued matching subsequent > lines as part of the same blockquote. Now only blank lines prefixed with > continue the blockquote, matching GFM where an unquoted blank line separates two distinct blockquotes.
1 parent c59a7a8 commit 958470d

2 files changed

Lines changed: 104 additions & 28 deletions

File tree

lib/rdoc/markdown.kpeg

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@
202202
# Extensions enabled by default
203203

204204
DEFAULT_EXTENSIONS = [
205+
:break_on_newline,
205206
:definition_lists,
206207
:github,
207208
:html,
@@ -617,8 +618,8 @@ BlockQuote = BlockQuoteRaw:a
617618

618619
BlockQuoteRaw = @StartList:a
619620
(( ">" " "? Line:l { a << l } )
620-
( !">" !@BlankLine Line:c { a << c } )*
621-
( @BlankLine:n { a << n } )*
621+
( !">" !@BlankLine !AtxStart !Bullet !Enumerator !Ticks3 Line:c { a << c } )*
622+
( ">" @BlankLine:n { a << n } )*
622623
)+
623624
{ inner_parse a.join }
624625

lib/rdoc/markdown.rb

Lines changed: 101 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,7 @@ def self.rule_info(name, rendered)
587587
# Extensions enabled by default
588588

589589
DEFAULT_EXTENSIONS = [
590+
:break_on_newline,
590591
:definition_lists,
591592
:github,
592593
:html,
@@ -1656,7 +1657,7 @@ def _BlockQuote
16561657
return _tmp
16571658
end
16581659

1659-
# BlockQuoteRaw = @StartList:a (">" " "? Line:l { a << l } (!">" !@BlankLine Line:c { a << c })* (@BlankLine:n { a << n })*)+ { inner_parse a.join }
1660+
# BlockQuoteRaw = @StartList:a (">" " "? Line:l { a << l } (!">" !@BlankLine !AtxStart !Bullet !Enumerator !Ticks3 Line:c { a << c })* (">" @BlankLine:n { a << n })*)+ { inner_parse a.join }
16601661
def _BlockQuoteRaw
16611662

16621663
_save = self.pos
@@ -1718,6 +1719,38 @@ def _BlockQuoteRaw
17181719
self.pos = _save5
17191720
break
17201721
end
1722+
_save8 = self.pos
1723+
_tmp = apply(:_AtxStart)
1724+
_tmp = _tmp ? nil : true
1725+
self.pos = _save8
1726+
unless _tmp
1727+
self.pos = _save5
1728+
break
1729+
end
1730+
_save9 = self.pos
1731+
_tmp = apply(:_Bullet)
1732+
_tmp = _tmp ? nil : true
1733+
self.pos = _save9
1734+
unless _tmp
1735+
self.pos = _save5
1736+
break
1737+
end
1738+
_save10 = self.pos
1739+
_tmp = apply(:_Enumerator)
1740+
_tmp = _tmp ? nil : true
1741+
self.pos = _save10
1742+
unless _tmp
1743+
self.pos = _save5
1744+
break
1745+
end
1746+
_save11 = self.pos
1747+
_tmp = apply(:_Ticks3)
1748+
_tmp = _tmp ? nil : true
1749+
self.pos = _save11
1750+
unless _tmp
1751+
self.pos = _save5
1752+
break
1753+
end
17211754
_tmp = apply(:_Line)
17221755
c = @result
17231756
unless _tmp
@@ -1741,18 +1774,23 @@ def _BlockQuoteRaw
17411774
end
17421775
while true
17431776

1744-
_save9 = self.pos
1777+
_save13 = self.pos
17451778
while true # sequence
1779+
_tmp = match_string(">")
1780+
unless _tmp
1781+
self.pos = _save13
1782+
break
1783+
end
17461784
_tmp = _BlankLine()
17471785
n = @result
17481786
unless _tmp
1749-
self.pos = _save9
1787+
self.pos = _save13
17501788
break
17511789
end
17521790
@result = begin; a << n ; end
17531791
_tmp = true
17541792
unless _tmp
1755-
self.pos = _save9
1793+
self.pos = _save13
17561794
end
17571795
break
17581796
end # end sequence
@@ -1769,65 +1807,97 @@ def _BlockQuoteRaw
17691807
if _tmp
17701808
while true
17711809

1772-
_save10 = self.pos
1810+
_save14 = self.pos
17731811
while true # sequence
17741812
_tmp = match_string(">")
17751813
unless _tmp
1776-
self.pos = _save10
1814+
self.pos = _save14
17771815
break
17781816
end
1779-
_save11 = self.pos
1817+
_save15 = self.pos
17801818
_tmp = match_string(" ")
17811819
unless _tmp
17821820
_tmp = true
1783-
self.pos = _save11
1821+
self.pos = _save15
17841822
end
17851823
unless _tmp
1786-
self.pos = _save10
1824+
self.pos = _save14
17871825
break
17881826
end
17891827
_tmp = apply(:_Line)
17901828
l = @result
17911829
unless _tmp
1792-
self.pos = _save10
1830+
self.pos = _save14
17931831
break
17941832
end
17951833
@result = begin; a << l ; end
17961834
_tmp = true
17971835
unless _tmp
1798-
self.pos = _save10
1836+
self.pos = _save14
17991837
break
18001838
end
18011839
while true
18021840

1803-
_save13 = self.pos
1841+
_save17 = self.pos
18041842
while true # sequence
1805-
_save14 = self.pos
1843+
_save18 = self.pos
18061844
_tmp = match_string(">")
18071845
_tmp = _tmp ? nil : true
1808-
self.pos = _save14
1846+
self.pos = _save18
18091847
unless _tmp
1810-
self.pos = _save13
1848+
self.pos = _save17
18111849
break
18121850
end
1813-
_save15 = self.pos
1851+
_save19 = self.pos
18141852
_tmp = _BlankLine()
18151853
_tmp = _tmp ? nil : true
1816-
self.pos = _save15
1854+
self.pos = _save19
1855+
unless _tmp
1856+
self.pos = _save17
1857+
break
1858+
end
1859+
_save20 = self.pos
1860+
_tmp = apply(:_AtxStart)
1861+
_tmp = _tmp ? nil : true
1862+
self.pos = _save20
1863+
unless _tmp
1864+
self.pos = _save17
1865+
break
1866+
end
1867+
_save21 = self.pos
1868+
_tmp = apply(:_Bullet)
1869+
_tmp = _tmp ? nil : true
1870+
self.pos = _save21
1871+
unless _tmp
1872+
self.pos = _save17
1873+
break
1874+
end
1875+
_save22 = self.pos
1876+
_tmp = apply(:_Enumerator)
1877+
_tmp = _tmp ? nil : true
1878+
self.pos = _save22
1879+
unless _tmp
1880+
self.pos = _save17
1881+
break
1882+
end
1883+
_save23 = self.pos
1884+
_tmp = apply(:_Ticks3)
1885+
_tmp = _tmp ? nil : true
1886+
self.pos = _save23
18171887
unless _tmp
1818-
self.pos = _save13
1888+
self.pos = _save17
18191889
break
18201890
end
18211891
_tmp = apply(:_Line)
18221892
c = @result
18231893
unless _tmp
1824-
self.pos = _save13
1894+
self.pos = _save17
18251895
break
18261896
end
18271897
@result = begin; a << c ; end
18281898
_tmp = true
18291899
unless _tmp
1830-
self.pos = _save13
1900+
self.pos = _save17
18311901
end
18321902
break
18331903
end # end sequence
@@ -1836,23 +1906,28 @@ def _BlockQuoteRaw
18361906
end
18371907
_tmp = true
18381908
unless _tmp
1839-
self.pos = _save10
1909+
self.pos = _save14
18401910
break
18411911
end
18421912
while true
18431913

1844-
_save17 = self.pos
1914+
_save25 = self.pos
18451915
while true # sequence
1916+
_tmp = match_string(">")
1917+
unless _tmp
1918+
self.pos = _save25
1919+
break
1920+
end
18461921
_tmp = _BlankLine()
18471922
n = @result
18481923
unless _tmp
1849-
self.pos = _save17
1924+
self.pos = _save25
18501925
break
18511926
end
18521927
@result = begin; a << n ; end
18531928
_tmp = true
18541929
unless _tmp
1855-
self.pos = _save17
1930+
self.pos = _save25
18561931
end
18571932
break
18581933
end # end sequence
@@ -1861,7 +1936,7 @@ def _BlockQuoteRaw
18611936
end
18621937
_tmp = true
18631938
unless _tmp
1864-
self.pos = _save10
1939+
self.pos = _save14
18651940
end
18661941
break
18671942
end # end sequence
@@ -16457,7 +16532,7 @@ def _DefinitionListDefinition
1645716532
Rules[:_SetextHeading2] = rule_info("SetextHeading2", "&(@RawLine SetextBottom2) @StartList:a (!@Endline Inline:b { a << b })+ @Sp @Newline SetextBottom2 { RDoc::Markup::Heading.new(2, a.join) }")
1645816533
Rules[:_Heading] = rule_info("Heading", "(SetextHeading | AtxHeading)")
1645916534
Rules[:_BlockQuote] = rule_info("BlockQuote", "BlockQuoteRaw:a { RDoc::Markup::BlockQuote.new(*a) }")
16460-
Rules[:_BlockQuoteRaw] = rule_info("BlockQuoteRaw", "@StartList:a (\">\" \" \"? Line:l { a << l } (!\">\" !@BlankLine Line:c { a << c })* (@BlankLine:n { a << n })*)+ { inner_parse a.join }")
16535+
Rules[:_BlockQuoteRaw] = rule_info("BlockQuoteRaw", "@StartList:a (\">\" \" \"? Line:l { a << l } (!\">\" !@BlankLine !AtxStart !Bullet !Enumerator !Ticks3 Line:c { a << c })* (\">\" @BlankLine:n { a << n })*)+ { inner_parse a.join }")
1646116536
Rules[:_NonblankIndentedLine] = rule_info("NonblankIndentedLine", "!@BlankLine IndentedLine")
1646216537
Rules[:_VerbatimChunk] = rule_info("VerbatimChunk", "@BlankLine*:a NonblankIndentedLine+:b { a.concat b }")
1646316538
Rules[:_Verbatim] = rule_info("Verbatim", "VerbatimChunk+:a { RDoc::Markup::Verbatim.new(*a.flatten) }")

0 commit comments

Comments
 (0)