Merge branch 'adjust-code-syntax' of https://github.com/srawlins/dart-markdown into srawlins-adjust-code-syntax
diff --git a/pkgs/markdown/lib/src/inline_parser.dart b/pkgs/markdown/lib/src/inline_parser.dart index d371be8..3b1d9fa 100644 --- a/pkgs/markdown/lib/src/inline_parser.dart +++ b/pkgs/markdown/lib/src/inline_parser.dart
@@ -50,10 +50,7 @@ // TODO(rnystrom): Underscores in the middle of a word should not be // parsed as emphasis like_in_this. new TagSyntax(r'_', tag: 'em'), - // Parse inline code within double backticks: "``code``". - new CodeSyntax(r'``\s?((?:.|\n)*?)\s?``'), - // Parse inline code within backticks: "`code`". - new CodeSyntax(r'`([^`]*)`') + new CodeSyntax(), // We will add the LinkSyntax once we know about the specific link resolver. ]; @@ -167,6 +164,9 @@ InlineSyntax(String pattern) : pattern = new RegExp(pattern, multiLine: true); + /// Try to match at the parser's current position. + /// + /// Returns whether or not the pattern successfully matched. bool tryMatch(InlineParser parser) { var startMatch = pattern.matchAsPrefix(parser.source, parser.pos); if (startMatch != null) { @@ -370,10 +370,41 @@ /// Matches backtick-enclosed inline code blocks. class CodeSyntax extends InlineSyntax { - CodeSyntax(String pattern) : super(pattern); + // This pattern matches: + // + // * a string of backticks (not followed by any more), followed by + // * a non-greedy string of anying, including newlines, ending with anything + // except a backtick, followed by + // * a string of backticks the same length as the first, not followed by any + // more. + // + // This conforms to the delimiters of inline code, both in Markdown.pl, and + // CommonMark. + static String _pattern = r'(`+(?!`))((?:.|\n)*?[^`])\1(?!`)'; + + CodeSyntax() : super(_pattern); + + bool tryMatch(InlineParser parser) { + if (parser.pos > 0 && parser.source[parser.pos-1] == '`') { + // Not really a match! We can't just sneak past one backtick to try the + // next character. An example of this situation would be: + // + // before ``` and `` after. + // ^--parser.pos + return false; + } + + var match = pattern.matchAsPrefix(parser.source, parser.pos); + if (match == null) { + return false; + } + parser.writeText(); + if (onMatch(parser, match)) parser.consume(match[0].length); + return true; + } bool onMatch(InlineParser parser, Match match) { - parser.addNode(new Element.text('code', escapeHtml(match[1]))); + parser.addNode(new Element.text('code', escapeHtml(match[2].trim()))); return true; } }
diff --git a/pkgs/markdown/test/original/inline_code.unit b/pkgs/markdown/test/original/inline_code.unit index 30fd05c..05c31f9 100644 --- a/pkgs/markdown/test/original/inline_code.unit +++ b/pkgs/markdown/test/original/inline_code.unit
@@ -3,6 +3,11 @@ <<< <p>before <code>source</code> after</p> +>>> single characters +before `x` and `_` after + +<<< +<p>before <code>x</code> and <code>_</code> after</p> >>> unmatched backtick before ` after @@ -25,6 +30,11 @@ <<< <p>before <code>source</code> after</p> +>>> even more backticks +before ````source with ``` and```` after + +<<< +<p>before <code>source with ``` and</code> after</p> >>> double backticks before ``can `contain` backticks`` after @@ -35,6 +45,13 @@ <<< <p>before <code>`tick`</code> after</p> +>>> multiline single backticks with spaces +before `in tick +another` after + +<<< +<p>before <code>in tick +another</code> after</p> >>> multiline double backticks with spaces before ``in `tick` another`` after @@ -57,3 +74,13 @@ <<< <p>'*' <code><em></code></p> +>>> leave unmatched backticks when first are too long +before ``` tick `` after + +<<< +<p>before ``` tick `` after</p> +>>> leave unmatched backticks when first are too short +before `` tick ``` after + +<<< +<p>before `` tick ``` after</p>