Merge branch 'master' into regexp
diff --git a/pkgs/markdown/benchmark/input.md b/pkgs/markdown/benchmark/input.md index 31f5f57..1af6a7e 100644 --- a/pkgs/markdown/benchmark/input.md +++ b/pkgs/markdown/benchmark/input.md
@@ -1,10 +1,16 @@ **TODO: Add more examples to cover all of the syntax.** +# Regressions + +Bad backtracking in the HR parser: + +-------------------------- | ------------------------------------------------- + +# Real-world sample + This input was taken from the test package's README to get a representative sample of real-world markdown: -## Writing Tests - Tests are specified using the top-level [`test()`][test] function, and test assertions are made using [`expect()`][expect]:
diff --git a/pkgs/markdown/benchmark/output.html b/pkgs/markdown/benchmark/output.html index 6c49aae..71e5771 100644 --- a/pkgs/markdown/benchmark/output.html +++ b/pkgs/markdown/benchmark/output.html
@@ -1,7 +1,10 @@ <p><strong>TODO: Add more examples to cover all of the syntax.</strong></p> +<h1>Regressions</h1> +<p>Bad backtracking in the HR parser:</p> +<p>-------------------------- | -------------------------------------------------</p> +<h1>Real-world sample</h1> <p>This input was taken from the test package's README to get a representative sample of real-world markdown:</p> -<h2>Writing Tests</h2> <p>Tests are specified using the top-level <a href="http://www.dartdocs.org/documentation/test/latest/index.html#test/test@id_test"><code>test()</code></a> function, and test assertions are made using <a href="http://www.dartdocs.org/documentation/test/latest/index.html#test/test@id_expect"><code>expect()</code></a>:</p> <pre class="dart"><code>import "package:test/test.dart";
diff --git a/pkgs/markdown/lib/src/block_parser.dart b/pkgs/markdown/lib/src/block_parser.dart index 504fdbb..5bdc111 100644 --- a/pkgs/markdown/lib/src/block_parser.dart +++ b/pkgs/markdown/lib/src/block_parser.dart
@@ -9,13 +9,16 @@ import 'util.dart'; /// The line contains only whitespace or is empty. -final _emptyPattern = new RegExp(r'^([ \t]*)$'); +final _emptyPattern = new RegExp(r'^(?:[ \t]*)$'); /// A series of `=` or `-` (on the next line) define setext-style headers. -final _setextPattern = new RegExp(r'^((=+)|(-+))$'); +final _setextPattern = new RegExp(r'^(=+|-+)$'); /// Leading (and trailing) `#` define atx-style headers. -final _headerPattern = new RegExp(r'^(#{1,6})(.*?)#*$'); +/// +/// Starts with 1-6 unescaped `#` characters which must not be followed by a +/// non-space character. Line may end with any number of `#` characters,. +final _headerPattern = new RegExp(r'^(#{1,6})[ \x09\x0b\x0c](.*?)#*$'); /// The line starts with `>` with one optional space after. final _blockquotePattern = new RegExp(r'^[ ]{0,3}>[ ]?(.*)$'); @@ -24,14 +27,12 @@ final _indentPattern = new RegExp(r'^(?: |\t)(.*)$'); /// Fenced code block. -final _codePattern = new RegExp(r'^(`{3,}|~{3,})(.*)$'); +final _codePattern = new RegExp(r'^[ ]{0,3}(`{3,}|~{3,})(.*)$'); /// Three or more hyphens, asterisks or underscores by themselves. Note that /// a line like `----` is valid as both HR and SETEXT. In case of a tie, /// SETEXT should win. -final _hrPattern = new RegExp(r'^[ ]{0,3}((-+[ ]{0,2}){3,}|' - r'(_+[ ]{0,2}){3,}|' - r'(\*+[ ]{0,2}){3,})$'); +final _hrPattern = new RegExp(r'^ {0,3}([-*_]) *\1 *\1(?:\1| )*$'); /// Really hacky way to detect block-level embedded HTML. Just looks for /// "<somename".
diff --git a/pkgs/markdown/test/markdown_test.dart b/pkgs/markdown/test/markdown_test.dart index 4facb3b..b747289 100644 --- a/pkgs/markdown/test/markdown_test.dart +++ b/pkgs/markdown/test/markdown_test.dart
@@ -236,6 +236,24 @@ '''); validate( + 'h7 is not a header', + ''' + ####### header + ''', + ''' + <p>####### header</p> + '''); + + validate( + 'h6 must not be followed by non-space ', + ''' + ######A header + ''', + ''' + <p>######A header</p> + '''); + + validate( 'trailing "#" are removed', ''' # header ######