UNPKG

@diplodoc/transform

Version:

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

133 lines 5.78 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.liquidSnippet = exports.liquidDocument = void 0; const cloneDeepWith_1 = __importDefault(require("lodash/cloneDeepWith")); const frontmatter_1 = require("../frontmatter"); const substitutions_1 = __importDefault(require("./substitutions")); const sourceMap_1 = require("./sourceMap"); const cycles_1 = __importDefault(require("./cycles")); const conditions_1 = __importDefault(require("./conditions")); const argv_1 = __importDefault(require("./services/argv")); const fence = '```'; const find = (open, close, string, index) => { const start = string.indexOf(open, index); const end = start > -1 ? string.indexOf(close, start + open.length) : -1; return [start, end]; }; const replace = (open, close, value, string) => { let result = ''; let carriage = 0; let [start, end] = find(open, close, string, carriage); while (start > -1 && end > -1) { const fragment = string.slice(start + open.length, end); result += string.slice(carriage, start) + open + value(fragment) + close; carriage = end + close.length; [start, end] = find(open, close, string, carriage); } result += string.slice(carriage); return result; }; function saveCode(str, vars, codes, path, substitutions) { return replace(fence, fence, (code) => { const codeWithVars = substitutions ? (0, substitutions_1.default)(code, vars, path) : code; const index = codes.push(codeWithVars) - 1; /* Keep the same count of lines to avoid transformation of the source map */ const codeLines = codeWithVars.split('\n'); const emptyLines = codeLines.length > 1 ? '\n'.repeat(codeLines.length) : ''; return `${index}${emptyLines}`; }, str); } function repairCode(str, codes) { return replace(fence, fence, (code) => codes[Number(code)], str); } function liquidSnippet(originInput, vars, path, settings) { const { cycles = true, conditions = true, substitutions = true, conditionsInCode = false, useLegacyConditions = false, keepNotVar = false, withSourceMap, } = settings || {}; argv_1.default.init({ cycles, conditions, substitutions, conditionsInCode, useLegacyConditions, keepNotVar, withSourceMap, }); const codes = []; let output = conditionsInCode ? originInput : saveCode(originInput, vars, codes, path, substitutions); let sourceMap = {}; if (withSourceMap) { const lines = output.split('\n'); sourceMap = lines.reduce((acc, _cur, index) => { acc[index + 1] = index + 1; return acc; }, {}); } if (cycles) { output = (0, cycles_1.default)(output, vars, path, { sourceMap }); } if (conditions) { const strict = conditions === 'strict'; output = (0, conditions_1.default)(output, vars, path, { sourceMap, strict, useLegacyConditions }); } if (substitutions) { output = (0, substitutions_1.default)(output, vars, path); } if (!conditionsInCode && typeof output === 'string') { output = repairCode(output, codes); } codes.length = 0; if (withSourceMap) { return { output, sourceMap: (0, sourceMap_1.prepareSourceMap)(sourceMap), }; } return output; } exports.liquidSnippet = liquidSnippet; function linesCount(content) { let count = 1, index = -1; while ((index = content.indexOf('\n', index + 1)) > -1) { count++; } return count; } function liquidDocument(input, vars, path, settings) { const [frontMatter, strippedContent] = (0, frontmatter_1.extractFrontMatter)(input, path); const liquidedFrontMatter = (0, cloneDeepWith_1.default)(frontMatter, (value) => typeof value === 'string' ? liquidSnippet(value, vars, path, Object.assign(Object.assign({}, settings), { withSourceMap: false })) : undefined); const liquidedResult = liquidSnippet(strippedContent, vars, path, settings); const liquidedContent = typeof liquidedResult === 'object' ? liquidedResult.output : liquidedResult; const output = (0, frontmatter_1.composeFrontMatter)(liquidedFrontMatter, liquidedContent); if (typeof liquidedResult === 'object') { const inputLinesCount = linesCount(input); const outputLinesCount = linesCount(output); const contentLinesCount = linesCount(strippedContent); const contentLinesDiff = linesCount(liquidedContent) - contentLinesCount; const fullLinesDiff = outputLinesCount - inputLinesCount; // Always >= 0 const sourceOffset = inputLinesCount - contentLinesCount; // Content lines diff already counted in source map const resultOffset = fullLinesDiff - contentLinesDiff; liquidedResult.sourceMap = Object.fromEntries(Object.entries(liquidedResult.sourceMap).map(([lineInResult, lineInSource]) => [ (Number(lineInResult) + resultOffset).toString(), (Number(lineInSource) + sourceOffset).toString(), ])); } // typeof check for better inference; the catch is that return of liquidSnippet can be an // object even with source maps off, see `substitutions.test.ts` return ((settings === null || settings === void 0 ? void 0 : settings.withSourceMap) && typeof liquidedResult === 'object' ? { output, sourceMap: liquidedResult.sourceMap, } : output); } exports.liquidDocument = liquidDocument; exports.default = liquidDocument; //# sourceMappingURL=index.js.map