UNPKG

monaco-latex

Version:

LaTeX language support for Monaco Editor

115 lines (114 loc) 4.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createFoldingProvider = exports.LaTeXFoldingRangeProvider = void 0; class LaTeXFoldingRangeProvider { constructor(monaco) { this.monaco = monaco; } provideFoldingRanges(model, context, token) { const ranges = []; const lineCount = model.getLineCount(); // Stack for tracking nested environments const envStack = []; // Stack for sections (hierarchical) const sectionStack = []; const sectionLevels = { part: 0, chapter: 1, section: 2, subsection: 3, subsubsection: 4, paragraph: 5, subparagraph: 6, }; // Multi-line comment tracking let commentStart = null; for (let lineNumber = 1; lineNumber <= lineCount; lineNumber++) { const line = model.getLineContent(lineNumber); // Check for \begin{environment} const beginMatch = line.match(/\\begin\{(\w+\*?)\}/); if (beginMatch) { envStack.push({ name: beginMatch[1], line: lineNumber }); } // Check for \end{environment} const endMatch = line.match(/\\end\{(\w+\*?)\}/); if (endMatch && envStack.length > 0) { // Find matching begin for (let i = envStack.length - 1; i >= 0; i--) { if (envStack[i].name === endMatch[1]) { if (lineNumber > envStack[i].line) { ranges.push({ start: envStack[i].line, end: lineNumber, kind: this.monaco.languages.FoldingRangeKind.Region, }); } envStack.splice(i, 1); break; } } } // Check for sections const sectionMatch = line.match(/\\(part|chapter|section|subsection|subsubsection|paragraph|subparagraph)\*?\s*[\[{]/); if (sectionMatch) { const level = sectionLevels[sectionMatch[1]]; // Close any sections at same or higher level (lower number = higher level) while (sectionStack.length > 0 && sectionStack[sectionStack.length - 1].level >= level) { const prev = sectionStack.pop(); if (lineNumber - prev.line > 1) { ranges.push({ start: prev.line, end: lineNumber - 1, kind: this.monaco.languages.FoldingRangeKind.Region, }); } } sectionStack.push({ level, line: lineNumber }); } // Check for comment blocks (consecutive comment lines) const isComment = line.trim().startsWith('%'); if (isComment && commentStart === null) { commentStart = lineNumber; } else if (!isComment && commentStart !== null) { if (lineNumber - commentStart > 2) { ranges.push({ start: commentStart, end: lineNumber - 1, kind: this.monaco.languages.FoldingRangeKind.Comment, }); } commentStart = null; } } // Close remaining sections at end of document while (sectionStack.length > 0) { const prev = sectionStack.pop(); if (lineCount - prev.line > 1) { ranges.push({ start: prev.line, end: lineCount, kind: this.monaco.languages.FoldingRangeKind.Region, }); } } // Close any unclosed comment block if (commentStart !== null && lineCount - commentStart > 2) { ranges.push({ start: commentStart, end: lineCount, kind: this.monaco.languages.FoldingRangeKind.Comment, }); } return ranges; } } exports.LaTeXFoldingRangeProvider = LaTeXFoldingRangeProvider; /** * Creates a folding range provider for LaTeX. */ function createFoldingProvider(monaco) { return new LaTeXFoldingRangeProvider(monaco); } exports.createFoldingProvider = createFoldingProvider;