@diplodoc/transform
Version:
A simple transformer of text in YFM (Yandex Flavored Markdown) to HTML
76 lines • 2.92 kB
JavaScript
;
const utilsFS_1 = require("../../utilsFS");
const INCLUDE_REGEXP = /^\s*{%\s*included\s*\((.+?)\)\s*%}\s*$/;
const INCLUDE_END_REGEXP = /^\s*{% endincluded %}\s*$/;
const preprocessLine = (lines, start, { root, path, }, md) => {
const hasIncludedCache = md && root && path;
const str = lines[start];
const match = str === null || str === void 0 ? void 0 : str.match(INCLUDE_REGEXP);
// Protect from unmatched results
if (!match) {
return false;
}
const includePathKey = match[1];
// Protect from empty path
if (!includePathKey) {
return false;
}
const includePaths = includePathKey.split(':');
// 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 === null || str === void 0 ? void 0 : str.match(INCLUDE_END_REGEXP)) {
break;
}
data.push(str);
}
// No included cache for lint mode
if (hasIncludedCache) {
if (!md.included) {
md.included = {};
}
// Normalize the path to absolute
let includePath = (0, utilsFS_1.getFullIncludePath)(includePaths[0], root, path);
for (let index = 1; index < includePaths.length; index++) {
const pathname = includePaths[index];
includePath = (0, utilsFS_1.getFullIncludePath)(pathname, root, includePath);
}
// Store the included content
md.included[includePath] = data.join('\n');
}
// Remove the content of the included file
lines.splice(start, data.length + 2);
return true;
};
const index = (input, options, md) => {
const { included, path, root } = options;
// To reduce file reading we can include the file content into the generated content
if (included !== false) {
const lines = (input === null || input === void 0 ? void 0 : 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 === null || input === void 0 ? void 0 : 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;
}
}
input = lines.join('\n');
}
return input;
};
module.exports = index;
//# sourceMappingURL=index.js.map