From d38eeaa36a5775de0408157c2ea07132d4878111 Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Tue, 30 Sep 2025 17:06:02 +0200 Subject: [PATCH 1/5] [markdown] Simplify deindentation logic for fenced code blocks --- .../fenced_code_block_syntax.dart | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/pkgs/markdown/lib/src/block_syntaxes/fenced_code_block_syntax.dart b/pkgs/markdown/lib/src/block_syntaxes/fenced_code_block_syntax.dart index cea110665..aa7a41151 100644 --- a/pkgs/markdown/lib/src/block_syntaxes/fenced_code_block_syntax.dart +++ b/pkgs/markdown/lib/src/block_syntaxes/fenced_code_block_syntax.dart @@ -4,6 +4,7 @@ import '../ast.dart'; import '../block_parser.dart'; +import '../charcode.dart' show $space; import '../line.dart'; import '../patterns.dart'; import '../util.dart'; @@ -50,9 +51,22 @@ class FencedCodeBlockSyntax extends BlockSyntax { return Element('pre', [code]); } - String _removeIndentation(String content, int length) { - final text = content.replaceFirst(RegExp('^\\s{0,$length}'), ''); - return content.substring(content.length - text.length); + static String _removeLeadingSpaces(String content, {required int upTo}) { + var indexAfterRemovedSpaces = 0; + + // Find the index of the first non-space character + // or the first space after the maximum removed specified by 'upTo'. + while (indexAfterRemovedSpaces < upTo && + indexAfterRemovedSpaces < content.length) { + // We can just check for space (` `) since fenced code blocks + // consider spaces before the opening code fence as the + // indentation that should be removed. + if (content.codeUnitAt(indexAfterRemovedSpaces) != $space) { + break; + } + indexAfterRemovedSpaces += 1; + } + return content.substring(indexAfterRemovedSpaces); } @override @@ -76,7 +90,7 @@ class FencedCodeBlockSyntax extends BlockSyntax { !closingFence.marker.startsWith(openingMarker) || closingFence.hasInfo) { childLines.add( - Line(_removeIndentation(parser.current.content, indent)), + Line(_removeLeadingSpaces(parser.current.content, upTo: indent)), ); parser.advance(); } else { From 9431ab9c4f4f19dbb4207df7d4b69d463a17c6b5 Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Tue, 30 Sep 2025 17:11:22 +0200 Subject: [PATCH 2/5] Move function and add doc comment --- .../fenced_code_block_syntax.dart | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/pkgs/markdown/lib/src/block_syntaxes/fenced_code_block_syntax.dart b/pkgs/markdown/lib/src/block_syntaxes/fenced_code_block_syntax.dart index aa7a41151..c9dfeedd5 100644 --- a/pkgs/markdown/lib/src/block_syntaxes/fenced_code_block_syntax.dart +++ b/pkgs/markdown/lib/src/block_syntaxes/fenced_code_block_syntax.dart @@ -51,24 +51,6 @@ class FencedCodeBlockSyntax extends BlockSyntax { return Element('pre', [code]); } - static String _removeLeadingSpaces(String content, {required int upTo}) { - var indexAfterRemovedSpaces = 0; - - // Find the index of the first non-space character - // or the first space after the maximum removed specified by 'upTo'. - while (indexAfterRemovedSpaces < upTo && - indexAfterRemovedSpaces < content.length) { - // We can just check for space (` `) since fenced code blocks - // consider spaces before the opening code fence as the - // indentation that should be removed. - if (content.codeUnitAt(indexAfterRemovedSpaces) != $space) { - break; - } - indexAfterRemovedSpaces += 1; - } - return content.substring(indexAfterRemovedSpaces); - } - @override List parseChildLines( BlockParser parser, [ @@ -109,6 +91,25 @@ class FencedCodeBlockSyntax extends BlockSyntax { return childLines; } + + /// Removes the leading spaces (` `) from [content] up the given [upTo] count. + static String _removeLeadingSpaces(String content, {required int upTo}) { + var indexAfterRemovedSpaces = 0; + + // Find the index of the first non-space character + // or the first space after the maximum removed specified by 'upTo'. + while (indexAfterRemovedSpaces < upTo && + indexAfterRemovedSpaces < content.length) { + // We can just check for space (` `) since fenced code blocks + // consider spaces before the opening code fence as the + // indentation that should be removed. + if (content.codeUnitAt(indexAfterRemovedSpaces) != $space) { + break; + } + indexAfterRemovedSpaces += 1; + } + return content.substring(indexAfterRemovedSpaces); + } } class _FenceMatch { From f535f55f8c2d5f9a2c7106b2ecae55a2e84829ea Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Tue, 30 Sep 2025 17:16:54 +0200 Subject: [PATCH 3/5] Rename `indexAfterRemovedSpaces` to `leadingSpacesCount` Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- .../src/block_syntaxes/fenced_code_block_syntax.dart | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pkgs/markdown/lib/src/block_syntaxes/fenced_code_block_syntax.dart b/pkgs/markdown/lib/src/block_syntaxes/fenced_code_block_syntax.dart index c9dfeedd5..a7f08103d 100644 --- a/pkgs/markdown/lib/src/block_syntaxes/fenced_code_block_syntax.dart +++ b/pkgs/markdown/lib/src/block_syntaxes/fenced_code_block_syntax.dart @@ -94,21 +94,21 @@ class FencedCodeBlockSyntax extends BlockSyntax { /// Removes the leading spaces (` `) from [content] up the given [upTo] count. static String _removeLeadingSpaces(String content, {required int upTo}) { - var indexAfterRemovedSpaces = 0; + var leadingSpacesCount = 0; // Find the index of the first non-space character // or the first space after the maximum removed specified by 'upTo'. - while (indexAfterRemovedSpaces < upTo && - indexAfterRemovedSpaces < content.length) { + while (leadingSpacesCount < upTo && + leadingSpacesCount < content.length) { // We can just check for space (` `) since fenced code blocks // consider spaces before the opening code fence as the // indentation that should be removed. - if (content.codeUnitAt(indexAfterRemovedSpaces) != $space) { + if (content.codeUnitAt(leadingSpacesCount) != $space) { break; } - indexAfterRemovedSpaces += 1; + leadingSpacesCount += 1; } - return content.substring(indexAfterRemovedSpaces); + return content.substring(leadingSpacesCount); } } From 22e4d0813bfb57f9d1ea1573f3d6e94f925417b2 Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Tue, 30 Sep 2025 17:29:34 +0200 Subject: [PATCH 4/5] Reformat after applying rename --- .../lib/src/block_syntaxes/fenced_code_block_syntax.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkgs/markdown/lib/src/block_syntaxes/fenced_code_block_syntax.dart b/pkgs/markdown/lib/src/block_syntaxes/fenced_code_block_syntax.dart index a7f08103d..de695c7a9 100644 --- a/pkgs/markdown/lib/src/block_syntaxes/fenced_code_block_syntax.dart +++ b/pkgs/markdown/lib/src/block_syntaxes/fenced_code_block_syntax.dart @@ -98,8 +98,7 @@ class FencedCodeBlockSyntax extends BlockSyntax { // Find the index of the first non-space character // or the first space after the maximum removed specified by 'upTo'. - while (leadingSpacesCount < upTo && - leadingSpacesCount < content.length) { + while (leadingSpacesCount < upTo && leadingSpacesCount < content.length) { // We can just check for space (` `) since fenced code blocks // consider spaces before the opening code fence as the // indentation that should be removed. From 1afcdc0615ca1b23273209ab14926dfddf19b772 Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Tue, 30 Sep 2025 17:30:40 +0200 Subject: [PATCH 5/5] Add a small comment to changelog --- pkgs/markdown/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/pkgs/markdown/CHANGELOG.md b/pkgs/markdown/CHANGELOG.md index 60a250887..cc4337702 100644 --- a/pkgs/markdown/CHANGELOG.md +++ b/pkgs/markdown/CHANGELOG.md @@ -4,6 +4,7 @@ (https://dart-lang.github.io/tools). * Update `package:web` API references in the example. * Fix performance and correctness of HTML comment parser. +* Optimize indentation processing of fenced code blocks. * Require Dart `^3.4.0`. ## 7.3.0