Files
continue/core/utils/streamMarkdownUtils.ts
2025-07-13 14:47:54 -07:00

99 lines
2.7 KiB
TypeScript

import { LineStream } from "../diff/util";
import { isMarkdownFile, MarkdownBlockStateTracker } from "./markdownUtils";
/**
* Determines if we should stop at a markdown block based on nested markdown logic.
* This handles the complex case where markdown blocks contain other markdown blocks.
* Uses optimized state tracking to avoid redundant computation.
*/
export function shouldStopAtMarkdownBlock(
stateTracker: MarkdownBlockStateTracker,
currentIndex: number,
): boolean {
return stateTracker.shouldStopAtPosition(currentIndex);
}
/**
* Processes block nesting logic and returns updated state.
*/
export function processBlockNesting(
line: string,
seenFirstFence: boolean,
shouldRemoveLineBeforeStart: (line: string) => boolean,
): { newSeenFirstFence: boolean; shouldSkip: boolean } {
if (!seenFirstFence && shouldRemoveLineBeforeStart(line)) {
return { newSeenFirstFence: false, shouldSkip: true };
}
if (!seenFirstFence) {
return { newSeenFirstFence: true, shouldSkip: false };
}
return { newSeenFirstFence: seenFirstFence, shouldSkip: false };
}
/**
* Stream transformation that stops when encountering a markdown code block ending.
* Handles nested markdown blocks in markdown files.
*/
export async function* stopAtLinesWithMarkdownSupport(
lines: LineStream,
filename: string,
): LineStream {
if (!isMarkdownFile(filename)) {
for await (const line of lines) {
if (line.trim() === "```") {
return;
}
yield line;
}
return;
}
const allLines: string[] = [];
for await (const line of lines) {
allLines.push(line);
}
const source = allLines.join("\n");
if (!source.match(/```(\w*|.*)(md|markdown|gfm|github-markdown)/)) {
// No nested markdown blocks detected, check for simple ``` stopping condition
let foundStandaloneBackticks = false;
for (let i = 0; i < allLines.length; i++) {
if (allLines[i].trim() === "```") {
// Found standalone backticks, yield lines up to this point
for (let j = 0; j < i; j++) {
yield allLines[j];
}
foundStandaloneBackticks = true;
return;
}
}
// No standalone backticks found, yield all lines
if (!foundStandaloneBackticks) {
for (const line of allLines) {
yield line;
}
}
return;
}
// Use optimized state tracker for markdown block analysis
const stateTracker = new MarkdownBlockStateTracker(allLines);
for (let i = 0; i < allLines.length; i++) {
if (stateTracker.shouldStopAtPosition(i)) {
for (let j = 0; j < i; j++) {
yield allLines[j];
}
return;
}
}
// If we get here, yield all lines
for (const line of allLines) {
yield line;
}
}