Skip to content

Commit b500ab5

Browse files
committed
Fix code block state tracking for embedded fence markers
Track the indentation level of opening code fences and only treat appears inside code blocks (e.g., in Python strings containing markdown examples).
1 parent 59b09f9 commit b500ab5

File tree

1 file changed

+27
-10
lines changed

1 file changed

+27
-10
lines changed

app/api/markdown/[[...slug]]/route.ts

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -179,26 +179,43 @@ function extractFrontmatterMeta(frontmatter: string): {
179179
function normalizeIndentation(text: string): string {
180180
const finalLines: string[] = [];
181181
let inCodeBlock = false;
182+
let fenceIndent = 0; // Track indentation level of opening fence
182183

183184
for (const line of text.split("\n")) {
184-
if (line.trim().startsWith("```")) {
185-
inCodeBlock = !inCodeBlock;
186-
finalLines.push(line.trimStart()); // Code block markers should start at column 0
185+
const trimmed = line.trim();
186+
const leadingSpaces = line.length - trimmed.length;
187+
188+
if (trimmed.startsWith("```")) {
189+
if (!inCodeBlock) {
190+
// Opening fence - track its indentation
191+
inCodeBlock = true;
192+
fenceIndent = leadingSpaces;
193+
finalLines.push(line.trimStart()); // Code block markers should start at column 0
194+
} else if (leadingSpaces <= fenceIndent) {
195+
// Closing fence - only if not indented more than opening fence
196+
inCodeBlock = false;
197+
fenceIndent = 0;
198+
finalLines.push(line.trimStart());
199+
} else {
200+
// ``` inside code block (indented more than opening fence)
201+
finalLines.push(line); // Preserve as code block content
202+
}
187203
} else if (inCodeBlock) {
188204
finalLines.push(line); // Preserve indentation inside code blocks
189205
} else {
190-
const trimmed = line.trimStart();
206+
const trimmedLine = line.trimStart();
191207
// Preserve indentation for nested list items and blockquotes
192208
const isListItem =
193-
UNORDERED_LIST_REGEX.test(trimmed) || ORDERED_LIST_REGEX.test(trimmed);
194-
const isBlockquote = trimmed.startsWith(">");
209+
UNORDERED_LIST_REGEX.test(trimmedLine) ||
210+
ORDERED_LIST_REGEX.test(trimmedLine);
211+
const isBlockquote = trimmedLine.startsWith(">");
195212
if ((isListItem || isBlockquote) && line.startsWith(" ")) {
196213
// Keep markdown-meaningful indentation (but normalize to 2-space increments)
197-
const leadingSpaces = line.length - line.trimStart().length;
198-
const normalizedIndent = " ".repeat(Math.floor(leadingSpaces / 2));
199-
finalLines.push(normalizedIndent + trimmed);
214+
const leadingSpacesCount = line.length - line.trimStart().length;
215+
const normalizedIndent = " ".repeat(Math.floor(leadingSpacesCount / 2));
216+
finalLines.push(normalizedIndent + trimmedLine);
200217
} else {
201-
finalLines.push(trimmed); // Remove leading whitespace for other lines
218+
finalLines.push(trimmedLine); // Remove leading whitespace for other lines
202219
}
203220
}
204221
}

0 commit comments

Comments
 (0)