"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _postcss = _interopRequireDefault(require("postcss")); var _parse = _interopRequireDefault(require("./postcss/import/parse")); var _meta = _interopRequireDefault(require("./postcss/meta")); var _nesting = _interopRequireDefault(require("./postcss/nesting")); var _increasing_specificity = require("./postcss/root/increasing_specificity"); var _replace = _interopRequireDefault(require("./postcss/root/replace")); var _section_size = _interopRequireDefault(require("./postcss/section_size")); var _symbol = _interopRequireDefault(require("./theme/symbol")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } const absoluteUnits = { cm: v => v * 960 / 25.4, in: v => v * 96, mm: v => v * 96 / 25.4, pc: v => v * 16, pt: v => v * 4 / 3, px: v => v, q: v => v * 24 / 25.4 }; const convertToPixel = value => { if (typeof value !== 'string') return undefined; const matched = value.match(/^(-?[.0-9]+)([a-z]+)$/i); if (!matched) return undefined; const [, num, unit] = matched; const parsed = Number.parseFloat(num); if (Number.isNaN(parsed)) return undefined; const conv = absoluteUnits[unit.toLowerCase()]; return conv ? conv(parsed) : undefined; }; const memoizeProp = name => `${name}Memoized`; const reservedMetaType = { theme: String }; /** * Marpit theme class. */ class Theme { /** * Create a Theme instance. * * You should use {@link Theme.fromCSS} unless there is some particular * reason. * * @param {string} name The name of theme. * @param {string} css The content of CSS. * @hideconstructor */ constructor(name, css) { /** * The name of theme. * @type {string} */ this.name = name; /** * The content of theme CSS. * @type {string} */ this.css = css; /** * Parsed metadata from CSS comments. * @type {Object} */ this.meta = Object.freeze({}); /** * Parsed `@import` rules. * @type {module:postcss/import/parse~ImportMeta[]} */ this.importRules = []; /** * Slide width. It requires the absolute unit supported in CSS. * @type {string} */ this.width = undefined; /** * Slide height. It requires the absolute unit supported in CSS. * @type {string} */ this.height = undefined; this.memoizeInit('width'); this.memoizeInit('height'); } /** * Create a Theme instance from Marpit theme CSS. * * @alias Theme.fromCSS * @param {string} cssString The string of Marpit theme CSS. It requires * `@theme` meta comment. * @param {Object} [opts] * @param {Object} [opts.metaType] An object for defined types for metadata. * @param {Object} [opts.cssNesting] Enable support for CSS nesting. */ static fromCSS(cssString, opts = {}) { const metaType = { ...(opts.metaType || {}), ...reservedMetaType }; const { css, result } = (0, _postcss.default)([!!opts.cssNesting && _nesting.default, (0, _meta.default)({ metaType }), (0, _replace.default)({ pseudoClass: _increasing_specificity.pseudoClass }), (0, _section_size.default)({ preferedPseudoClass: _increasing_specificity.pseudoClass }), _parse.default].filter(p => p)).process(cssString); if (!opts[_symbol.default] && !result.marpitMeta.theme) throw new Error('Marpit theme CSS requires @theme meta.'); const theme = new Theme(result.marpitMeta.theme, css); theme.importRules = [...result.marpitImport]; theme.meta = Object.freeze({ ...result.marpitMeta }); Object.assign(theme, { ...result.marpitSectionSize }); return Object.freeze(theme); } /** * The converted width into pixel. * * @alias Theme#widthPixel * @type {number} * @readonly */ get widthPixel() { return this.memoize('width', convertToPixel); } /** * The converted height into pixel. * * @alias Theme#heightPixel * @type {number} * @readonly */ get heightPixel() { return this.memoize('height', convertToPixel); } /** @private */ memoize(prop, func) { if (this[memoizeProp(prop)].has(this[prop])) return this[memoizeProp(prop)].get(this[prop]); const converted = func(this[prop]); this[memoizeProp(prop)].set(this[prop], converted); return converted; } /** @private */ memoizeInit(prop) { if (!this[memoizeProp(prop)]) Object.defineProperty(this, memoizeProp(prop), { value: new Map() }); } } var _default = exports.default = Theme;