diff --git a/dist/markdownItInclude.js b/dist/markdownItInclude.js index cd93e2d..368645c 100644 --- a/dist/markdownItInclude.js +++ b/dist/markdownItInclude.js @@ -73,7 +73,7 @@ const include_plugin = (md, options) => { } if (!errorMessage) { - filePath = path.resolve(rootdir, includePath); // check if child file exists or if there is a circular reference + filePath = path.resolve(includePath.indexOf('/') === 0 ? rootdir : parentFilePath ? path.dirname(parentFilePath) : rootdir, `./${includePath}`); // check if child file exists or if there is a circular reference if (!fs.existsSync(filePath)) { // child file does not exist @@ -95,7 +95,7 @@ const include_plugin = (md, options) => { // get content of child file mdSrc = fs.readFileSync(filePath, 'utf8'); // check if child file also has includes - mdSrc = _replaceIncludeByContent(mdSrc, path.dirname(filePath), filePath, filesProcessed); // remove one trailing newline, if it exists: that way, the included content does NOT + mdSrc = _replaceIncludeByContent(mdSrc, rootdir, filePath, filesProcessed); // remove one trailing newline, if it exists: that way, the included content does NOT // automatically terminate the paragraph it is in due to the writer of the included // part having terminated the content with a newline. // However, when that snippet writer terminated with TWO (or more) newlines, these, minus one, diff --git a/dist/markdownItInclude.js.map b/dist/markdownItInclude.js.map index 8940da3..e5a460f 100644 --- a/dist/markdownItInclude.js.map +++ b/dist/markdownItInclude.js.map @@ -1 +1 @@ -{"version":3,"file":"markdownItInclude.js","sources":["../index.js"],"sourcesContent":["\nconst path = require('path');\nconst fs = require('fs');\n\nconst INCLUDE_RE = /!{3}\\s*include(.+?)!{3}/i;\nconst BRACES_RE = /\\((.+?)\\)/i;\n\nconst include_plugin = (md, options) => {\n const defaultOptions = {\n root: '.',\n getRootDir: (pluginOptions/*, state, startLine, endLine*/) => pluginOptions.root,\n includeRe: INCLUDE_RE,\n throwError: true,\n bracesAreOptional: false,\n notFoundMessage: 'File \\'{{FILE}}\\' not found.',\n circularMessage: 'Circular reference between \\'{{FILE}}\\' and \\'{{PARENT}}\\'.'\n };\n\n if (typeof options === 'string') {\n options = {\n ...defaultOptions,\n root: options\n };\n } else {\n options = {\n ...defaultOptions,\n ...options\n };\n }\n\n const _replaceIncludeByContent = (src, rootdir, parentFilePath, filesProcessed) => {\n filesProcessed = filesProcessed ? filesProcessed.slice() : []; // making a copy\n let cap, filePath, mdSrc, errorMessage;\n\n // store parent file path to check circular references\n if (parentFilePath) {\n filesProcessed.push(parentFilePath);\n }\n while ((cap = options.includeRe.exec(src))) {\n let includePath = cap[1].trim();\n const sansBracesMatch = BRACES_RE.exec(includePath);\n\n if (!sansBracesMatch && !options.bracesAreOptional) {\n errorMessage = `INCLUDE statement '${src.trim()}' MUST have '()' braces around the include path ('${includePath}')`;\n } else if (sansBracesMatch) {\n includePath = sansBracesMatch[1].trim();\n } else if (!/^\\s/.test(cap[1])) {\n // path SHOULD have been preceeded by at least ONE whitespace character!\n /* eslint max-len: \"off\" */\n errorMessage = `INCLUDE statement '${src.trim()}': when not using braces around the path ('${includePath}'), it MUST be preceeded by at least one whitespace character to separate the include keyword and the include path.`;\n }\n\n if (!errorMessage) {\n filePath = path.resolve(rootdir, includePath);\n\n // check if child file exists or if there is a circular reference\n if (!fs.existsSync(filePath)) {\n // child file does not exist\n errorMessage = options.notFoundMessage.replace('{{FILE}}', filePath);\n } else if (filesProcessed.indexOf(filePath) !== -1) {\n // reference would be circular\n errorMessage = options.circularMessage.replace('{{FILE}}', filePath).replace('{{PARENT}}', parentFilePath);\n }\n }\n\n // check if there were any errors\n if (errorMessage) {\n if (options.throwError) {\n throw new Error(errorMessage);\n }\n mdSrc = `\\n\\n# INCLUDE ERROR: ${errorMessage}\\n\\n`;\n } else {\n // get content of child file\n mdSrc = fs.readFileSync(filePath, 'utf8');\n // check if child file also has includes\n mdSrc = _replaceIncludeByContent(mdSrc, path.dirname(filePath), filePath, filesProcessed);\n // remove one trailing newline, if it exists: that way, the included content does NOT\n // automatically terminate the paragraph it is in due to the writer of the included\n // part having terminated the content with a newline.\n // However, when that snippet writer terminated with TWO (or more) newlines, these, minus one,\n // will be merged with the newline after the #include statement, resulting in a 2-NL paragraph\n // termination.\n const len = mdSrc.length;\n if (mdSrc[len - 1] === '\\n') {\n mdSrc = mdSrc.substring(0, len - 1);\n }\n }\n\n // replace include by file content\n src = src.slice(0, cap.index) + mdSrc + src.slice(cap.index + cap[0].length, src.length);\n }\n return src;\n };\n\n const _includeFileParts = (state, startLine, endLine/*, silent*/) => {\n state.src = _replaceIncludeByContent(state.src, options.getRootDir(options, state, startLine, endLine));\n };\n\n md.core.ruler.before('normalize', 'include', _includeFileParts);\n};\n\nmodule.exports = include_plugin;\n"],"names":["path","require","fs","INCLUDE_RE","BRACES_RE","include_plugin","md","options","defaultOptions","root","getRootDir","pluginOptions","includeRe","throwError","bracesAreOptional","notFoundMessage","circularMessage","_replaceIncludeByContent","src","rootdir","parentFilePath","filesProcessed","slice","cap","filePath","mdSrc","errorMessage","push","exec","includePath","trim","sansBracesMatch","test","resolve","existsSync","replace","indexOf","Error","readFileSync","dirname","len","length","substring","index","_includeFileParts","state","startLine","endLine","core","ruler","before","module","exports"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"markdownItInclude.js","sources":["../index.js"],"sourcesContent":["\nconst path = require('path');\nconst fs = require('fs');\n\nconst INCLUDE_RE = /!{3}\\s*include(.+?)!{3}/i;\nconst BRACES_RE = /\\((.+?)\\)/i;\n\nconst include_plugin = (md, options) => {\n const defaultOptions = {\n root: '.',\n getRootDir: (pluginOptions/*, state, startLine, endLine*/) => pluginOptions.root,\n includeRe: INCLUDE_RE,\n throwError: true,\n bracesAreOptional: false,\n notFoundMessage: 'File \\'{{FILE}}\\' not found.',\n circularMessage: 'Circular reference between \\'{{FILE}}\\' and \\'{{PARENT}}\\'.'\n };\n\n if (typeof options === 'string') {\n options = {\n ...defaultOptions,\n root: options\n };\n } else {\n options = {\n ...defaultOptions,\n ...options\n };\n }\n\n const _replaceIncludeByContent = (src, rootdir, parentFilePath, filesProcessed) => {\n filesProcessed = filesProcessed ? filesProcessed.slice() : []; // making a copy\n let cap, filePath, mdSrc, errorMessage;\n\n // store parent file path to check circular references\n if (parentFilePath) {\n filesProcessed.push(parentFilePath);\n }\n while ((cap = options.includeRe.exec(src))) {\n let includePath = cap[1].trim();\n const sansBracesMatch = BRACES_RE.exec(includePath);\n\n if (!sansBracesMatch && !options.bracesAreOptional) {\n errorMessage = `INCLUDE statement '${src.trim()}' MUST have '()' braces around the include path ('${includePath}')`;\n } else if (sansBracesMatch) {\n includePath = sansBracesMatch[1].trim();\n } else if (!/^\\s/.test(cap[1])) {\n // path SHOULD have been preceeded by at least ONE whitespace character!\n /* eslint max-len: \"off\" */\n errorMessage = `INCLUDE statement '${src.trim()}': when not using braces around the path ('${includePath}'), it MUST be preceeded by at least one whitespace character to separate the include keyword and the include path.`;\n }\n\n if (!errorMessage) {\n filePath = path.resolve(includePath.indexOf('/') === 0\n ? rootdir\n : parentFilePath\n ? path.dirname(parentFilePath)\n : rootdir\n , `./${includePath}`);\n\n // check if child file exists or if there is a circular reference\n if (!fs.existsSync(filePath)) {\n // child file does not exist\n errorMessage = options.notFoundMessage.replace('{{FILE}}', filePath);\n } else if (filesProcessed.indexOf(filePath) !== -1) {\n // reference would be circular\n errorMessage = options.circularMessage.replace('{{FILE}}', filePath).replace('{{PARENT}}', parentFilePath);\n }\n }\n\n // check if there were any errors\n if (errorMessage) {\n if (options.throwError) {\n throw new Error(errorMessage);\n }\n mdSrc = `\\n\\n# INCLUDE ERROR: ${errorMessage}\\n\\n`;\n } else {\n // get content of child file\n mdSrc = fs.readFileSync(filePath, 'utf8');\n // check if child file also has includes\n mdSrc = _replaceIncludeByContent(mdSrc, rootdir, filePath, filesProcessed);\n // remove one trailing newline, if it exists: that way, the included content does NOT\n // automatically terminate the paragraph it is in due to the writer of the included\n // part having terminated the content with a newline.\n // However, when that snippet writer terminated with TWO (or more) newlines, these, minus one,\n // will be merged with the newline after the #include statement, resulting in a 2-NL paragraph\n // termination.\n const len = mdSrc.length;\n if (mdSrc[len - 1] === '\\n') {\n mdSrc = mdSrc.substring(0, len - 1);\n }\n }\n\n // replace include by file content\n src = src.slice(0, cap.index) + mdSrc + src.slice(cap.index + cap[0].length, src.length);\n }\n return src;\n };\n\n const _includeFileParts = (state, startLine, endLine/*, silent*/) => {\n state.src = _replaceIncludeByContent(state.src, options.getRootDir(options, state, startLine, endLine));\n };\n\n md.core.ruler.before('normalize', 'include', _includeFileParts);\n};\n\nmodule.exports = include_plugin;\n"],"names":["path","require","fs","INCLUDE_RE","BRACES_RE","include_plugin","md","options","defaultOptions","root","getRootDir","pluginOptions","includeRe","throwError","bracesAreOptional","notFoundMessage","circularMessage","_replaceIncludeByContent","src","rootdir","parentFilePath","filesProcessed","slice","cap","filePath","mdSrc","errorMessage","push","exec","includePath","trim","sansBracesMatch","test","resolve","indexOf","dirname","existsSync","replace","Error","readFileSync","len","length","substring","index","_includeFileParts","state","startLine","endLine","core","ruler","before","module","exports"],"mappings":"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"} \ No newline at end of file diff --git a/dist/markdownItInclude.mjs b/dist/markdownItInclude.mjs index e12e6dd..82c5335 100644 --- a/dist/markdownItInclude.mjs +++ b/dist/markdownItInclude.mjs @@ -71,7 +71,7 @@ const include_plugin = (md, options) => { } if (!errorMessage) { - filePath = path.resolve(rootdir, includePath); // check if child file exists or if there is a circular reference + filePath = path.resolve(includePath.indexOf('/') === 0 ? rootdir : parentFilePath ? path.dirname(parentFilePath) : rootdir, `./${includePath}`); // check if child file exists or if there is a circular reference if (!fs.existsSync(filePath)) { // child file does not exist @@ -93,7 +93,7 @@ const include_plugin = (md, options) => { // get content of child file mdSrc = fs.readFileSync(filePath, 'utf8'); // check if child file also has includes - mdSrc = _replaceIncludeByContent(mdSrc, path.dirname(filePath), filePath, filesProcessed); // remove one trailing newline, if it exists: that way, the included content does NOT + mdSrc = _replaceIncludeByContent(mdSrc, rootdir, filePath, filesProcessed); // remove one trailing newline, if it exists: that way, the included content does NOT // automatically terminate the paragraph it is in due to the writer of the included // part having terminated the content with a newline. // However, when that snippet writer terminated with TWO (or more) newlines, these, minus one, diff --git a/dist/markdownItInclude.mjs.map b/dist/markdownItInclude.mjs.map index 284fb61..8c3b8fc 100644 --- a/dist/markdownItInclude.mjs.map +++ b/dist/markdownItInclude.mjs.map @@ -1 +1 @@ -{"version":3,"file":"markdownItInclude.mjs","sources":["../index.js"],"sourcesContent":["\nconst path = require('path');\nconst fs = require('fs');\n\nconst INCLUDE_RE = /!{3}\\s*include(.+?)!{3}/i;\nconst BRACES_RE = /\\((.+?)\\)/i;\n\nconst include_plugin = (md, options) => {\n const defaultOptions = {\n root: '.',\n getRootDir: (pluginOptions/*, state, startLine, endLine*/) => pluginOptions.root,\n includeRe: INCLUDE_RE,\n throwError: true,\n bracesAreOptional: false,\n notFoundMessage: 'File \\'{{FILE}}\\' not found.',\n circularMessage: 'Circular reference between \\'{{FILE}}\\' and \\'{{PARENT}}\\'.'\n };\n\n if (typeof options === 'string') {\n options = {\n ...defaultOptions,\n root: options\n };\n } else {\n options = {\n ...defaultOptions,\n ...options\n };\n }\n\n const _replaceIncludeByContent = (src, rootdir, parentFilePath, filesProcessed) => {\n filesProcessed = filesProcessed ? filesProcessed.slice() : []; // making a copy\n let cap, filePath, mdSrc, errorMessage;\n\n // store parent file path to check circular references\n if (parentFilePath) {\n filesProcessed.push(parentFilePath);\n }\n while ((cap = options.includeRe.exec(src))) {\n let includePath = cap[1].trim();\n const sansBracesMatch = BRACES_RE.exec(includePath);\n\n if (!sansBracesMatch && !options.bracesAreOptional) {\n errorMessage = `INCLUDE statement '${src.trim()}' MUST have '()' braces around the include path ('${includePath}')`;\n } else if (sansBracesMatch) {\n includePath = sansBracesMatch[1].trim();\n } else if (!/^\\s/.test(cap[1])) {\n // path SHOULD have been preceeded by at least ONE whitespace character!\n /* eslint max-len: \"off\" */\n errorMessage = `INCLUDE statement '${src.trim()}': when not using braces around the path ('${includePath}'), it MUST be preceeded by at least one whitespace character to separate the include keyword and the include path.`;\n }\n\n if (!errorMessage) {\n filePath = path.resolve(rootdir, includePath);\n\n // check if child file exists or if there is a circular reference\n if (!fs.existsSync(filePath)) {\n // child file does not exist\n errorMessage = options.notFoundMessage.replace('{{FILE}}', filePath);\n } else if (filesProcessed.indexOf(filePath) !== -1) {\n // reference would be circular\n errorMessage = options.circularMessage.replace('{{FILE}}', filePath).replace('{{PARENT}}', parentFilePath);\n }\n }\n\n // check if there were any errors\n if (errorMessage) {\n if (options.throwError) {\n throw new Error(errorMessage);\n }\n mdSrc = `\\n\\n# INCLUDE ERROR: ${errorMessage}\\n\\n`;\n } else {\n // get content of child file\n mdSrc = fs.readFileSync(filePath, 'utf8');\n // check if child file also has includes\n mdSrc = _replaceIncludeByContent(mdSrc, path.dirname(filePath), filePath, filesProcessed);\n // remove one trailing newline, if it exists: that way, the included content does NOT\n // automatically terminate the paragraph it is in due to the writer of the included\n // part having terminated the content with a newline.\n // However, when that snippet writer terminated with TWO (or more) newlines, these, minus one,\n // will be merged with the newline after the #include statement, resulting in a 2-NL paragraph\n // termination.\n const len = mdSrc.length;\n if (mdSrc[len - 1] === '\\n') {\n mdSrc = mdSrc.substring(0, len - 1);\n }\n }\n\n // replace include by file content\n src = src.slice(0, cap.index) + mdSrc + src.slice(cap.index + cap[0].length, src.length);\n }\n return src;\n };\n\n const _includeFileParts = (state, startLine, endLine/*, silent*/) => {\n state.src = _replaceIncludeByContent(state.src, options.getRootDir(options, state, startLine, endLine));\n };\n\n md.core.ruler.before('normalize', 'include', _includeFileParts);\n};\n\nmodule.exports = include_plugin;\n"],"names":["path","require","fs","INCLUDE_RE","BRACES_RE","include_plugin","md","options","defaultOptions","root","getRootDir","pluginOptions","includeRe","throwError","bracesAreOptional","notFoundMessage","circularMessage","_replaceIncludeByContent","src","rootdir","parentFilePath","filesProcessed","slice","cap","filePath","mdSrc","errorMessage","push","exec","includePath","trim","sansBracesMatch","test","resolve","existsSync","replace","indexOf","Error","readFileSync","dirname","len","length","substring","index","_includeFileParts","state","startLine","endLine","core","ruler","before","module","exports"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"markdownItInclude.mjs","sources":["../index.js"],"sourcesContent":["\nconst path = require('path');\nconst fs = require('fs');\n\nconst INCLUDE_RE = /!{3}\\s*include(.+?)!{3}/i;\nconst BRACES_RE = /\\((.+?)\\)/i;\n\nconst include_plugin = (md, options) => {\n const defaultOptions = {\n root: '.',\n getRootDir: (pluginOptions/*, state, startLine, endLine*/) => pluginOptions.root,\n includeRe: INCLUDE_RE,\n throwError: true,\n bracesAreOptional: false,\n notFoundMessage: 'File \\'{{FILE}}\\' not found.',\n circularMessage: 'Circular reference between \\'{{FILE}}\\' and \\'{{PARENT}}\\'.'\n };\n\n if (typeof options === 'string') {\n options = {\n ...defaultOptions,\n root: options\n };\n } else {\n options = {\n ...defaultOptions,\n ...options\n };\n }\n\n const _replaceIncludeByContent = (src, rootdir, parentFilePath, filesProcessed) => {\n filesProcessed = filesProcessed ? filesProcessed.slice() : []; // making a copy\n let cap, filePath, mdSrc, errorMessage;\n\n // store parent file path to check circular references\n if (parentFilePath) {\n filesProcessed.push(parentFilePath);\n }\n while ((cap = options.includeRe.exec(src))) {\n let includePath = cap[1].trim();\n const sansBracesMatch = BRACES_RE.exec(includePath);\n\n if (!sansBracesMatch && !options.bracesAreOptional) {\n errorMessage = `INCLUDE statement '${src.trim()}' MUST have '()' braces around the include path ('${includePath}')`;\n } else if (sansBracesMatch) {\n includePath = sansBracesMatch[1].trim();\n } else if (!/^\\s/.test(cap[1])) {\n // path SHOULD have been preceeded by at least ONE whitespace character!\n /* eslint max-len: \"off\" */\n errorMessage = `INCLUDE statement '${src.trim()}': when not using braces around the path ('${includePath}'), it MUST be preceeded by at least one whitespace character to separate the include keyword and the include path.`;\n }\n\n if (!errorMessage) {\n filePath = path.resolve(includePath.indexOf('/') === 0\n ? rootdir\n : parentFilePath\n ? path.dirname(parentFilePath)\n : rootdir\n , `./${includePath}`);\n\n // check if child file exists or if there is a circular reference\n if (!fs.existsSync(filePath)) {\n // child file does not exist\n errorMessage = options.notFoundMessage.replace('{{FILE}}', filePath);\n } else if (filesProcessed.indexOf(filePath) !== -1) {\n // reference would be circular\n errorMessage = options.circularMessage.replace('{{FILE}}', filePath).replace('{{PARENT}}', parentFilePath);\n }\n }\n\n // check if there were any errors\n if (errorMessage) {\n if (options.throwError) {\n throw new Error(errorMessage);\n }\n mdSrc = `\\n\\n# INCLUDE ERROR: ${errorMessage}\\n\\n`;\n } else {\n // get content of child file\n mdSrc = fs.readFileSync(filePath, 'utf8');\n // check if child file also has includes\n mdSrc = _replaceIncludeByContent(mdSrc, rootdir, filePath, filesProcessed);\n // remove one trailing newline, if it exists: that way, the included content does NOT\n // automatically terminate the paragraph it is in due to the writer of the included\n // part having terminated the content with a newline.\n // However, when that snippet writer terminated with TWO (or more) newlines, these, minus one,\n // will be merged with the newline after the #include statement, resulting in a 2-NL paragraph\n // termination.\n const len = mdSrc.length;\n if (mdSrc[len - 1] === '\\n') {\n mdSrc = mdSrc.substring(0, len - 1);\n }\n }\n\n // replace include by file content\n src = src.slice(0, cap.index) + mdSrc + src.slice(cap.index + cap[0].length, src.length);\n }\n return src;\n };\n\n const _includeFileParts = (state, startLine, endLine/*, silent*/) => {\n state.src = _replaceIncludeByContent(state.src, options.getRootDir(options, state, startLine, endLine));\n };\n\n md.core.ruler.before('normalize', 'include', _includeFileParts);\n};\n\nmodule.exports = include_plugin;\n"],"names":["path","require","fs","INCLUDE_RE","BRACES_RE","include_plugin","md","options","defaultOptions","root","getRootDir","pluginOptions","includeRe","throwError","bracesAreOptional","notFoundMessage","circularMessage","_replaceIncludeByContent","src","rootdir","parentFilePath","filesProcessed","slice","cap","filePath","mdSrc","errorMessage","push","exec","includePath","trim","sansBracesMatch","test","resolve","indexOf","dirname","existsSync","replace","Error","readFileSync","len","length","substring","index","_includeFileParts","state","startLine","endLine","core","ruler","before","module","exports"],"mappings":"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"} \ No newline at end of file diff --git a/dist/markdownItInclude.modern.js b/dist/markdownItInclude.modern.js index f26de17..f013b5b 100644 --- a/dist/markdownItInclude.modern.js +++ b/dist/markdownItInclude.modern.js @@ -55,7 +55,7 @@ const include_plugin = (md, options) => { } if (!errorMessage) { - filePath = path.resolve(rootdir, includePath); // check if child file exists or if there is a circular reference + filePath = path.resolve(includePath.indexOf('/') === 0 ? rootdir : parentFilePath ? path.dirname(parentFilePath) : rootdir, `./${includePath}`); // check if child file exists or if there is a circular reference if (!fs.existsSync(filePath)) { // child file does not exist @@ -77,7 +77,7 @@ const include_plugin = (md, options) => { // get content of child file mdSrc = fs.readFileSync(filePath, 'utf8'); // check if child file also has includes - mdSrc = _replaceIncludeByContent(mdSrc, path.dirname(filePath), filePath, filesProcessed); // remove one trailing newline, if it exists: that way, the included content does NOT + mdSrc = _replaceIncludeByContent(mdSrc, rootdir, filePath, filesProcessed); // remove one trailing newline, if it exists: that way, the included content does NOT // automatically terminate the paragraph it is in due to the writer of the included // part having terminated the content with a newline. // However, when that snippet writer terminated with TWO (or more) newlines, these, minus one, diff --git a/dist/markdownItInclude.modern.js.map b/dist/markdownItInclude.modern.js.map index 83b40dd..9427eef 100644 --- a/dist/markdownItInclude.modern.js.map +++ b/dist/markdownItInclude.modern.js.map @@ -1 +1 @@ -{"version":3,"file":"markdownItInclude.modern.js","sources":["../index.js"],"sourcesContent":["\nconst path = require('path');\nconst fs = require('fs');\n\nconst INCLUDE_RE = /!{3}\\s*include(.+?)!{3}/i;\nconst BRACES_RE = /\\((.+?)\\)/i;\n\nconst include_plugin = (md, options) => {\n const defaultOptions = {\n root: '.',\n getRootDir: (pluginOptions/*, state, startLine, endLine*/) => pluginOptions.root,\n includeRe: INCLUDE_RE,\n throwError: true,\n bracesAreOptional: false,\n notFoundMessage: 'File \\'{{FILE}}\\' not found.',\n circularMessage: 'Circular reference between \\'{{FILE}}\\' and \\'{{PARENT}}\\'.'\n };\n\n if (typeof options === 'string') {\n options = {\n ...defaultOptions,\n root: options\n };\n } else {\n options = {\n ...defaultOptions,\n ...options\n };\n }\n\n const _replaceIncludeByContent = (src, rootdir, parentFilePath, filesProcessed) => {\n filesProcessed = filesProcessed ? filesProcessed.slice() : []; // making a copy\n let cap, filePath, mdSrc, errorMessage;\n\n // store parent file path to check circular references\n if (parentFilePath) {\n filesProcessed.push(parentFilePath);\n }\n while ((cap = options.includeRe.exec(src))) {\n let includePath = cap[1].trim();\n const sansBracesMatch = BRACES_RE.exec(includePath);\n\n if (!sansBracesMatch && !options.bracesAreOptional) {\n errorMessage = `INCLUDE statement '${src.trim()}' MUST have '()' braces around the include path ('${includePath}')`;\n } else if (sansBracesMatch) {\n includePath = sansBracesMatch[1].trim();\n } else if (!/^\\s/.test(cap[1])) {\n // path SHOULD have been preceeded by at least ONE whitespace character!\n /* eslint max-len: \"off\" */\n errorMessage = `INCLUDE statement '${src.trim()}': when not using braces around the path ('${includePath}'), it MUST be preceeded by at least one whitespace character to separate the include keyword and the include path.`;\n }\n\n if (!errorMessage) {\n filePath = path.resolve(rootdir, includePath);\n\n // check if child file exists or if there is a circular reference\n if (!fs.existsSync(filePath)) {\n // child file does not exist\n errorMessage = options.notFoundMessage.replace('{{FILE}}', filePath);\n } else if (filesProcessed.indexOf(filePath) !== -1) {\n // reference would be circular\n errorMessage = options.circularMessage.replace('{{FILE}}', filePath).replace('{{PARENT}}', parentFilePath);\n }\n }\n\n // check if there were any errors\n if (errorMessage) {\n if (options.throwError) {\n throw new Error(errorMessage);\n }\n mdSrc = `\\n\\n# INCLUDE ERROR: ${errorMessage}\\n\\n`;\n } else {\n // get content of child file\n mdSrc = fs.readFileSync(filePath, 'utf8');\n // check if child file also has includes\n mdSrc = _replaceIncludeByContent(mdSrc, path.dirname(filePath), filePath, filesProcessed);\n // remove one trailing newline, if it exists: that way, the included content does NOT\n // automatically terminate the paragraph it is in due to the writer of the included\n // part having terminated the content with a newline.\n // However, when that snippet writer terminated with TWO (or more) newlines, these, minus one,\n // will be merged with the newline after the #include statement, resulting in a 2-NL paragraph\n // termination.\n const len = mdSrc.length;\n if (mdSrc[len - 1] === '\\n') {\n mdSrc = mdSrc.substring(0, len - 1);\n }\n }\n\n // replace include by file content\n src = src.slice(0, cap.index) + mdSrc + src.slice(cap.index + cap[0].length, src.length);\n }\n return src;\n };\n\n const _includeFileParts = (state, startLine, endLine/*, silent*/) => {\n state.src = _replaceIncludeByContent(state.src, options.getRootDir(options, state, startLine, endLine));\n };\n\n md.core.ruler.before('normalize', 'include', _includeFileParts);\n};\n\nmodule.exports = include_plugin;\n"],"names":["path","require","fs","INCLUDE_RE","BRACES_RE","include_plugin","md","options","defaultOptions","root","getRootDir","pluginOptions","includeRe","throwError","bracesAreOptional","notFoundMessage","circularMessage","_replaceIncludeByContent","src","rootdir","parentFilePath","filesProcessed","slice","cap","filePath","mdSrc","errorMessage","push","exec","includePath","trim","sansBracesMatch","test","resolve","existsSync","replace","indexOf","Error","readFileSync","dirname","len","length","substring","index","_includeFileParts","state","startLine","endLine","core","ruler","before","module","exports"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"markdownItInclude.modern.js","sources":["../index.js"],"sourcesContent":["\nconst path = require('path');\nconst fs = require('fs');\n\nconst INCLUDE_RE = /!{3}\\s*include(.+?)!{3}/i;\nconst BRACES_RE = /\\((.+?)\\)/i;\n\nconst include_plugin = (md, options) => {\n const defaultOptions = {\n root: '.',\n getRootDir: (pluginOptions/*, state, startLine, endLine*/) => pluginOptions.root,\n includeRe: INCLUDE_RE,\n throwError: true,\n bracesAreOptional: false,\n notFoundMessage: 'File \\'{{FILE}}\\' not found.',\n circularMessage: 'Circular reference between \\'{{FILE}}\\' and \\'{{PARENT}}\\'.'\n };\n\n if (typeof options === 'string') {\n options = {\n ...defaultOptions,\n root: options\n };\n } else {\n options = {\n ...defaultOptions,\n ...options\n };\n }\n\n const _replaceIncludeByContent = (src, rootdir, parentFilePath, filesProcessed) => {\n filesProcessed = filesProcessed ? filesProcessed.slice() : []; // making a copy\n let cap, filePath, mdSrc, errorMessage;\n\n // store parent file path to check circular references\n if (parentFilePath) {\n filesProcessed.push(parentFilePath);\n }\n while ((cap = options.includeRe.exec(src))) {\n let includePath = cap[1].trim();\n const sansBracesMatch = BRACES_RE.exec(includePath);\n\n if (!sansBracesMatch && !options.bracesAreOptional) {\n errorMessage = `INCLUDE statement '${src.trim()}' MUST have '()' braces around the include path ('${includePath}')`;\n } else if (sansBracesMatch) {\n includePath = sansBracesMatch[1].trim();\n } else if (!/^\\s/.test(cap[1])) {\n // path SHOULD have been preceeded by at least ONE whitespace character!\n /* eslint max-len: \"off\" */\n errorMessage = `INCLUDE statement '${src.trim()}': when not using braces around the path ('${includePath}'), it MUST be preceeded by at least one whitespace character to separate the include keyword and the include path.`;\n }\n\n if (!errorMessage) {\n filePath = path.resolve(includePath.indexOf('/') === 0\n ? rootdir\n : parentFilePath\n ? path.dirname(parentFilePath)\n : rootdir\n , `./${includePath}`);\n\n // check if child file exists or if there is a circular reference\n if (!fs.existsSync(filePath)) {\n // child file does not exist\n errorMessage = options.notFoundMessage.replace('{{FILE}}', filePath);\n } else if (filesProcessed.indexOf(filePath) !== -1) {\n // reference would be circular\n errorMessage = options.circularMessage.replace('{{FILE}}', filePath).replace('{{PARENT}}', parentFilePath);\n }\n }\n\n // check if there were any errors\n if (errorMessage) {\n if (options.throwError) {\n throw new Error(errorMessage);\n }\n mdSrc = `\\n\\n# INCLUDE ERROR: ${errorMessage}\\n\\n`;\n } else {\n // get content of child file\n mdSrc = fs.readFileSync(filePath, 'utf8');\n // check if child file also has includes\n mdSrc = _replaceIncludeByContent(mdSrc, rootdir, filePath, filesProcessed);\n // remove one trailing newline, if it exists: that way, the included content does NOT\n // automatically terminate the paragraph it is in due to the writer of the included\n // part having terminated the content with a newline.\n // However, when that snippet writer terminated with TWO (or more) newlines, these, minus one,\n // will be merged with the newline after the #include statement, resulting in a 2-NL paragraph\n // termination.\n const len = mdSrc.length;\n if (mdSrc[len - 1] === '\\n') {\n mdSrc = mdSrc.substring(0, len - 1);\n }\n }\n\n // replace include by file content\n src = src.slice(0, cap.index) + mdSrc + src.slice(cap.index + cap[0].length, src.length);\n }\n return src;\n };\n\n const _includeFileParts = (state, startLine, endLine/*, silent*/) => {\n state.src = _replaceIncludeByContent(state.src, options.getRootDir(options, state, startLine, endLine));\n };\n\n md.core.ruler.before('normalize', 'include', _includeFileParts);\n};\n\nmodule.exports = include_plugin;\n"],"names":["path","require","fs","INCLUDE_RE","BRACES_RE","include_plugin","md","options","defaultOptions","root","getRootDir","pluginOptions","includeRe","throwError","bracesAreOptional","notFoundMessage","circularMessage","_replaceIncludeByContent","src","rootdir","parentFilePath","filesProcessed","slice","cap","filePath","mdSrc","errorMessage","push","exec","includePath","trim","sansBracesMatch","test","resolve","indexOf","dirname","existsSync","replace","Error","readFileSync","len","length","substring","index","_includeFileParts","state","startLine","endLine","core","ruler","before","module","exports"],"mappings":"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"} \ No newline at end of file diff --git a/dist/markdownItInclude.umd.js b/dist/markdownItInclude.umd.js index 23de2b3..5292992 100644 --- a/dist/markdownItInclude.umd.js +++ b/dist/markdownItInclude.umd.js @@ -76,7 +76,7 @@ } if (!errorMessage) { - filePath = path.resolve(rootdir, includePath); // check if child file exists or if there is a circular reference + filePath = path.resolve(includePath.indexOf('/') === 0 ? rootdir : parentFilePath ? path.dirname(parentFilePath) : rootdir, `./${includePath}`); // check if child file exists or if there is a circular reference if (!fs.existsSync(filePath)) { // child file does not exist @@ -98,7 +98,7 @@ // get content of child file mdSrc = fs.readFileSync(filePath, 'utf8'); // check if child file also has includes - mdSrc = _replaceIncludeByContent(mdSrc, path.dirname(filePath), filePath, filesProcessed); // remove one trailing newline, if it exists: that way, the included content does NOT + mdSrc = _replaceIncludeByContent(mdSrc, rootdir, filePath, filesProcessed); // remove one trailing newline, if it exists: that way, the included content does NOT // automatically terminate the paragraph it is in due to the writer of the included // part having terminated the content with a newline. // However, when that snippet writer terminated with TWO (or more) newlines, these, minus one, diff --git a/dist/markdownItInclude.umd.js.map b/dist/markdownItInclude.umd.js.map index 4af9ce2..03aea34 100644 --- a/dist/markdownItInclude.umd.js.map +++ b/dist/markdownItInclude.umd.js.map @@ -1 +1 @@ -{"version":3,"file":"markdownItInclude.umd.js","sources":["../index.js"],"sourcesContent":["\nconst path = require('path');\nconst fs = require('fs');\n\nconst INCLUDE_RE = /!{3}\\s*include(.+?)!{3}/i;\nconst BRACES_RE = /\\((.+?)\\)/i;\n\nconst include_plugin = (md, options) => {\n const defaultOptions = {\n root: '.',\n getRootDir: (pluginOptions/*, state, startLine, endLine*/) => pluginOptions.root,\n includeRe: INCLUDE_RE,\n throwError: true,\n bracesAreOptional: false,\n notFoundMessage: 'File \\'{{FILE}}\\' not found.',\n circularMessage: 'Circular reference between \\'{{FILE}}\\' and \\'{{PARENT}}\\'.'\n };\n\n if (typeof options === 'string') {\n options = {\n ...defaultOptions,\n root: options\n };\n } else {\n options = {\n ...defaultOptions,\n ...options\n };\n }\n\n const _replaceIncludeByContent = (src, rootdir, parentFilePath, filesProcessed) => {\n filesProcessed = filesProcessed ? filesProcessed.slice() : []; // making a copy\n let cap, filePath, mdSrc, errorMessage;\n\n // store parent file path to check circular references\n if (parentFilePath) {\n filesProcessed.push(parentFilePath);\n }\n while ((cap = options.includeRe.exec(src))) {\n let includePath = cap[1].trim();\n const sansBracesMatch = BRACES_RE.exec(includePath);\n\n if (!sansBracesMatch && !options.bracesAreOptional) {\n errorMessage = `INCLUDE statement '${src.trim()}' MUST have '()' braces around the include path ('${includePath}')`;\n } else if (sansBracesMatch) {\n includePath = sansBracesMatch[1].trim();\n } else if (!/^\\s/.test(cap[1])) {\n // path SHOULD have been preceeded by at least ONE whitespace character!\n /* eslint max-len: \"off\" */\n errorMessage = `INCLUDE statement '${src.trim()}': when not using braces around the path ('${includePath}'), it MUST be preceeded by at least one whitespace character to separate the include keyword and the include path.`;\n }\n\n if (!errorMessage) {\n filePath = path.resolve(rootdir, includePath);\n\n // check if child file exists or if there is a circular reference\n if (!fs.existsSync(filePath)) {\n // child file does not exist\n errorMessage = options.notFoundMessage.replace('{{FILE}}', filePath);\n } else if (filesProcessed.indexOf(filePath) !== -1) {\n // reference would be circular\n errorMessage = options.circularMessage.replace('{{FILE}}', filePath).replace('{{PARENT}}', parentFilePath);\n }\n }\n\n // check if there were any errors\n if (errorMessage) {\n if (options.throwError) {\n throw new Error(errorMessage);\n }\n mdSrc = `\\n\\n# INCLUDE ERROR: ${errorMessage}\\n\\n`;\n } else {\n // get content of child file\n mdSrc = fs.readFileSync(filePath, 'utf8');\n // check if child file also has includes\n mdSrc = _replaceIncludeByContent(mdSrc, path.dirname(filePath), filePath, filesProcessed);\n // remove one trailing newline, if it exists: that way, the included content does NOT\n // automatically terminate the paragraph it is in due to the writer of the included\n // part having terminated the content with a newline.\n // However, when that snippet writer terminated with TWO (or more) newlines, these, minus one,\n // will be merged with the newline after the #include statement, resulting in a 2-NL paragraph\n // termination.\n const len = mdSrc.length;\n if (mdSrc[len - 1] === '\\n') {\n mdSrc = mdSrc.substring(0, len - 1);\n }\n }\n\n // replace include by file content\n src = src.slice(0, cap.index) + mdSrc + src.slice(cap.index + cap[0].length, src.length);\n }\n return src;\n };\n\n const _includeFileParts = (state, startLine, endLine/*, silent*/) => {\n state.src = _replaceIncludeByContent(state.src, options.getRootDir(options, state, startLine, endLine));\n };\n\n md.core.ruler.before('normalize', 'include', _includeFileParts);\n};\n\nmodule.exports = include_plugin;\n"],"names":["path","require","fs","INCLUDE_RE","BRACES_RE","include_plugin","md","options","defaultOptions","root","getRootDir","pluginOptions","includeRe","throwError","bracesAreOptional","notFoundMessage","circularMessage","_replaceIncludeByContent","src","rootdir","parentFilePath","filesProcessed","slice","cap","filePath","mdSrc","errorMessage","push","exec","includePath","trim","sansBracesMatch","test","resolve","existsSync","replace","indexOf","Error","readFileSync","dirname","len","length","substring","index","_includeFileParts","state","startLine","endLine","core","ruler","before","module","exports"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"markdownItInclude.umd.js","sources":["../index.js"],"sourcesContent":["\nconst path = require('path');\nconst fs = require('fs');\n\nconst INCLUDE_RE = /!{3}\\s*include(.+?)!{3}/i;\nconst BRACES_RE = /\\((.+?)\\)/i;\n\nconst include_plugin = (md, options) => {\n const defaultOptions = {\n root: '.',\n getRootDir: (pluginOptions/*, state, startLine, endLine*/) => pluginOptions.root,\n includeRe: INCLUDE_RE,\n throwError: true,\n bracesAreOptional: false,\n notFoundMessage: 'File \\'{{FILE}}\\' not found.',\n circularMessage: 'Circular reference between \\'{{FILE}}\\' and \\'{{PARENT}}\\'.'\n };\n\n if (typeof options === 'string') {\n options = {\n ...defaultOptions,\n root: options\n };\n } else {\n options = {\n ...defaultOptions,\n ...options\n };\n }\n\n const _replaceIncludeByContent = (src, rootdir, parentFilePath, filesProcessed) => {\n filesProcessed = filesProcessed ? filesProcessed.slice() : []; // making a copy\n let cap, filePath, mdSrc, errorMessage;\n\n // store parent file path to check circular references\n if (parentFilePath) {\n filesProcessed.push(parentFilePath);\n }\n while ((cap = options.includeRe.exec(src))) {\n let includePath = cap[1].trim();\n const sansBracesMatch = BRACES_RE.exec(includePath);\n\n if (!sansBracesMatch && !options.bracesAreOptional) {\n errorMessage = `INCLUDE statement '${src.trim()}' MUST have '()' braces around the include path ('${includePath}')`;\n } else if (sansBracesMatch) {\n includePath = sansBracesMatch[1].trim();\n } else if (!/^\\s/.test(cap[1])) {\n // path SHOULD have been preceeded by at least ONE whitespace character!\n /* eslint max-len: \"off\" */\n errorMessage = `INCLUDE statement '${src.trim()}': when not using braces around the path ('${includePath}'), it MUST be preceeded by at least one whitespace character to separate the include keyword and the include path.`;\n }\n\n if (!errorMessage) {\n filePath = path.resolve(includePath.indexOf('/') === 0\n ? rootdir\n : parentFilePath\n ? path.dirname(parentFilePath)\n : rootdir\n , `./${includePath}`);\n\n // check if child file exists or if there is a circular reference\n if (!fs.existsSync(filePath)) {\n // child file does not exist\n errorMessage = options.notFoundMessage.replace('{{FILE}}', filePath);\n } else if (filesProcessed.indexOf(filePath) !== -1) {\n // reference would be circular\n errorMessage = options.circularMessage.replace('{{FILE}}', filePath).replace('{{PARENT}}', parentFilePath);\n }\n }\n\n // check if there were any errors\n if (errorMessage) {\n if (options.throwError) {\n throw new Error(errorMessage);\n }\n mdSrc = `\\n\\n# INCLUDE ERROR: ${errorMessage}\\n\\n`;\n } else {\n // get content of child file\n mdSrc = fs.readFileSync(filePath, 'utf8');\n // check if child file also has includes\n mdSrc = _replaceIncludeByContent(mdSrc, rootdir, filePath, filesProcessed);\n // remove one trailing newline, if it exists: that way, the included content does NOT\n // automatically terminate the paragraph it is in due to the writer of the included\n // part having terminated the content with a newline.\n // However, when that snippet writer terminated with TWO (or more) newlines, these, minus one,\n // will be merged with the newline after the #include statement, resulting in a 2-NL paragraph\n // termination.\n const len = mdSrc.length;\n if (mdSrc[len - 1] === '\\n') {\n mdSrc = mdSrc.substring(0, len - 1);\n }\n }\n\n // replace include by file content\n src = src.slice(0, cap.index) + mdSrc + src.slice(cap.index + cap[0].length, src.length);\n }\n return src;\n };\n\n const _includeFileParts = (state, startLine, endLine/*, silent*/) => {\n state.src = _replaceIncludeByContent(state.src, options.getRootDir(options, state, startLine, endLine));\n };\n\n md.core.ruler.before('normalize', 'include', _includeFileParts);\n};\n\nmodule.exports = include_plugin;\n"],"names":["path","require","fs","INCLUDE_RE","BRACES_RE","include_plugin","md","options","defaultOptions","root","getRootDir","pluginOptions","includeRe","throwError","bracesAreOptional","notFoundMessage","circularMessage","_replaceIncludeByContent","src","rootdir","parentFilePath","filesProcessed","slice","cap","filePath","mdSrc","errorMessage","push","exec","includePath","trim","sansBracesMatch","test","resolve","indexOf","dirname","existsSync","replace","Error","readFileSync","len","length","substring","index","_includeFileParts","state","startLine","endLine","core","ruler","before","module","exports"],"mappings":"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"} \ No newline at end of file diff --git a/index.js b/index.js index d72dbed..6529c34 100644 --- a/index.js +++ b/index.js @@ -51,7 +51,12 @@ const include_plugin = (md, options) => { } if (!errorMessage) { - filePath = path.resolve(rootdir, includePath); + filePath = path.resolve(includePath.indexOf('/') === 0 + ? rootdir + : parentFilePath + ? path.dirname(parentFilePath) + : rootdir + , `./${includePath}`); // check if child file exists or if there is a circular reference if (!fs.existsSync(filePath)) { @@ -73,7 +78,7 @@ const include_plugin = (md, options) => { // get content of child file mdSrc = fs.readFileSync(filePath, 'utf8'); // check if child file also has includes - mdSrc = _replaceIncludeByContent(mdSrc, path.dirname(filePath), filePath, filesProcessed); + mdSrc = _replaceIncludeByContent(mdSrc, rootdir, filePath, filesProcessed); // remove one trailing newline, if it exists: that way, the included content does NOT // automatically terminate the paragraph it is in due to the writer of the included // part having terminated the content with a newline. diff --git a/test/default.js b/test/default.js index 3f12a55..3eca3ad 100644 --- a/test/default.js +++ b/test/default.js @@ -27,6 +27,14 @@ describe('plugin', () => { '

a content\na content

\n'); }); + it ('absolute root path reference', () => { + const md = markdown() + .use(markdown_it_include, fixturesPath); + + assert.equal(md.render('!!! include( L1/L2/r.md ) !!!'), + '

a content

\n'); + }); + it ('default options', () => { let md = markdown() .use(markdown_it_include); diff --git a/test/fixtures/L1/L2/r.md b/test/fixtures/L1/L2/r.md new file mode 100644 index 0000000..2d5acf0 --- /dev/null +++ b/test/fixtures/L1/L2/r.md @@ -0,0 +1 @@ +!!!include(/a.md)!!!