diff --git a/src/plugins/code-loader.js b/src/plugins/code-loader.js index a44f6932..f0398f65 100644 --- a/src/plugins/code-loader.js +++ b/src/plugins/code-loader.js @@ -1,27 +1,24 @@ -// Plugin to load code snippets from files and replace the CODE_LOAD tag with the content of the file - const fs = require('fs'); const fetch = require('node-fetch'); const plugin = (options) => { - const codeLoadRegex = /^CODE_LOAD::([^#]+)(?:#([^#]+)-([^#]+))?$/g; + const codeLoadRegex = /^CODE_LOAD::([^#?]+)(?:#([^#]+)-([^#]+))?(?:\?([^#]+))?$/g; const injectCode = async (str) => { let fileData = null; - str.replace(codeLoadRegex, (match, filePath, customStartTag, customEndTag) => { - console.info(`Loading code snippet from with optional custom tags: ${customStartTag} and ${customEndTag}`) - fileData = { filePath, customStartTag, customEndTag } + str.replace(codeLoadRegex, (match, filePath, customStartTag, customEndTag, markNumber) => { + fileData = { filePath, customStartTag, customEndTag, markNumber }; return match; }); - if(!fileData){ + if (!fileData) { return str; } const fileContent = await readFileOrFetch(fileData.filePath); - const data = extractAndClean(fileContent, fileData.customStartTag, fileData.customEndTag, fileData.filePath); + const data = extractAndClean(fileContent, fileData.customStartTag, fileData.customEndTag, fileData.markNumber, fileData.filePath); return str.replace(codeLoadRegex, () => data); - } + }; async function readFileOrFetch(filepath) { if (filepath.startsWith('https://raw.githubusercontent.com/')) { @@ -35,8 +32,7 @@ const plugin = (options) => { } } - function extractAndClean(fileContent, customStartTag, customEndTag, filePath){ - // If custom start and end tags are provided, check if they are present in the file, otherwise fail + function extractAndClean(fileContent, customStartTag, customEndTag, markNumber, filePath) { if (customStartTag && !fileContent.includes(customStartTag)) { throw new Error(`Custom start tag "${customStartTag}" not found in file ${filePath}`); } @@ -47,27 +43,54 @@ const plugin = (options) => { const startTag = customStartTag ?? ""; const endTag = customEndTag ?? ""; - // Split to only keep lines between "start_here" and "end_here" - const lines = fileContent.split(startTag).pop().split(endTag).shift(); + let lines = fileContent.split(startTag).pop().split(endTag).shift().split('\n').slice(1,-1); + let finalLines = []; + + if (markNumber) { + const markStartTag = `// `; + const markEndTag = `// `; + + let needToMark = false; + lines.forEach(function (line, index) { + if(line.includes(markStartTag)){ + if(needToMark){ + throw new Error(`Mark start tag found before mark end tag in file ${filePath}`) + } + needToMark = true; + } + if(line.includes(markEndTag)){ + if(!needToMark){ + throw new Error(`Mark end tag found before mark start tag in file ${filePath}`) + } + needToMark = false; + } + + if(!line.includes(' { + return !line.includes(' line.replace(new RegExp(`^${leadingWhitespace}`), '')) .join('\n'); } const transformer = async (ast) => { - const {visit} = await import('unist-util-visit') + const { visit } = await import('unist-util-visit'); const codes = []; await visit(ast, ['code', 'inlineCode'], (node) => { codes.push(node); @@ -81,4 +104,4 @@ const plugin = (options) => { return transformer; }; -module.exports = plugin; \ No newline at end of file +module.exports = plugin;