From 901cb2e863214b84de2ca6c7ca89628b50e2267d Mon Sep 17 00:00:00 2001 From: Lila Rest Date: Sun, 29 Jan 2023 16:03:55 +0100 Subject: [PATCH] feat: allow to add classes to multiline code blocks and tables in Live Prev. with compatibility mode --- src/live-preview-mode.ts | 111 +++++++++++++++++++++++++++++++-------- 1 file changed, 90 insertions(+), 21 deletions(-) diff --git a/src/live-preview-mode.ts b/src/live-preview-mode.ts index f48cf7a..eddb3ff 100644 --- a/src/live-preview-mode.ts +++ b/src/live-preview-mode.ts @@ -68,39 +68,108 @@ class CompatibilityModeRenderWidget extends WidgetType { } } + +function isLineContent (line: any): boolean { + return line.text.trim() !== ""; +} + +function isLineList (line: any): Array { + let listType = null; + if (/^(\s*)(\-)(\s+)(.*)/.test(line.text)) listType = "ul"; + else if (/^(\s*)(\d+[\.\)])(\s+)(.*)/.test(line.text)) listType = "ol"; + const isList = listType ? true : false; + return [isList, listType]; +} + +function isLineCodeblockBounds (line: any): boolean { + return line.text.trim().startsWith("```"); +} + +function isTableLine (line: any): boolean { + return line.text.trim().startsWith("|") && line.text.trim().endsWith("|"); +} + + function getTargettedLinesNumber (doc: any, lineNumber: number): number { let numberOfLines = 0; - let lastLineWasList = false; - let lastListType = null; - for (let offset = 1; lineNumber + offset <= doc.lines; offset++) { + // Retrieve first line + const firstLine = doc.line(lineNumber + 1); + + // Return numberOfLine if the firstLine is a line break or empty line + if (!isLineContent(firstLine)) return numberOfLines; + + // Else increment the number of targetted lines + numberOfLines++; + + // If first line is a list item + const [firstLineIsList, firstListListType] = isLineList(firstLine); + if (firstLineIsList) { + + // Iterate over next lines + let lastListType = firstListListType; + for (let offset = 1; lineNumber + offset <= doc.lines; offset++) { + + // Retrieve next line + const nextLine = doc.line(firstLine.number + offset); - // Break if one line is already targetted but wasn't a list item - if (numberOfLines > 0 && !lastLineWasList) break; + // Return numberOfLines if the nextLine is a line break or empty line + if (!isLineContent(nextLine)) return numberOfLines; - // Retrieve line - const line = doc.line(lineNumber + offset); + // If nextLine is a list item + const [nextLineIsList, nextListListType] = isLineList(nextLine); + if (nextLineIsList) { - // Break if the line is empty - if (line.text.trim() === "") break; + // Return numberOfLines if the listType has changed + if (lastListType !== nextListListType) return numberOfLines; - // Figure whether the line is a list item and if yes, its type - let listType = null; - if (/^(\s*)(\-)(\s+)(.*)/.test(line.text)) listType = "ul"; - else if (/^(\s*)(\d+[\.\)])(\s+)(.*)/.test(line.text)) listType = "ol"; - const isList = listType ? true : false; + // Else simply increment the numberOfLines + numberOfLines++; - // Break if the - if (lastLineWasList && listType !== lastListType) break; + // And update the last list item type + lastListType = nextListListType; + } + + // Else return the numberOfLines + else return numberOfLines; + } + } - // Increment the number of lines - numberOfLines++; + // Else if first line is a multiline code block bounds + else if (isLineCodeblockBounds(firstLine)) { - // Update last list was line and last list type - lastLineWasList = isList; - lastListType = listType; + // Iterate over next lines + for (let offset = 1; lineNumber + offset <= doc.lines; offset++) { + + // Retrieve next line + const nextLine = doc.line(firstLine.number + offset); + + // Increment the number of Lines + numberOfLines++; + + // Return numberOfLines if the other bound is encoutered + if (isLineCodeblockBounds(nextLine)) return numberOfLines; + } + } + + // Else if first line is a table + else if (isTableLine(firstLine)) { + + // Iterate over next lines + for (let offset = 1; lineNumber + offset <= doc.lines; offset++) { + + // Retrieve next line + const nextLine = doc.line(firstLine.number + offset); + + // Return if the nextLine is not anymore a table line + if (!isTableLine(nextLine)) return numberOfLines; + + // Else increment the numberOfLines + numberOfLines++; + } } + // Else return the number of lines return numberOfLines; }