UNPKG

@diplodoc/transform

Version:

A simple transformer of text in YFM (Yandex Flavored Markdown) to HTML

174 lines 6.72 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; const chalk_1 = require("chalk"); const log_1 = require("../log"); const evaluation_1 = __importDefault(require("./evaluation")); const lexical_1 = require("./lexical"); const utils_1 = require("./utils"); const sourceMap_1 = require("./sourceMap"); function changeSourceMap({ firstLineNumber, lastLineNumber, resFirstLineNumber, resLastLineNumber, linesTotal, sourceMap, }) { if (!sourceMap) { return; } const { getSourceMapValue, moveLines, removeLines } = (0, sourceMap_1.createSourceMapApi)(sourceMap); let offsetRestLines; if (resFirstLineNumber) { // Move condition's content to the top const offsetContentLines = firstLineNumber - resFirstLineNumber; moveLines({ start: resFirstLineNumber, end: resLastLineNumber - 1, offset: offsetContentLines, withReplace: true, }); // Remove the rest lines of the condition block removeLines({ start: firstLineNumber, end: resFirstLineNumber - 1 }); removeLines({ start: resLastLineNumber, end: lastLineNumber }); // Calculate an offset of the rest lines offsetRestLines = getSourceMapValue(resLastLineNumber - 1) - lastLineNumber; } else { // Remove the whole condition block removeLines({ start: firstLineNumber, end: lastLineNumber }); // Calculate offset of the rest lines offsetRestLines = firstLineNumber - lastLineNumber - 1; } // Offset the rest lines moveLines({ start: lastLineNumber + 1, end: linesTotal, offset: offsetRestLines }); } function getElseProp({ elses }, propName, index = 0) { if (!elses.length || index >= elses.length) { return undefined; } return elses[index][propName]; } function inlineConditions({ ifTag, vars, content, match, lastIndex, sourceMap, linesTotal }) { let res = ''; const firstLineNumber = (0, sourceMap_1.getLineNumber)(content, ifTag.startPos); const lastLineNumber = (0, sourceMap_1.getLineNumber)(content, lastIndex); let resFirstLineNumber = 0; let resLastLineNumber = 0; if ((0, evaluation_1.default)(ifTag.condition, vars)) { const ifRawLastIndex = ifTag.startPos + ifTag.ifRaw.length; const contentLastIndex = getElseProp(ifTag, 'startPos') || match.index; res = content.substring(ifRawLastIndex, contentLastIndex); resFirstLineNumber = (0, sourceMap_1.getLineNumber)(content, ifRawLastIndex + 1); resLastLineNumber = (0, sourceMap_1.getLineNumber)(content, contentLastIndex + 1); } else { ifTag.elses.some(({ condition, startPos, raw }, index) => { const isTruthy = !condition || (0, evaluation_1.default)(condition, vars); if (isTruthy) { const elseRawLastIndex = startPos + raw.length; const contentLastIndex = getElseProp(ifTag, 'startPos', index + 1) || match.index; res = content.substring(elseRawLastIndex, contentLastIndex); resFirstLineNumber = (0, sourceMap_1.getLineNumber)(content, elseRawLastIndex + 1); resLastLineNumber = (0, sourceMap_1.getLineNumber)(content, contentLastIndex + 1); return true; } return false; }); } changeSourceMap({ firstLineNumber, lastLineNumber, resFirstLineNumber, resLastLineNumber, linesTotal, sourceMap, }); const preparedLeftContent = (0, utils_1.getPreparedLeftContent)({ content, tagStartPos: ifTag.startPos, tagContent: res, }); let shift = 0; if (res === '' && preparedLeftContent[preparedLeftContent.length - 1] === '\n' && content[lastIndex] === '\n') { shift = 1; } if (res !== '') { if (res[0] === '\n') { res = res.substring(1); } res = (0, utils_1.removeIndentBlock)(res); if (res[res.length - 1] === '\n') { res = res.slice(0, -1); } } const leftPart = preparedLeftContent + res; return { result: leftPart + content.substring(lastIndex + shift), idx: leftPart.length, }; } module.exports = function legacyConditions(originInput, vars, path, settings) { const sourceMap = (settings === null || settings === void 0 ? void 0 : settings.sourceMap) || {}; const R_LIQUID = /({%-?([\s\S]*?)-?%})/g; let match; const tagStack = []; let input = originInput; let linesTotal = originInput.split('\n').length; while ((match = R_LIQUID.exec(input)) !== null) { if (!match[1]) { continue; } const tagMatch = match[2].trim().match(lexical_1.tagLine); if (!tagMatch) { continue; } const [type, args] = tagMatch.slice(1); switch (type) { case 'if': tagStack.push({ isOpen: true, condition: args, startPos: match.index, ifRaw: match[1], elses: [], }); break; case 'else': tagStack[tagStack.length - 1].elses.push({ startPos: match.index, raw: match[1], }); break; case 'elsif': tagStack[tagStack.length - 1].elses.push({ condition: args, startPos: match.index, raw: match[1], }); break; case 'endif': { const ifTag = tagStack.pop(); if (!ifTag) { log_1.log.error(`If block must be opened before close${path ? ` in ${(0, chalk_1.bold)(path)}` : ''}`); break; } const { idx, result } = inlineConditions({ ifTag, vars, content: input, match, lastIndex: R_LIQUID.lastIndex, sourceMap, linesTotal, }); R_LIQUID.lastIndex = idx; input = result; linesTotal = result.split('\n').length; break; } } } if (tagStack.length !== 0) { log_1.log.error(`Condition block must be closed${path ? ` in ${(0, chalk_1.bold)(path)}` : ''}`); } return input; }; //# sourceMappingURL=legacyConditions.js.map