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>&lt;em&gt;</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>