UNPKG

@diplodoc/transform

Version:

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

80 lines 3.58 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.composeFrontMatter = exports.extractFrontMatter = void 0; const js_yaml_1 = require("js-yaml"); const ts_dedent_1 = require("ts-dedent"); const cloneDeepWith_1 = __importDefault(require("lodash/cloneDeepWith")); const log_1 = require("./log"); const SEP = '---'; /** * Temporary workaround to enable parsing YAML metadata from potentially * Liquid-aware source files * @param content Input string which could contain Liquid-style substitution syntax (which clashes with YAML * object syntax) * @returns String with `{}` escaped, ready to be parsed with `js-yaml` */ const escapeLiquid = (content) => content.replace(/{{/g, '(({{').replace(/}}/g, '}}))'); /** * Inverse of a workaround defined above. * @see `escapeLiquid` * @param escapedContent Input string with `{}` escaped with backslashes * @returns Unescaped string */ const unescapeLiquid = (escapedContent) => escapedContent.replace(/\(\({{/g, '{{').replace(/}}\)\)/g, '}}'); const matchMetadata = (fileContent) => { if (!fileContent.startsWith(SEP)) { return null; } const closeStart = fileContent.indexOf('\n' + SEP, SEP.length); const closeEnd = fileContent.indexOf('\n', closeStart + 1); if (closeStart === -1) { return null; } return [fileContent.slice(SEP.length, closeStart).trim(), fileContent.slice(closeEnd + 1)]; }; const duplicateKeysCompatibleLoad = (yaml, filePath) => { try { return (0, js_yaml_1.load)(yaml); } catch (e) { if (e instanceof js_yaml_1.YAMLException) { const duplicateKeysDeprecationWarning = (0, ts_dedent_1.dedent) ` In ${filePath !== null && filePath !== void 0 ? filePath : '(unknown)'}: Encountered a YAML parsing exception when processing file metadata: ${e.reason}. It's highly possible the input file contains duplicate mapping keys. Will retry processing with necessary compatibility flags. Please note that this behaviour is DEPRECATED and WILL be removed in a future version without further notice, so the build WILL fail when supplied with YAML-incompatible meta. `; log_1.log.warn(duplicateKeysDeprecationWarning); return (0, js_yaml_1.load)(yaml, { json: true }); } throw e; } }; const extractFrontMatter = (fileContent, filePath) => { const matches = matchMetadata(fileContent); if (matches) { const [metadata, strippedContent] = matches; return [ (0, cloneDeepWith_1.default)(duplicateKeysCompatibleLoad(escapeLiquid(metadata), filePath), (v) => (typeof v === 'string' ? unescapeLiquid(v) : undefined)), strippedContent, ]; } return [{}, fileContent]; }; exports.extractFrontMatter = extractFrontMatter; const composeFrontMatter = (frontMatter, strippedContent) => { const dumped = (0, js_yaml_1.dump)(frontMatter, { lineWidth: -1 }).trim(); // This empty object check is a bit naive // The other option would be to check if all own fields are `undefined`, // since we exploit passing in `undefined` to remove a field quite a bit if (dumped === '{}') { return strippedContent; } return `${SEP}\n${dumped}\n${SEP}\n${strippedContent}`; }; exports.composeFrontMatter = composeFrontMatter; //# sourceMappingURL=frontmatter.js.map