diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0072bcb..9125fbe 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,9 @@
-## 6.0.0-dev
+## 6.0.1
+
+* Fix a crash in checkbox lists when mixing checkbox items with
+  non-checkbox items.
+
+## 6.0.0
 
 * Require Dart 2.17
 * Add support to GFM extension for GitHub task lists (aka checkboxes).  These
diff --git a/analysis_options.yaml b/analysis_options.yaml
index 8dc8263..4190e9a 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -20,10 +20,12 @@
     - directives_ordering
     - only_throw_errors
     - package_api_docs
+    - prefer_const_declarations
+    - prefer_final_locals
+    - prefer_single_quotes
     - test_types_in_equals
     - throw_in_finally
-    - prefer_final_locals
+    - unnecessary_raw_strings
     - use_if_null_to_convert_nulls_to_bools
     - use_raw_strings
     - use_super_parameters
-    - unnecessary_raw_strings
diff --git a/example/app.dart b/example/app.dart
index 0b06b6b..d8ea6e7 100644
--- a/example/app.dart
+++ b/example/app.dart
@@ -4,6 +4,7 @@
 
 import 'dart:async';
 import 'dart:html';
+
 import 'package:markdown/markdown.dart' as md;
 
 import 'highlight.dart';
@@ -14,11 +15,15 @@
 
 final nullSanitizer = NullTreeSanitizer();
 const typing = Duration(milliseconds: 150);
-final introText = '''Markdown is the **best**!
+const introText = '''Markdown is the **best**!
 
 * It has lists.
 * It has [links](https://dart.dev).
-* It has _so much more_...''';
+* It has...
+  ```dart
+  void sourceCode() {}
+  ```
+* ...and _so much more_...''';
 
 // Flavor support.
 final basicRadio = querySelector('#basic-radio') as HtmlElement;
diff --git a/lib/src/block_syntaxes/list_syntax.dart b/lib/src/block_syntaxes/list_syntax.dart
index 483a0d8..4b7619f 100644
--- a/lib/src/block_syntaxes/list_syntax.dart
+++ b/lib/src/block_syntaxes/list_syntax.dart
@@ -6,21 +6,32 @@
 import '../block_parser.dart';
 import '../patterns.dart';
 import 'block_syntax.dart';
+import 'ordered_list_with_checkbox_syntax.dart';
+import 'unordered_list_with_checkbox_syntax.dart';
+
+/// As of Markdown 6.0.1 invisible indicators for checked/unchecked checkboxes are
+/// no longer used.  These constants are now empty strings to reflect that.
+@Deprecated(
+    'This string is no longer used internally.  It will be removed in a future version.')
+const indicatorForUncheckedCheckBox = '';
+
+/// As of Markdown 6.0.1 invisible indicators for checked/unchecked checkboxes are
+/// no longer used.  These constants are now empty strings to reflect that.
+@Deprecated(
+    'This string is no longer used internally.  It be will be removed in a future version.')
+const indicatorForCheckedCheckBox = '';
 
 class ListItem {
-  ListItem(this.lines);
+  const ListItem(
+    this.lines, {
+    this.taskListItemState,
+  });
 
-  bool forceBlock = false;
   final List<String> lines;
+  final TaskListItemState? taskListItemState;
 }
 
-/// Invisible string used to placehold for an *unchecked* CheckBox.
-/// The character is Unicode Zero Width Space (U+200B).
-const indicatorForUncheckedCheckBox = '\u{200B}';
-
-/// Invisible string used to placehold for a *checked* CheckBox.
-/// This is 2 Unicode Zero Width Space (U+200B) characters.
-const indicatorForCheckedCheckBox = '\u{200B}\u{200B}';
+enum TaskListItemState { checked, unchecked }
 
 /// Base class for both ordered and unordered lists.
 abstract class ListSyntax extends BlockSyntax {
@@ -55,18 +66,36 @@
 
   @override
   Node parse(BlockParser parser) {
+    final taskListParserEnabled = this is UnorderedListWithCheckboxSyntax ||
+        this is OrderedListWithCheckboxSyntax;
     final items = <ListItem>[];
     var childLines = <String>[];
-    final isCheckboxListSubclass =
-        (listTag == 'ol_with_checkbox' || listTag == 'ul_with_checkbox');
+    TaskListItemState? taskListItemState;
 
     void endItem() {
       if (childLines.isNotEmpty) {
-        items.add(ListItem(childLines));
+        items.add(ListItem(childLines, taskListItemState: taskListItemState));
         childLines = <String>[];
       }
     }
 
+    String parseTaskListItem(String text) {
+      final pattern = RegExp(r'^ {0,3}\[([ xX])\][ \t]');
+
+      if (taskListParserEnabled && pattern.hasMatch(text)) {
+        return text.replaceFirstMapped(pattern, ((match) {
+          taskListItemState = match[1] == ' '
+              ? TaskListItemState.unchecked
+              : TaskListItemState.checked;
+
+          return '';
+        }));
+      } else {
+        taskListItemState = null;
+        return text;
+      }
+    }
+
     late Match? possibleMatch;
     bool tryMatch(RegExp pattern) {
       possibleMatch = pattern.firstMatch(parser.current);
@@ -83,7 +112,7 @@
       final leadingSpace =
           _whitespaceRe.matchAsPrefix(parser.current)!.group(0)!;
       final leadingExpandedTabLength = _expandedTabLength(leadingSpace);
-      if (tryMatch(emptyPattern)) {
+      if (emptyPattern.hasMatch(parser.current)) {
         if (emptyPattern.hasMatch(parser.next ?? '')) {
           // Two blank lines ends a list.
           break;
@@ -95,47 +124,21 @@
         final line = parser.current
             .replaceFirst(leadingSpace, ' ' * leadingExpandedTabLength)
             .replaceFirst(indent, '');
-        childLines.add(line);
+        childLines.add(parseTaskListItem(line));
       } else if (tryMatch(hrPattern)) {
         // Horizontal rule takes precedence to a new list item.
         break;
-      } else if ((isCheckboxListSubclass &&
-              (tryMatch(ulWithCheckBoxPattern) ||
-                  tryMatch(olWithCheckBoxPattern))) ||
-          tryMatch(ulPattern) ||
-          tryMatch(olPattern)) {
-        // We know we have a valid [possibleMatch] now, so capture it.
-        final successfulMatch = possibleMatch!;
-        // The checkbox "subclass" patterns ([ulWithCheckBoxPattern] and
-        // [olWithCheckBoxPattern]) have 2 extra capturing groups at the 5
-        // position to capture the checkbox. These shift the other groups
-        // forward by 2 slots.
-        final cbGroupOffset = isCheckboxListSubclass ? 2 : 0;
-        final precedingWhitespace = successfulMatch[1]!;
-        final digits = successfulMatch[2] ?? '';
+      } else if (tryMatch(ulPattern) || tryMatch(olPattern)) {
+        final match = possibleMatch!;
+        final precedingWhitespace = match[1]!;
+        final digits = match[2] ?? '';
         if (startNumber == null && digits.isNotEmpty) {
           startNumber = int.parse(digits);
         }
-        final marker = successfulMatch[3]!;
-        // [checkBoxIndicator] is always empty unless a checkbox was found.
-        String checkBoxIndicator = '';
-        if (isCheckboxListSubclass) {
-          // Look at checkbox capture group and get checkbox state.
-          // If we find a checked or unchecked checkbox then we will
-          // set [checkBoxIndicator] to one of our invisible
-          // codes that we can later detect to know if we need to insert
-          // a check or unchecked checkbox when we are inserting the
-          // listitem li node.
-          final String checkboxGroup = successfulMatch[5]!.toLowerCase();
-          if (checkboxGroup == '[ ]') {
-            checkBoxIndicator = indicatorForUncheckedCheckBox;
-          } else if (checkboxGroup == '[x]') {
-            checkBoxIndicator = indicatorForCheckedCheckBox;
-          }
-        }
-        final firstWhitespace = successfulMatch[5 + cbGroupOffset] ?? '';
-        final restWhitespace = successfulMatch[6 + cbGroupOffset] ?? '';
-        final content = successfulMatch[7 + cbGroupOffset] ?? '';
+        final marker = match[3]!;
+        final firstWhitespace = match[5] ?? '';
+        final restWhitespace = match[6] ?? '';
+        final content = match[7] ?? '';
         final isBlank = content.isEmpty;
         if (listMarker != null && listMarker != marker) {
           // Changing the bullet or ordered list delimiter starts a new list.
@@ -165,7 +168,7 @@
         }
         // End the current list item and start a new one.
         endItem();
-        childLines.add('$checkBoxIndicator$restWhitespace$content');
+        childLines.add(parseTaskListItem('$restWhitespace$content'));
       } else if (BlockSyntax.isAtBlockEnd(parser)) {
         // Done with the list.
         break;
@@ -189,34 +192,27 @@
     items.forEach(_removeLeadingEmptyLine);
     final anyEmptyLines = _removeTrailingEmptyLines(items);
     var anyEmptyLinesBetweenBlocks = false;
+    var containsTaskList = false;
 
     for (final item in items) {
-      final itemParser = BlockParser(item.lines, parser.document);
-      final children = itemParser.parseLines();
-      // If this is a checkbox sublass of ListSyntax then we must check
-      // for possible invisible checkbox placeholder characters at
-      // the start of first node's text to see if we need to insert a checkbox.
       Element? checkboxToInsert;
-      if (isCheckboxListSubclass) {
-        if (children.isNotEmpty) {
-          if (children.first.textContent
-              .startsWith(indicatorForCheckedCheckBox)) {
-            checkboxToInsert = Element.withTag('input')
-              ..attributes['type'] = 'checkbox'
-              ..attributes['checked'] = 'true';
-          } else if (children.first.textContent
-              .startsWith(indicatorForUncheckedCheckBox)) {
-            checkboxToInsert = Element.withTag('input')
-              ..attributes['type'] = 'checkbox';
-          }
+      if (item.taskListItemState != null) {
+        containsTaskList = true;
+        checkboxToInsert = Element.withTag('input')
+          ..attributes['type'] = 'checkbox';
+        if (item.taskListItemState == TaskListItemState.checked) {
+          checkboxToInsert.attributes['checked'] = 'true';
         }
       }
-      if (checkboxToInsert != null) {
-        itemNodes.add(Element('li', [checkboxToInsert, ...children])
-          ..attributes['class'] = 'task-list-item');
-      } else {
-        itemNodes.add(Element('li', children));
-      }
+
+      final itemParser = BlockParser(item.lines, parser.document);
+      final children = itemParser.parseLines();
+      final itemElement = checkboxToInsert == null
+          ? Element('li', children)
+          : (Element('li', [checkboxToInsert, ...children])
+            ..attributes['class'] = 'task-list-item');
+
+      itemNodes.add(itemElement);
       anyEmptyLinesBetweenBlocks =
           anyEmptyLinesBetweenBlocks || itemParser.encounteredBlankLine;
     }
@@ -242,21 +238,15 @@
       }
     }
 
-    if (listTag == 'ol_with_checkbox') {
-      final olWithCheckbox = Element('ol', itemNodes)
-        ..attributes['class'] = 'contains-task-list';
-      if (startNumber != 1) {
-        olWithCheckbox.attributes['start'] = '$startNumber';
-      }
-      return olWithCheckbox;
-    } else if (listTag == 'ul_with_checkbox') {
-      return Element('ul', itemNodes)
-        ..attributes['class'] = 'contains-task-list';
-    } else if (listTag == 'ol' && startNumber != 1) {
-      return Element(listTag, itemNodes)..attributes['start'] = '$startNumber';
-    } else {
-      return Element(listTag, itemNodes);
+    final listElement = Element(listTag, itemNodes);
+    if (listTag == 'ol' && startNumber != 1) {
+      listElement.attributes['start'] = '$startNumber';
     }
+
+    if (containsTaskList) {
+      listElement.attributes['class'] = 'contains-task-list';
+    }
+    return listElement;
   }
 
   void _removeLeadingEmptyLine(ListItem item) {
diff --git a/lib/src/block_syntaxes/ordered_list_with_checkbox_syntax.dart b/lib/src/block_syntaxes/ordered_list_with_checkbox_syntax.dart
index 2f8a66a..8d865e8 100644
--- a/lib/src/block_syntaxes/ordered_list_with_checkbox_syntax.dart
+++ b/lib/src/block_syntaxes/ordered_list_with_checkbox_syntax.dart
@@ -2,16 +2,9 @@
 // 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 '../patterns.dart';
-import 'list_syntax.dart';
+import 'ordered_list_syntax.dart';
 
-/// Parses ordered lists.
-class OrderedListWithCheckBoxSyntax extends ListSyntax {
-  @override
-  RegExp get pattern => olWithCheckBoxPattern;
-
-  @override
-  String get listTag => 'ol_with_checkbox';
-
-  const OrderedListWithCheckBoxSyntax();
+/// Parses ordered lists with checkboxes.
+class OrderedListWithCheckboxSyntax extends OrderedListSyntax {
+  const OrderedListWithCheckboxSyntax();
 }
diff --git a/lib/src/block_syntaxes/unordered_list_syntax.dart b/lib/src/block_syntaxes/unordered_list_syntax.dart
index 6b1ae10..66bdf0f 100644
--- a/lib/src/block_syntaxes/unordered_list_syntax.dart
+++ b/lib/src/block_syntaxes/unordered_list_syntax.dart
@@ -2,6 +2,7 @@
 // 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 '../block_parser.dart';
 import '../patterns.dart';
 import 'list_syntax.dart';
 
@@ -11,6 +12,21 @@
   RegExp get pattern => ulPattern;
 
   @override
+  bool canParse(BlockParser parser) {
+    // Check if it matches `hrPattern`, otherwise it will produce an infinite
+    // loop if put `UnorderedListSyntax` or `UnorderedListWithCheckboxSyntax`
+    // bofore `HorizontalRuleSyntax` and parse:
+    // ```
+    // * * *
+    // ```
+    if (hrPattern.hasMatch(parser.current)) {
+      return false;
+    }
+
+    return pattern.hasMatch(parser.current);
+  }
+
+  @override
   String get listTag => 'ul';
 
   const UnorderedListSyntax();
diff --git a/lib/src/block_syntaxes/unordered_list_with_checkbox_syntax.dart b/lib/src/block_syntaxes/unordered_list_with_checkbox_syntax.dart
index 795d8a7..5f3ddf0 100644
--- a/lib/src/block_syntaxes/unordered_list_with_checkbox_syntax.dart
+++ b/lib/src/block_syntaxes/unordered_list_with_checkbox_syntax.dart
@@ -2,16 +2,9 @@
 // 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 '../patterns.dart';
-import 'list_syntax.dart';
+import 'unordered_list_syntax.dart';
 
-/// Parses unordered lists.
-class UnorderedListWithCheckBoxSyntax extends ListSyntax {
-  @override
-  RegExp get pattern => ulWithCheckBoxPattern;
-
-  @override
-  String get listTag => 'ul_with_checkbox';
-
-  const UnorderedListWithCheckBoxSyntax();
+/// Parses unordered lists with checkboxes.
+class UnorderedListWithCheckboxSyntax extends UnorderedListSyntax {
+  const UnorderedListWithCheckboxSyntax();
 }
diff --git a/lib/src/extension_set.dart b/lib/src/extension_set.dart
index 7f2be48..bbbd8ef 100644
--- a/lib/src/extension_set.dart
+++ b/lib/src/extension_set.dart
@@ -60,8 +60,8 @@
         const HeaderWithIdSyntax(),
         const SetextHeaderWithIdSyntax(),
         const TableSyntax(),
-        const UnorderedListWithCheckBoxSyntax(),
-        const OrderedListWithCheckBoxSyntax(),
+        const UnorderedListWithCheckboxSyntax(),
+        const OrderedListWithCheckboxSyntax(),
       ],
     ),
     List<InlineSyntax>.unmodifiable(
@@ -82,8 +82,8 @@
       <BlockSyntax>[
         const FencedCodeBlockSyntax(),
         const TableSyntax(),
-        const UnorderedListWithCheckBoxSyntax(),
-        const OrderedListWithCheckBoxSyntax(),
+        const UnorderedListWithCheckboxSyntax(),
+        const OrderedListWithCheckboxSyntax(),
       ],
     ),
     List<InlineSyntax>.unmodifiable(
diff --git a/lib/src/html_renderer.dart b/lib/src/html_renderer.dart
index f317707..a6abfcd 100644
--- a/lib/src/html_renderer.dart
+++ b/lib/src/html_renderer.dart
@@ -103,13 +103,13 @@
 
   @override
   void visitText(Text text) {
-    var content = text.text;
+    var content = text.textContent;
     if (const ['br', 'p', 'li'].contains(_lastVisitedTag)) {
       final lines = LineSplitter.split(content);
       content = content.contains('<pre>')
           ? lines.join('\n')
           : lines.map((line) => line.trimLeft()).join('\n');
-      if (text.text.endsWith('\n')) {
+      if (text.textContent.endsWith('\n')) {
         content = '$content\n';
       }
     }
diff --git a/lib/src/inline_syntaxes/code_syntax.dart b/lib/src/inline_syntaxes/code_syntax.dart
index efc415d..afd6371 100644
--- a/lib/src/inline_syntaxes/code_syntax.dart
+++ b/lib/src/inline_syntaxes/code_syntax.dart
@@ -20,7 +20,7 @@
   //
   // This conforms to the delimiters of inline code, both in Markdown.pl, and
   // CommonMark.
-  static final String _pattern = r'(`+(?!`))((?:.|\n)*?[^`])\1(?!`)';
+  static const _pattern = r'(`+(?!`))((?:.|\n)*?[^`])\1(?!`)';
 
   CodeSyntax() : super(_pattern);
 
diff --git a/lib/src/inline_syntaxes/color_swatch_syntax.dart b/lib/src/inline_syntaxes/color_swatch_syntax.dart
index 0998d74..e44fdbf 100644
--- a/lib/src/inline_syntaxes/color_swatch_syntax.dart
+++ b/lib/src/inline_syntaxes/color_swatch_syntax.dart
@@ -35,7 +35,7 @@
   /// * `hsl(540,70%,50%)`
   /// * `HSLA(540,70%,50%,0.3)`
   /// * `Hsla(540,70%,50%,0.3)`
-  static final String _pattern =
+  static const _pattern =
       '`((#([A-Fa-f0-9]{3}|[A-Fa-f0-9]{4}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{8}))|'
       r'([Rr][Gg][Bb][Aa]?\((\d+[%]?),(\d+[%]?),(\d+[%]?),?(\d+\.?\d+[%]?)?\))|'
       r'([Hh][Ss][Ll][Aa]?\((\d+[%]?),(\d+[%]?),(\d+[%]?),?(\d+\.?\d+[%]?)?\)))`';
diff --git a/lib/src/inline_syntaxes/delimiter_syntax.dart b/lib/src/inline_syntaxes/delimiter_syntax.dart
index 7b48ce2..4c71b17 100644
--- a/lib/src/inline_syntaxes/delimiter_syntax.dart
+++ b/lib/src/inline_syntaxes/delimiter_syntax.dart
@@ -217,7 +217,7 @@
       ']');
 
   // TODO(srawlins): Unicode whitespace
-  static final String whitespace = ' \t\r\n';
+  static const whitespace = ' \t\r\n';
 
   @override
   Text node;
diff --git a/lib/src/inline_syntaxes/email_autolink_syntax.dart b/lib/src/inline_syntaxes/email_autolink_syntax.dart
index f5b5962..e7b90ff 100644
--- a/lib/src/inline_syntaxes/email_autolink_syntax.dart
+++ b/lib/src/inline_syntaxes/email_autolink_syntax.dart
@@ -12,7 +12,7 @@
 ///
 /// See <http://spec.commonmark.org/0.28/#email-address>.
 class EmailAutolinkSyntax extends InlineSyntax {
-  static final _email =
+  static const _email =
       r'''[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}'''
       r'''[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*''';
 
diff --git a/lib/src/patterns.dart b/lib/src/patterns.dart
index f2aa7d8..5602630 100644
--- a/lib/src/patterns.dart
+++ b/lib/src/patterns.dart
@@ -31,32 +31,91 @@
 /// SETEXT should win.
 final hrPattern = RegExp(r'^ {0,3}([-*_])[ \t]*\1[ \t]*\1(?:\1|[ \t])*$');
 
-/// A line starting with one of these markers: `-`, `*`, `+`. May have up to
-/// three leading spaces before the marker and any number of spaces or tabs
-/// after.
+// why `{1}`?
+const _checkbox = r'\[[ xX]{1}\]';
+
+const _groupedWhitespaceAndEverything = r'([ \t])([ \t]*)(.*)';
+
+const _oneToNineDigits = r'\d{1,9}';
+
+const _zeroToFourWhitespace = r'[ \t]{0,4}';
+
+const _zeroToThreeSpaces = '[ ]{0,3}';
+
+/// A line starting with one of these markers: `-`, `*`, `+`.
+///
+/// May have up to three leading spaces before the marker and any number of
+/// spaces or tabs after.
 ///
 /// Contains a dummy group at `[2]`, so that the groups in [ulPattern] and
 /// [olPattern] match up; in both, `[2]` is the length of the number that begins
 /// the list marker.
-final ulPattern = RegExp(r'^([ ]{0,3})()([*+-])(([ \t])([ \t]*)(.*))?$');
+final ulPattern = RegExp(''
+    '^($_zeroToThreeSpaces)'
+    // Empty group for group number alignment with [olPattern].
+    '()'
+    '([*+-])'
+    '($_groupedWhitespaceAndEverything)?\$');
 
-/// Similar to [ulPattern] but with a GitHub style checkbox
-/// `'[ ]'|'[x]'|'[X]'` following the number. The checkbox will
-/// be grabbed by group `[5]` and [ulPattern]'s groups `[5,6,7]` are all
-/// shifted 2 places to be `[7,8,9]`
-final ulWithCheckBoxPattern = RegExp(
-    r'^([ ]{0,3})()([*+-])([ \t]{0,4})(\[[ xX]{1}\])(([ \t])([ \t]*)(.*))?$');
+/// Similar to [ulPattern] but with a GitHub-style checkbox
+/// (`'[ ]'|'[x]'|'[X]'`) following the number.
+///
+/// The checkbox will be grabbed by group `[5]` and [ulPattern]'s groups
+/// `[4]`, `[5]`, and `[6]` are all shifted 2 places to be `[6]`, `[7]`, and
+/// `[8]`.
+final ulWithCheckBoxPattern = RegExp(''
+    '^($_zeroToThreeSpaces)'
+    // Empty group for group number alignment with [olWithCheckBoxPattern].
+    '()'
+    '([*+-])'
+    '($_zeroToFourWhitespace)'
+    '($_checkbox)'
+    '($_groupedWhitespaceAndEverything)?\$');
+
+/// Similar to [ulWithCheckBoxPattern] but the checkbox is optional.
+// TODO(srawlins): This is temporary tech debt. I think we will collapse
+// [ulPattern] and [ulWithCheckBoxPattern] into this one pattern.
+final ulWithPossibleCheckboxPattern = RegExp(''
+    '^($_zeroToThreeSpaces)'
+    // Empty group for group number alignment with [olWithCheckBoxPattern].
+    '()'
+    '([*+-])'
+    '(($_zeroToFourWhitespace)($_checkbox))?'
+    // [7], [8], [9], and [10].
+    '($_groupedWhitespaceAndEverything)?\$');
 
 /// A line starting with a number like `123.`. May have up to three leading
 /// spaces before the marker and any number of spaces or tabs after.
-final olPattern = RegExp(r'^([ ]{0,3})(\d{1,9})([\.)])(([ \t])([ \t]*)(.*))?$');
+final olPattern = RegExp(''
+    '^($_zeroToThreeSpaces)'
+    '($_oneToNineDigits)'
+    r'([\.)])'
+    '($_groupedWhitespaceAndEverything)?\$');
 
-/// Similar to [olPattern] but with a GitHub style checkbox
-/// `'[ ]'|'[x]'|'[X]'` following the number. The checkbox will
-/// be grabbed by group `[5]` and [olPattern]'s groups `[5,6,7]` are all
-/// shifted 2 places to be `[7,8,9]`
-final olWithCheckBoxPattern = RegExp(
-    r'^([ ]{0,3})(\d{1,9})([\.)])([ \t]{0,4})(\[[ xX]{1}\])(([ \t])([ \t]*)(.*))?$');
+/// Similar to [olPattern] but with a GitHub-style checkbox
+/// (`'[ ]'|'[x]'|'[X]'`) following the number.
+///
+/// The checkbox will be grabbed by group `[5]` and [olPattern]'s groups
+/// `[4]`, `[5]`, and `[6]` are all shifted 2 places to be `[6]`, `[7]`, and
+/// `[8]`.
+final olWithCheckBoxPattern = RegExp(''
+    '^($_zeroToThreeSpaces)'
+    '($_oneToNineDigits)'
+    r'([\.)])'
+    '($_zeroToFourWhitespace)'
+    '($_checkbox)'
+    '($_groupedWhitespaceAndEverything)?\$');
+
+/// Similar to [olWithCheckBoxPattern] but the checkbox is optional.
+// TODO(srawlins): This is temporary tech debt. I think we will collapse
+// [olPattern] and [olWithCheckBoxPattern] into this one pattern.
+final olWithPossibleCheckboxPattern = RegExp(''
+    '^($_zeroToThreeSpaces)'
+    '($_oneToNineDigits)'
+    r'([\.)])'
+    '(($_zeroToFourWhitespace)($_checkbox))?'
+    // [7], [8], [9], and [10].
+    '($_groupedWhitespaceAndEverything)?\$');
 
 /// A line of hyphens separated by at least one pipe.
 final tablePattern = RegExp(
diff --git a/lib/src/version.dart b/lib/src/version.dart
index 92964be..da01dc7 100644
--- a/lib/src/version.dart
+++ b/lib/src/version.dart
@@ -1,2 +1,2 @@
 // Generated code. Do not modify.
-const packageVersion = '6.0.0-dev';
+const packageVersion = '6.0.1';
diff --git a/pubspec.yaml b/pubspec.yaml
index 0dc576f..ab02324 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: markdown
-version: 6.0.0-dev
+version: 6.0.1
 
 description: A portable Markdown library written in Dart that can parse
  Markdown into HTML.
diff --git a/test/document_test.dart b/test/document_test.dart
index 8a26900..42ca40f 100644
--- a/test/document_test.dart
+++ b/test/document_test.dart
@@ -54,7 +54,7 @@
 
       test('encodeHtml spaces are preserved in text', () {
         // Example to get a <p> tag rendered before a text node.
-        final contents = 'Sample\n\n<pre>\n A\n B\n</pre>';
+        const contents = 'Sample\n\n<pre>\n A\n B\n</pre>';
         final document = Document(encodeHtml: true);
         final lines = LineSplitter.split(contents).toList();
         final nodes = BlockParser(lines, document).parseLines();
@@ -64,7 +64,7 @@
 
       test('encode double quotes, greater than, and less than when escaped',
           () {
-        final contents = r'\>\"\< Hello';
+        const contents = r'\>\"\< Hello';
         final document = Document(encodeHtml: true);
         final nodes = document.parseInline(contents);
         expect(nodes, hasLength(1));
@@ -113,7 +113,7 @@
       });
 
       test('leave double quotes, greater than, and less than when escaped', () {
-        final contents = r'\>\"\< Hello';
+        const contents = r'\>\"\< Hello';
         final document = Document(encodeHtml: false);
         final nodes = document.parseInline(contents);
         expect(nodes, hasLength(1));
diff --git a/test/extensions/ordered_list_with_checkboxes.unit b/test/extensions/ordered_list_with_checkboxes.unit
new file mode 100644
index 0000000..84cf86e
--- /dev/null
+++ b/test/extensions/ordered_list_with_checkboxes.unit
@@ -0,0 +1,65 @@
+>>> checkbox with space
+1. [ ] one
+2. [ ] two
+<<<
+<ol class="contains-task-list">
+<li class="task-list-item"><input type="checkbox"></input>one</li>
+<li class="task-list-item"><input type="checkbox"></input>two</li>
+</ol>
+>>> empty checkbox
+1. [] one
+2. [] two
+<<<
+<ol>
+<li>[] one</li>
+<li>[] two</li>
+</ol>
+>>> checkbox with x
+1. [x] one
+2. [x] two
+<<<
+<ol class="contains-task-list">
+<li class="task-list-item"><input type="checkbox" checked="true"></input>one</li>
+<li class="task-list-item"><input type="checkbox" checked="true"></input>two</li>
+</ol>
+>>> checkbox with X
+1. [X] one
+2. [X] two
+<<<
+<ol class="contains-task-list">
+<li class="task-list-item"><input type="checkbox" checked="true"></input>one</li>
+<li class="task-list-item"><input type="checkbox" checked="true"></input>two</li>
+</ol>
+>>> mixed checkboxes
+1. [ ] one
+2. [] two
+3. [x] three
+4. [X] four
+5. five
+<<<
+<ol class="contains-task-list">
+<li class="task-list-item"><input type="checkbox"></input>one</li>
+<li>[] two</li>
+<li class="task-list-item"><input type="checkbox" checked="true"></input>three</li>
+<li class="task-list-item"><input type="checkbox" checked="true"></input>four</li>
+<li>five</li>
+</ol>
+>>> mixed leading spaces
+1.[ ] zero
+2. [ ] one
+3.  [ ] two
+4.   [ ] three
+5.    [ ] four
+6.     [ ] five
+<<<
+<p>1.[ ] zero</p>
+<ol start="2" class="contains-task-list">
+<li class="task-list-item"><input type="checkbox"></input>one</li>
+<li class="task-list-item"><input type="checkbox"></input>two</li>
+<li class="task-list-item"><input type="checkbox"></input>three</li>
+<li class="task-list-item"><input type="checkbox"></input>four</li>
+<li>
+<pre><code>[ ] five
+</code></pre>
+</li>
+</ol>
\ No newline at end of file
diff --git a/test/extensions/unordered_list_with_checkboxes.unit b/test/extensions/unordered_list_with_checkboxes.unit
new file mode 100644
index 0000000..170b6de
--- /dev/null
+++ b/test/extensions/unordered_list_with_checkboxes.unit
@@ -0,0 +1,65 @@
+>>> checkbox with space
+* [ ] one
+* [ ] two
+<<<
+<ul class="contains-task-list">
+<li class="task-list-item"><input type="checkbox"></input>one</li>
+<li class="task-list-item"><input type="checkbox"></input>two</li>
+</ul>
+>>> empty checkbox
+* [] one
+* [] two
+<<<
+<ul>
+<li>[] one</li>
+<li>[] two</li>
+</ul>
+>>> checkbox with x
+* [x] one
+* [x] two
+<<<
+<ul class="contains-task-list">
+<li class="task-list-item"><input type="checkbox" checked="true"></input>one</li>
+<li class="task-list-item"><input type="checkbox" checked="true"></input>two</li>
+</ul>
+>>> checkbox with X
+* [X] one
+* [X] two
+<<<
+<ul class="contains-task-list">
+<li class="task-list-item"><input type="checkbox" checked="true"></input>one</li>
+<li class="task-list-item"><input type="checkbox" checked="true"></input>two</li>
+</ul>
+>>> mixed checkboxes
+* [ ] one
+* [] two
+* [x] three
+* [X] four
+* five
+<<<
+<ul class="contains-task-list">
+<li class="task-list-item"><input type="checkbox"></input>one</li>
+<li>[] two</li>
+<li class="task-list-item"><input type="checkbox" checked="true"></input>three</li>
+<li class="task-list-item"><input type="checkbox" checked="true"></input>four</li>
+<li>five</li>
+</ul>
+>>> mixed leading spaces
+*[ ] zero
+* [ ] one
+*  [ ] two
+*   [ ] three
+*    [ ] four
+*     [ ] five
+<<<
+<p>*[ ] zero</p>
+<ul class="contains-task-list">
+<li class="task-list-item"><input type="checkbox"></input>one</li>
+<li class="task-list-item"><input type="checkbox"></input>two</li>
+<li class="task-list-item"><input type="checkbox"></input>three</li>
+<li class="task-list-item"><input type="checkbox"></input>four</li>
+<li>
+<pre><code>[ ] five
+</code></pre>
+</li>
+</ul>
\ No newline at end of file
diff --git a/test/markdown_test.dart b/test/markdown_test.dart
index a9f6fde..0b05c73 100644
--- a/test/markdown_test.dart
+++ b/test/markdown_test.dart
@@ -10,7 +10,11 @@
 void main() async {
   await testDirectory('original');
 
-  // Block syntax extensions
+  // Block syntax extensions.
+  testFile(
+    'extensions/fenced_blockquotes.unit',
+    blockSyntaxes: [const FencedBlockquoteSyntax()],
+  );
   testFile(
     'extensions/fenced_code_blocks.unit',
     blockSyntaxes: [const FencedCodeBlockSyntax()],
@@ -20,6 +24,10 @@
     blockSyntaxes: [const HeaderWithIdSyntax()],
   );
   testFile(
+    'extensions/ordered_list_with_checkboxes.unit',
+    blockSyntaxes: [const OrderedListWithCheckboxSyntax()],
+  );
+  testFile(
     'extensions/setext_headers_with_ids.unit',
     blockSyntaxes: [const SetextHeaderWithIdSyntax()],
   );
@@ -28,8 +36,8 @@
     blockSyntaxes: [const TableSyntax()],
   );
   testFile(
-    'extensions/fenced_blockquotes.unit',
-    blockSyntaxes: [const FencedBlockquoteSyntax()],
+    'extensions/unordered_list_with_checkboxes.unit',
+    blockSyntaxes: [const UnorderedListWithCheckboxSyntax()],
   );
 
   // Inline syntax extensions
diff --git a/tool/dartdoc_compare.dart b/tool/dartdoc_compare.dart
index e0195ba..7186d79 100644
--- a/tool/dartdoc_compare.dart
+++ b/tool/dartdoc_compare.dart
@@ -121,7 +121,7 @@
       }
       final out = Directory.systemTemp
           .createTempSync('dartdoc-compare-${markdownRef}__');
-      final cmd = 'dart';
+      const cmd = 'dart';
       final args = [dartdocBin, '--output=${out.path}'];
 
       if (sdk) {
diff --git a/tool/stats.dart b/tool/stats.dart
index a212e6c..d09b0df 100644
--- a/tool/stats.dart
+++ b/tool/stats.dart
@@ -220,7 +220,7 @@
     sink = stdout;
   }
 
-  final encoder = const JsonEncoder.withIndent(' ', _convert);
+  const encoder = JsonEncoder.withIndent(' ', _convert);
   try {
     sink.writeln(encoder.convert(scores));
   } on JsonUnsupportedObjectError catch (e) {
diff --git a/tool/update_blns.dart b/tool/update_blns.dart
index b48b8a7..1f50e36 100644
--- a/tool/update_blns.dart
+++ b/tool/update_blns.dart
@@ -2,9 +2,9 @@
 import 'dart:convert';
 import 'dart:io';
 
-final _blnsJsonRawUrl =
+const _blnsJsonRawUrl =
     'https://github.com/minimaxir/big-list-of-naughty-strings/raw/master/blns.json';
-final _blnsFilePath = 'test/blns.dart';
+const _blnsFilePath = 'test/blns.dart';
 
 Future<void> main() async {
   final client = HttpClient();
diff --git a/tool/update_emojis.dart b/tool/update_emojis.dart
index 6b11e7a..396be33 100644
--- a/tool/update_emojis.dart
+++ b/tool/update_emojis.dart
@@ -9,9 +9,9 @@
 // update_github_emojis.dart now generates the emoji list using the GitHub API
 // to retrieve the emoji list.  It uses this emoji source as a source to keep
 // binary compatibility with the Unicode sequences for each emoji found here.
-final _emojisJsonRawUrl =
+const _emojisJsonRawUrl =
     'https://raw.githubusercontent.com/muan/emojilib/v2.4.0/emojis.json';
-final _emojisFilePath = 'lib/src/legacy_emojis.dart';
+const _emojisFilePath = 'lib/src/legacy_emojis.dart';
 
 Future<void> main() async {
   final client = HttpClient();
diff --git a/tool/update_github_emojis.dart b/tool/update_github_emojis.dart
index 5431d31..5fbf60c 100644
--- a/tool/update_github_emojis.dart
+++ b/tool/update_github_emojis.dart
@@ -26,11 +26,11 @@
 /// The 'cricket' emoji changes from `🏏` to `🦗`, legacy available as 'cricket_game'.
 /// (if the -g flag us used to force using the GitHub Unicode sequences for the
 /// emoji then additionally the 'email' emoji changes from '✉️' to '📧').
-final _emojisJsonRawUrl = 'https://api.github.com/emojis';
-final _emojisFilePath = 'lib/src/emojis.dart';
+const _emojisJsonRawUrl = 'https://api.github.com/emojis';
+const _emojisFilePath = 'lib/src/emojis.dart';
 
 /// Reference to emoji map within legacy_emojis.dart
-final legacyEmojis = legacy.emojis;
+const legacyEmojis = legacy.emojis;
 
 /// AUTO GENERATED by [reconcile_emojis.dart] - this only needed to be done ONCE
 /// during the reconciliation process with the legacy emoji.