Add SoftLineBreakSyntax (dart-lang/markdown#473)

diff --git a/pkgs/markdown/CHANGELOG.md b/pkgs/markdown/CHANGELOG.md
index 58e4ab0..a8b61a3 100644
--- a/pkgs/markdown/CHANGELOG.md
+++ b/pkgs/markdown/CHANGELOG.md
@@ -10,6 +10,8 @@
 * Add a new syntax `BlockHtmlSyntax` to parse HTML blocks.
 * Add a new syntax `DecodeHtmlSyntax` to decode HTML entity and numeric
   character references.
+* Add a new syntax `SoftLineBreakSyntax` to remove the single space before the
+  line ending.
 * Deprecate `BlockTagBlockHtmlSyntax`, `LongBlockHtmlSyntax` and
   `OtherTagBlockHtmlSyntax`. These syntaxes will be removed from the next major
   version.
diff --git a/pkgs/markdown/lib/markdown.dart b/pkgs/markdown/lib/markdown.dart
index de6792d..58d0d8e 100644
--- a/pkgs/markdown/lib/markdown.dart
+++ b/pkgs/markdown/lib/markdown.dart
@@ -78,6 +78,7 @@
 export 'src/inline_syntaxes/inline_syntax.dart';
 export 'src/inline_syntaxes/line_break_syntax.dart';
 export 'src/inline_syntaxes/link_syntax.dart';
+export 'src/inline_syntaxes/soft_line_break_syntax.dart';
 export 'src/inline_syntaxes/strikethrough_syntax.dart';
 export 'src/inline_syntaxes/tag_syntax.dart';
 export 'src/inline_syntaxes/text_syntax.dart';
diff --git a/pkgs/markdown/lib/src/inline_parser.dart b/pkgs/markdown/lib/src/inline_parser.dart
index e0f08c6..c9ebbb6 100644
--- a/pkgs/markdown/lib/src/inline_parser.dart
+++ b/pkgs/markdown/lib/src/inline_parser.dart
@@ -16,6 +16,7 @@
 import 'inline_syntaxes/inline_syntax.dart';
 import 'inline_syntaxes/line_break_syntax.dart';
 import 'inline_syntaxes/link_syntax.dart';
+import 'inline_syntaxes/soft_line_break_syntax.dart';
 import 'inline_syntaxes/text_syntax.dart';
 
 /// Maintains the internal state needed to parse inline span elements in
@@ -37,6 +38,7 @@
     // Parse "__strong__" and "_emphasis_" tags.
     EmphasisSyntax.underscore(),
     CodeSyntax(),
+    SoftLineBreakSyntax(),
     // We will add the LinkSyntax once we know about the specific link resolver.
   ]);
 
diff --git a/pkgs/markdown/lib/src/inline_syntaxes/soft_line_break_syntax.dart b/pkgs/markdown/lib/src/inline_syntaxes/soft_line_break_syntax.dart
new file mode 100644
index 0000000..c8395d5
--- /dev/null
+++ b/pkgs/markdown/lib/src/inline_syntaxes/soft_line_break_syntax.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import '../charcode.dart';
+import '../inline_parser.dart';
+import 'inline_syntax.dart';
+
+/// Removes the single space before the line ending.
+// https://spec.commonmark.org/0.30/#soft-line-breaks.
+// If there are more than one spaces before the line ending, it may hit the hard
+// break syntax.
+class SoftLineBreakSyntax extends InlineSyntax {
+  SoftLineBreakSyntax() : super(' \n', startCharacter: $space);
+
+  @override
+  bool onMatch(InlineParser parser, Match match) {
+    parser.consume(1);
+    return false;
+  }
+}
diff --git a/pkgs/markdown/test/common_mark/images.unit b/pkgs/markdown/test/common_mark/images.unit
index 8b561a3..f1cf602 100644
--- a/pkgs/markdown/test/common_mark/images.unit
+++ b/pkgs/markdown/test/common_mark/images.unit
@@ -80,7 +80,7 @@
 
 [foo]: /url "title"
 <<<
-<p><img src="/url" alt="foo" title="title" /> 
+<p><img src="/url" alt="foo" title="title" />
 []</p>
 >>> Images - 587
 ![foo]
diff --git a/pkgs/markdown/test/common_mark/links.unit b/pkgs/markdown/test/common_mark/links.unit
index d144227..5e99f65 100644
--- a/pkgs/markdown/test/common_mark/links.unit
+++ b/pkgs/markdown/test/common_mark/links.unit
@@ -390,7 +390,7 @@
 
 [foo]: /url "title"
 <<<
-<p><a href="/url" title="title">foo</a> 
+<p><a href="/url" title="title">foo</a>
 []</p>
 >>> Links - 556
 [foo]
diff --git a/pkgs/markdown/test/common_mark/soft_line_breaks.unit b/pkgs/markdown/test/common_mark/soft_line_breaks.unit
index f4c1da3..88e82f2 100644
--- a/pkgs/markdown/test/common_mark/soft_line_breaks.unit
+++ b/pkgs/markdown/test/common_mark/soft_line_breaks.unit
@@ -8,5 +8,5 @@
 foo 
  baz
 <<<
-<p>foo 
+<p>foo
 baz</p>
diff --git a/pkgs/markdown/test/gfm/images.unit b/pkgs/markdown/test/gfm/images.unit
index ed9b0bb..838a07c 100644
--- a/pkgs/markdown/test/gfm/images.unit
+++ b/pkgs/markdown/test/gfm/images.unit
@@ -80,7 +80,7 @@
 
 [foo]: /url "title"
 <<<
-<p><img src="/url" alt="foo" title="title" /> 
+<p><img src="/url" alt="foo" title="title" />
 []</p>
 >>> Images - 596
 ![foo]
diff --git a/pkgs/markdown/test/gfm/links.unit b/pkgs/markdown/test/gfm/links.unit
index f0209c9..b2d8e7f 100644
--- a/pkgs/markdown/test/gfm/links.unit
+++ b/pkgs/markdown/test/gfm/links.unit
@@ -378,7 +378,7 @@
 
 [foo]: /url "title"
 <<<
-<p><a href="/url" title="title">foo</a> 
+<p><a href="/url" title="title">foo</a>
 []</p>
 >>> Links - 565
 [foo]
diff --git a/pkgs/markdown/test/gfm/soft_line_breaks.unit b/pkgs/markdown/test/gfm/soft_line_breaks.unit
index 00f2f86..be7e802 100644
--- a/pkgs/markdown/test/gfm/soft_line_breaks.unit
+++ b/pkgs/markdown/test/gfm/soft_line_breaks.unit
@@ -8,5 +8,5 @@
 foo 
  baz
 <<<
-<p>foo 
+<p>foo
 baz</p>
diff --git a/pkgs/markdown/tool/common_mark_stats.json b/pkgs/markdown/tool/common_mark_stats.json
index 1de59bb..7c98634 100644
--- a/pkgs/markdown/tool/common_mark_stats.json
+++ b/pkgs/markdown/tool/common_mark_stats.json
@@ -371,7 +371,7 @@
   "583": "strict",
   "584": "strict",
   "585": "strict",
-  "586": "loose",
+  "586": "strict",
   "587": "strict",
   "588": "strict",
   "589": "loose",
@@ -500,7 +500,7 @@
   "552": "strict",
   "553": "strict",
   "554": "strict",
-  "555": "loose",
+  "555": "strict",
   "556": "strict",
   "557": "strict",
   "558": "strict",
@@ -662,7 +662,7 @@
  },
  "Soft line breaks": {
   "648": "strict",
-  "649": "loose"
+  "649": "strict"
  },
  "Tabs": {
   "1": "strict",
diff --git a/pkgs/markdown/tool/common_mark_stats.txt b/pkgs/markdown/tool/common_mark_stats.txt
index 3afa53c..f1200e9 100644
--- a/pkgs/markdown/tool/common_mark_stats.txt
+++ b/pkgs/markdown/tool/common_mark_stats.txt
@@ -25,4 +25,4 @@
    3 of    3 – 100.0%  Textual content
   19 of   19 – 100.0%  Thematic breaks
  622 of  652 –  95.4%  TOTAL
- 559 of  622 –  89.9%  TOTAL Strict
+ 562 of  622 –  90.4%  TOTAL Strict
diff --git a/pkgs/markdown/tool/gfm_stats.json b/pkgs/markdown/tool/gfm_stats.json
index 1460d3e..c37aada 100644
--- a/pkgs/markdown/tool/gfm_stats.json
+++ b/pkgs/markdown/tool/gfm_stats.json
@@ -386,7 +386,7 @@
   "592": "strict",
   "593": "strict",
   "594": "strict",
-  "595": "loose",
+  "595": "strict",
   "596": "strict",
   "597": "strict",
   "598": "loose",
@@ -513,7 +513,7 @@
   "561": "strict",
   "562": "strict",
   "563": "strict",
-  "564": "loose",
+  "564": "strict",
   "565": "strict",
   "566": "strict",
   "567": "strict",
@@ -675,7 +675,7 @@
  },
  "Soft line breaks": {
   "669": "strict",
-  "670": "loose"
+  "670": "strict"
  },
  "Strikethrough (extension)": {
   "491": "strict",
diff --git a/pkgs/markdown/tool/gfm_stats.txt b/pkgs/markdown/tool/gfm_stats.txt
index c455a49..5b47d05 100644
--- a/pkgs/markdown/tool/gfm_stats.txt
+++ b/pkgs/markdown/tool/gfm_stats.txt
@@ -29,4 +29,4 @@
    3 of    3 – 100.0%  Textual content
   19 of   19 – 100.0%  Thematic breaks
  640 of  671 –  95.4%  TOTAL
- 575 of  640 –  89.8%  TOTAL Strict
+ 578 of  640 –  90.3%  TOTAL Strict