fixMarkdownNewLines static method
Implementation
static String fixMarkdownNewLines(String data) {
final codeBlockPattern =
RegExp(r'```.*?```', dotAll: true); // Matches code blocks
final nonCodeBlocks = <String>[];
final codeBlocks = <String>[];
// Split data into segments of code blocks and non-code blocks
final matches = codeBlockPattern.allMatches(data);
int lastMatchEnd = 0;
for (final match in matches) {
// Add text before the code block as a non-code block
if (match.start > lastMatchEnd) {
nonCodeBlocks.add(data.substring(lastMatchEnd, match.start));
}
// Add the code block itself
codeBlocks.add(data.substring(match.start, match.end));
lastMatchEnd = match.end;
}
// Add any remaining non-code block text
if (lastMatchEnd < data.length) {
nonCodeBlocks.add(data.substring(lastMatchEnd));
}
// Process non-code blocks (using \u200B as a temporary hack to show new lines):
final processedNonCodeBlocks = nonCodeBlocks.map((block) {
return block
.replaceAll(
'\n\n\n\n', '\n\n\n\u200B\n') // First replace quadruple newlines
.replaceAll('\n\n\n', '\n\n\u200B\n') // Then replace triple newlines
.replaceAll('\n', ' \n'); // Then replace single newlines
}).toList();
// Combine processed non-code blocks and code blocks back together
final buffer = StringBuffer();
int codeIndex = 0, nonCodeIndex = 0;
for (final _ in matches) {
if (nonCodeIndex < processedNonCodeBlocks.length) {
buffer.write(processedNonCodeBlocks[nonCodeIndex++]);
}
if (codeIndex < codeBlocks.length) {
buffer.write(codeBlocks[codeIndex++]);
}
}
// Add any remaining non-code block
if (nonCodeIndex < processedNonCodeBlocks.length) {
buffer.write(processedNonCodeBlocks[nonCodeIndex]);
}
return buffer.toString();
}