UNPKG

@marp-team/marpit

Version:

The skinny framework for creating slide deck from Markdown

167 lines (136 loc) 4.61 kB
"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 _section_size = _interopRequireDefault(require("./postcss/section_size")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } 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 }; 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]; return conv ? conv(parsed) : undefined; }; const memoizeProp = name => `${name}Memoized`; const postcssParser = (0, _postcss.default)([_meta.default, _section_size.default, _parse.default]); /** * 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 = {}; /** * 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. */ static fromCSS(cssString, validate = true) { const processed = postcssParser.process(cssString); const { css, result } = processed; // validate option is for internal usage. User should never set as false. if (validate && !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 = _objectSpread({}, result.marpitMeta); Object.assign(theme, _objectSpread({}, 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 = Theme; exports.default = _default;