@diplodoc/transform
Version:
A simple transformer of text in YFM (Yandex Flavored Markdown) to HTML
80 lines • 3.58 kB
JavaScript
;
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