Merge pull request dart-lang/markdown#59 from srawlins/fix-escaping

Escape backslashes.
diff --git a/pkgs/markdown/CHANGELOG.md b/pkgs/markdown/CHANGELOG.md
index 8bd82d6..03ee8d0 100644
--- a/pkgs/markdown/CHANGELOG.md
+++ b/pkgs/markdown/CHANGELOG.md
@@ -10,6 +10,8 @@
 * The text `[foo]()` now renders as an inline link.
 * Header identifier support in the HeaderWithIdSyntax and
   SetextHeaderWithIdSyntax extensions.
+* Implement backslash-escaping so that Markdown syntax can be escaped, such as
+  `[foo]\(bar) ==> <p>[foo](bar)</p>`.
 
 ## 0.8.0
 
diff --git a/pkgs/markdown/lib/src/inline_parser.dart b/pkgs/markdown/lib/src/inline_parser.dart
index 5a496c0..94847c0 100644
--- a/pkgs/markdown/lib/src/inline_parser.dart
+++ b/pkgs/markdown/lib/src/inline_parser.dart
@@ -29,6 +29,8 @@
     new AutolinkSyntax(),
     new LinkSyntax(),
     new ImageLinkSyntax(),
+    // Allow any punctuation to be escaped.
+    new EscapeSyntax(),
     // "*" surrounded by spaces is left alone.
     new TextSyntax(r' \* '),
     // "_" surrounded by spaces is left alone.
@@ -199,6 +201,19 @@
   }
 }
 
+/// Escape punctuation preceded by a backslash.
+class EscapeSyntax extends InlineSyntax {
+  final String substitute;
+
+  EscapeSyntax() : super(r'''\\[!"#$%&'()*+,\-./:;<=>?@\[\\\]^_`{|}~]''');
+
+  bool onMatch(InlineParser parser, Match match) {
+    // Insert the substitution.
+    parser.addNode(new Text(match[0][1]));
+    return true;
+  }
+}
+
 /// Leave inline HTML tags alone, from
 /// [CommonMark 0.22](http://spec.commonmark.org/0.22/#raw-html).
 ///
diff --git a/pkgs/markdown/test/original/backslash_escapes.unit b/pkgs/markdown/test/original/backslash_escapes.unit
new file mode 100644
index 0000000..8828c49
--- /dev/null
+++ b/pkgs/markdown/test/original/backslash_escapes.unit
@@ -0,0 +1,38 @@
+>>> Escaped punctuation is indeed escaped.
+Punctuations like \! and \" and \# and \$ and \% and \& and \' and \( and \)
+and \* and \+ and \, and \- and \. and \/ and \: and \; and \< and \= and \>
+and \? and \@ and \[ and \\ and \] and \^ and \_ and \` and \{ and \| and \}
+and \~.
+
+<<<
+<p>Punctuations like ! and " and # and $ and % and & and ' and ( and )
+and * and + and , and - and . and / and : and ; and < and = and >
+and ? and @ and [ and \ and ] and ^ and _ and ` and { and | and }
+and ~.</p>
+>>> Inline code blocks can be escaped.
+Not \`code`.
+
+<<<
+<p>Not `code`.</p>
+>>> Emphasis can be escaped.
+\*Both* \_kinds_.
+
+<<<
+<p>*Both* _kinds_.</p>
+>>> Links can be escaped.
+Escaped brackets: \[foo](bar), and parens: [foo]\(bar).
+
+<<<
+<p>Escaped brackets: [foo](bar), and parens: [foo](bar).</p>
+>>> Reference links can be escaped.
+Front: \[foo][bar] and back: [foo]\[bar].
+
+<<<
+<p>Front: [foo][bar] and back: [foo][bar].</p>
+>>> Images can be escaped.
+Escapes the bang: \![img](img.png),
+and escapes the image: !\[img](img.png).
+
+<<<
+<p>Escapes the bang: !<a href="img.png">img</a>,
+and escapes the image: ![img](img.png).</p>