From b1629e2e6f6a510721561946261dd0bc03d96919 Mon Sep 17 00:00:00 2001 From: Maxim Karpov Date: Mon, 2 Sep 2024 11:20:56 +0300 Subject: [PATCH] feat: add merge included tests --- src/transform/preprocessors/included/index.ts | 134 ++++++++++-------- 1 file changed, 75 insertions(+), 59 deletions(-) diff --git a/src/transform/preprocessors/included/index.ts b/src/transform/preprocessors/included/index.ts index 7aa28c5c..1fef568d 100644 --- a/src/transform/preprocessors/included/index.ts +++ b/src/transform/preprocessors/included/index.ts @@ -5,79 +5,95 @@ import {MarkdownItIncluded} from '../../plugins/includes/types'; const INCLUDE_REGEXP = /^\s*{%\s*included\s*\((.+?)\)\s*%}\s*$/; const INCLUDE_END_REGEXP = /^\s*{% endincluded %}\s*$/; -const index: MarkdownItPreprocessorCb = (input, options, md?: MarkdownItIncluded) => { - const {path, root} = options; - - const preprocessLine = (lines: string[], start: number) => { - const hasIncludedCache = md && root && path; - const str = lines[start]; - const match = str?.match(INCLUDE_REGEXP); +const preprocessLine = ( + lines: string[], + start: number, + { + root, + path, + }: { + root?: string; + path?: string; + }, + md?: MarkdownItIncluded, +) => { + const hasIncludedCache = md && root && path; + const str = lines[start]; + const match = str?.match(INCLUDE_REGEXP); + + // Protect from unmatched results + if (!match) { + return false; + } - // Protect from unmatched results - if (!match) { - return false; - } + const includePathRelative = match[1]; - const includePathRelative = match[1]; + // Protect from empty path + if (!includePathRelative) { + return false; + } - // Protect from empty path - if (!includePathRelative) { - return false; + // Read all content from top to bottom(!) char of the included block + const data = []; + let line = start; + while (line < lines.length) { + line++; + const str = lines[line]; + if (str === null) { + break; } + if (str?.match(INCLUDE_END_REGEXP)) { + break; + } + data.push(str); + } - // Read all content from top to bottom(!) char of the included block - const data = []; - let line = start; - while (line < lines.length) { - line++; - const str = lines[line]; - if (str === null) { - break; - } - if (str?.match(INCLUDE_END_REGEXP)) { - break; - } - data.push(str); + // No included cache for lint mode + if (hasIncludedCache) { + if (!md.included) { + md.included = {}; } - // No included cache for lint mode - if (hasIncludedCache) { - if (!md.included) { - md.included = {}; - } + // Normalize the path to absolute + const includePath = getFullIncludePath(includePathRelative, root, path); + + // Store the included content + md.included[includePath] = data.join('\n'); + } - // Normalize the path to absolute - const includePath = getFullIncludePath(includePathRelative, root, path); + // Remove the content of the included file + lines.splice(start, data.length + 2); - // Store the included content - md.included[includePath] = data.join('\n'); - } + return true; +}; - // Remove the content of the included file - lines.splice(start, data.length + 2); - - return true; - }; - - const lines = input.split('\n') || []; - - // The finction reads the files from bottom to top(!). It stops the loop if it does not have anything to swap. - // If the function finds something to process then it restarts the loop because the position of the last element has been moved. - // eslint-disable-next-line no-unmodified-loop-condition - while (input?.length) { - let hasChars = false; - for (let line = lines.length - 1; line >= 0; line--) { - hasChars = preprocessLine(lines, line); - if (hasChars) { +const index: MarkdownItPreprocessorCb<{ + included?: boolean; +}> = (input, options, md?: MarkdownItIncluded) => { + const {included, path, root} = options; + + // To reduce file reading we can include the file content into the generated content + if (included) { + const lines = input.split('\n') || []; + + // The finction reads the files from bottom to top(!). It stops the loop if it does not have anything to swap. + // If the function finds something to process then it restarts the loop because the position of the last element has been moved. + // eslint-disable-next-line no-unmodified-loop-condition + while (input?.length) { + let hasChars = false; + for (let line = lines.length - 1; line >= 0; line--) { + hasChars = preprocessLine(lines, line, {path, root}, md); + if (hasChars) { + break; + } + } + if (!hasChars) { break; } } - if (!hasChars) { - break; - } - } - input = lines.join('\n'); + input = lines.join('\n'); + } return input; };