Refactor ATX headings (#486)

* Refactor ATX headings

* Update a comment

* A small fix

* Update stats
diff --git a/lib/src/block_syntaxes/header_syntax.dart b/lib/src/block_syntaxes/header_syntax.dart
index 7d2b94e..b68268d 100644
--- a/lib/src/block_syntaxes/header_syntax.dart
+++ b/lib/src/block_syntaxes/header_syntax.dart
@@ -17,9 +17,28 @@
   @override
   Node parse(BlockParser parser) {
     final match = pattern.firstMatch(parser.current)!;
+    final matchedText = match[0]!;
+    final openMarker = match[1]!;
+    final closeMarker = match[2];
+    final level = openMarker.length;
+    final openMarkerStart = matchedText.indexOf(openMarker);
+    final openMarkerEnd = openMarkerStart + level;
+
+    String? content;
+    if (closeMarker == null) {
+      content = parser.current.substring(openMarkerEnd);
+    } else {
+      final closeMarkerStart = matchedText.lastIndexOf(closeMarker);
+      content = parser.current.substring(openMarkerEnd, closeMarkerStart);
+    }
+    content = content.trim();
+
+    // https://spec.commonmark.org/0.30/#example-79
+    if (closeMarker == null && RegExp(r'^#+$').hasMatch(content)) {
+      content = null;
+    }
+
     parser.advance();
-    final level = match[1]!.length;
-    final contents = UnparsedContent(match[2]!.trim());
-    return Element('h$level', [contents]);
+    return Element('h$level', [if (content != null) UnparsedContent(content)]);
   }
 }
diff --git a/lib/src/patterns.dart b/lib/src/patterns.dart
index 269689f..2bd696b 100644
--- a/lib/src/patterns.dart
+++ b/lib/src/patterns.dart
@@ -12,7 +12,8 @@
 ///
 /// 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 = RegExp(r'^ {0,3}(#{1,6})[ \x09\x0b\x0c](.*?)#*$');
+final headerPattern =
+    RegExp(r'^ {0,3}(#{1,6})(?:[ \x09\x0b\x0c].*?)?(?:\s(#*)\s*)?$');
 
 /// The line starts with `>` with one optional space after.
 final blockquotePattern = RegExp(r'^[ ]{0,3}>[ \t]?.*$');
diff --git a/test/common_mark/atx_headings.unit b/test/common_mark/atx_headings.unit
index 1bb50e7..1cb7e98 100644
--- a/test/common_mark/atx_headings.unit
+++ b/test/common_mark/atx_headings.unit
@@ -69,7 +69,7 @@
 >>> ATX headings - 73
 ### foo ###     
 <<<
-<h3>foo ###</h3>
+<h3>foo</h3>
 >>> ATX headings - 74
 ### foo ### b
 <<<
@@ -77,15 +77,15 @@
 >>> ATX headings - 75
 # foo#
 <<<
-<h1>foo</h1>
+<h1>foo#</h1>
 >>> ATX headings - 76
 ### foo \###
 ## foo #\##
 # foo \#
 <<<
-<h3>foo \</h3>
-<h2>foo #\</h2>
-<h1>foo \</h1>
+<h3>foo ###</h3>
+<h2>foo ###</h2>
+<h1>foo #</h1>
 >>> ATX headings - 77
 ****
 ## foo
@@ -108,5 +108,5 @@
 ### ###
 <<<
 <h2></h2>
-<p>#</p>
+<h1></h1>
 <h3></h3>
diff --git a/test/gfm/atx_headings.unit b/test/gfm/atx_headings.unit
index 04e8d9f..5a60cf4 100644
--- a/test/gfm/atx_headings.unit
+++ b/test/gfm/atx_headings.unit
@@ -69,7 +69,7 @@
 >>> ATX headings - 43
 ### foo ###     
 <<<
-<h3>foo ###</h3>
+<h3>foo</h3>
 >>> ATX headings - 44
 ### foo ### b
 <<<
@@ -77,15 +77,15 @@
 >>> ATX headings - 45
 # foo#
 <<<
-<h1>foo</h1>
+<h1>foo#</h1>
 >>> ATX headings - 46
 ### foo \###
 ## foo #\##
 # foo \#
 <<<
-<h3>foo \</h3>
-<h2>foo #\</h2>
-<h1>foo \</h1>
+<h3>foo ###</h3>
+<h2>foo ###</h2>
+<h1>foo #</h1>
 >>> ATX headings - 47
 ****
 ## foo
@@ -108,5 +108,5 @@
 ### ###
 <<<
 <h2></h2>
-<p>#</p>
+<h1></h1>
 <h3></h3>
diff --git a/tool/common_mark_stats.json b/tool/common_mark_stats.json
index 1cfe950..daaa718 100644
--- a/tool/common_mark_stats.json
+++ b/tool/common_mark_stats.json
@@ -11,13 +11,13 @@
   "70": "strict",
   "71": "strict",
   "72": "strict",
-  "73": "loose",
+  "73": "strict",
   "74": "strict",
-  "75": "loose",
-  "76": "loose",
+  "75": "strict",
+  "76": "strict",
   "77": "strict",
   "78": "strict",
-  "79": "fail"
+  "79": "strict"
  },
  "Autolinks": {
   "593": "strict",
diff --git a/tool/common_mark_stats.txt b/tool/common_mark_stats.txt
index a42dfb3..337d16f 100644
--- a/tool/common_mark_stats.txt
+++ b/tool/common_mark_stats.txt
@@ -1,4 +1,4 @@
-  17 of   18 –  94.4%  ATX headings
+  18 of   18 – 100.0%  ATX headings
   19 of   19 – 100.0%  Autolinks
   13 of   13 – 100.0%  Backslash escapes
    1 of    1 – 100.0%  Blank lines
@@ -24,5 +24,5 @@
   11 of   11 – 100.0%  Tabs
    3 of    3 – 100.0%  Textual content
   19 of   19 – 100.0%  Thematic breaks
- 633 of  652 –  97.1%  TOTAL
- 610 of  633 –  96.4%  TOTAL Strict
+ 634 of  652 –  97.2%  TOTAL
+ 614 of  634 –  96.8%  TOTAL Strict
diff --git a/tool/gfm_stats.json b/tool/gfm_stats.json
index 5e5aae3..91de967 100644
--- a/tool/gfm_stats.json
+++ b/tool/gfm_stats.json
@@ -11,13 +11,13 @@
   "40": "strict",
   "41": "strict",
   "42": "strict",
-  "43": "loose",
+  "43": "strict",
   "44": "strict",
-  "45": "loose",
-  "46": "loose",
+  "45": "strict",
+  "46": "strict",
   "47": "strict",
   "48": "strict",
-  "49": "fail"
+  "49": "strict"
  },
  "Autolinks": {
   "602": "strict",
diff --git a/tool/gfm_stats.txt b/tool/gfm_stats.txt
index cc1d67f..b7598f9 100644
--- a/tool/gfm_stats.txt
+++ b/tool/gfm_stats.txt
@@ -1,4 +1,4 @@
-  17 of   18 –  94.4%  ATX headings
+  18 of   18 – 100.0%  ATX headings
   19 of   19 – 100.0%  Autolinks
   11 of   11 – 100.0%  Autolinks (extension)
   13 of   13 – 100.0%  Backslash escapes
@@ -28,5 +28,5 @@
   11 of   11 – 100.0%  Tabs
    3 of    3 – 100.0%  Textual content
   19 of   19 – 100.0%  Thematic breaks
- 651 of  671 –  97.0%  TOTAL
- 627 of  651 –  96.3%  TOTAL Strict
+ 652 of  671 –  97.2%  TOTAL
+ 631 of  652 –  96.8%  TOTAL Strict