UNPKG

@diplodoc/transform

Version:

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

134 lines 5.23 kB
"use strict"; const path_1 = require("path"); const chalk_1 = require("chalk"); const svgo_1 = require("svgo"); const fs_1 = require("fs"); const utilsFS_1 = require("../../utilsFS"); const utils_1 = require("../../utils"); const sanitizeAttribute = (value) => value.replace(/(\d*[%a-z]{0,5}).*/gi, '$1'); function replaceImageSrc(token, state, { assetsPublicPath = path_1.sep, root = '', path: optsPath, log }) { var _a; const src = (0, utils_1.getSrcTokenAttr)(token); const currentPath = state.env.path || optsPath; if (!(0, utils_1.isLocalUrl)(src)) { return; } const path = (0, utilsFS_1.resolveRelativePath)(currentPath, src); if ((0, utilsFS_1.isFileExists)(path)) { (_a = state.md.assets) === null || _a === void 0 ? void 0 : _a.push(src); } else { log.error(`Asset not found: ${(0, chalk_1.bold)(src)} in ${(0, chalk_1.bold)(currentPath)}`); } const relativeToRoot = path.replace(root + path_1.sep, ''); const publicSrc = (0, path_1.join)(assetsPublicPath, relativeToRoot); token.attrSet('src', publicSrc); } function convertSvg(token, state, { path: optsPath, log, notFoundCb, root, imageOpts }) { const currentPath = state.env.path || optsPath; const path = (0, utilsFS_1.resolveRelativePath)(currentPath, (0, utils_1.getSrcTokenAttr)(token)); try { const raw = (0, fs_1.readFileSync)(path).toString(); const content = raw === '' ? '' : replaceSvgContent(raw, imageOpts); const svgToken = new state.Token('image_svg', '', 0); svgToken.attrSet('content', content); return svgToken; } catch (e) { log.error(`SVG ${path} from ${currentPath} not found`); if (notFoundCb) { notFoundCb(path.replace(root, '')); } return token; } } const index = (md, opts) => { md.assets = []; const plugin = (state) => { const tokens = state.tokens; let i = 0; while (i < tokens.length) { if (tokens[i].type !== 'inline') { i++; continue; } const childrenTokens = tokens[i].children || []; let j = 0; while (j < childrenTokens.length) { if (childrenTokens[j].type === 'image') { const didPatch = childrenTokens[j].attrGet('yfm_patched') || false; if (didPatch) { return; } const imgSrc = (0, utils_1.getSrcTokenAttr)(childrenTokens[j]); const shouldInlineSvg = (childrenTokens[j].attrGet('inline') === null ? opts.inlineSvg !== false : childrenTokens[j].attrGet('inline') === 'true') && !(0, utils_1.isExternalHref)(imgSrc); if (imgSrc.endsWith('.svg') && shouldInlineSvg) { childrenTokens[j] = convertSvg(childrenTokens[j], state, opts); } else { replaceImageSrc(childrenTokens[j], state, opts); } childrenTokens[j].attrSet('yfm_patched', '1'); } j++; } i++; } }; try { md.core.ruler.before('includes', 'images', plugin); } catch (e) { md.core.ruler.push('images', plugin); } md.renderer.rules.image_svg = (tokens, index) => { const token = tokens[index]; return token.attrGet('content') || ''; }; }; function replaceSvgContent(content, options) { var _a; // monoline content = content.replace(/>\r?\n</g, '><').replace(/\r?\n/g, ' '); // width, height let svgRoot = content.replace(/.*?<svg([^>]*)>.*/g, '$1'); const { width, height } = ((_a = svgRoot .match(/(?:width="(.*?)")|(?:height="(.*?)")/g)) === null || _a === void 0 ? void 0 : _a.reduce((acc, val) => { const [key, value] = val.split('='); acc[key] = value; return acc; }, {})) || { width: undefined, height: undefined }; if (!width && options.width) { const sanitizedWidth = sanitizeAttribute(options.width.toString()); svgRoot = `${svgRoot} width="${sanitizedWidth}"`; } if (!height && options.height) { const sanitizedHeight = sanitizeAttribute(options.height.toString()); svgRoot = `${svgRoot} height="${sanitizedHeight}"`; } if ((!width && options.width) || (!height && options.height)) { content = content.replace(/.*?<svg([^>]*)>/, `<svg${svgRoot}>`); } // randomize ids content = (0, svgo_1.optimize)(content, { plugins: [ { name: 'prefixIds', params: { prefix: 'rnd-' + Math.floor(Math.random() * 1e9).toString(16), prefixClassNames: false, }, }, ], }).data; return content; } // Create an object that is the index function with an additional replaceSvgContent property const imagesPlugin = Object.assign(index, { replaceSvgContent, }); module.exports = imagesPlugin; //# sourceMappingURL=index.js.map