1
0

add initial marp implementation with sample content and build configuration

This commit is contained in:
2025-09-13 18:13:22 +02:00
parent dcacc9b409
commit e5f219507f
10319 changed files with 1402023 additions and 0 deletions

View File

@@ -0,0 +1,91 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.advancedBackground = void 0;
var _postcss_plugin = _interopRequireDefault(require("../helpers/postcss_plugin"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
/**
* Marpit PostCSS advanced background plugin.
*
* Append style to suport the advanced background.
*
* @function advancedBackground
*/
const advancedBackground = exports.advancedBackground = (0, _postcss_plugin.default)('marpit-postcss-advanced-background', () => css => {
css.last.after(`
section[data-marpit-advanced-background="background"] {
columns: initial !important;
display: block !important;
padding: 0 !important;
}
section[data-marpit-advanced-background="background"]::before,
section[data-marpit-advanced-background="background"]::after,
section[data-marpit-advanced-background="content"]::before,
section[data-marpit-advanced-background="content"]::after {
display: none !important;
}
section[data-marpit-advanced-background="background"] > div[data-marpit-advanced-background-container] {
all: initial;
display: flex;
flex-direction: row;
height: 100%;
overflow: hidden;
width: 100%;
}
section[data-marpit-advanced-background="background"] > div[data-marpit-advanced-background-container][data-marpit-advanced-background-direction="vertical"] {
flex-direction: column;
}
section[data-marpit-advanced-background="background"][data-marpit-advanced-background-split] > div[data-marpit-advanced-background-container] {
width: var(--marpit-advanced-background-split, 50%);
}
section[data-marpit-advanced-background="background"][data-marpit-advanced-background-split="right"] > div[data-marpit-advanced-background-container] {
margin-left: calc(100% - var(--marpit-advanced-background-split, 50%));
}
section[data-marpit-advanced-background="background"] > div[data-marpit-advanced-background-container] > figure {
all: initial;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
flex: auto;
margin: 0;
}
section[data-marpit-advanced-background="background"] > div[data-marpit-advanced-background-container] > figure > figcaption {
position: absolute;
border: 0;
clip: rect(0, 0, 0, 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
white-space: nowrap;
width: 1px;
}
section[data-marpit-advanced-background="content"],
section[data-marpit-advanced-background="pseudo"] {
background: transparent !important;
}
section[data-marpit-advanced-background="pseudo"],
:marpit-container > svg[data-marpit-svg] > foreignObject[data-marpit-advanced-background="pseudo"] {
pointer-events: none !important;
}
section[data-marpit-advanced-background-split] {
width: 100%;
height: 100%;
}
`.trim());
});
var _default = exports.default = advancedBackground;

View File

@@ -0,0 +1,44 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.postprocess = exports.default = exports.containerQuery = void 0;
var _cssesc = _interopRequireDefault(require("cssesc"));
var _postcss_plugin = _interopRequireDefault(require("../helpers/postcss_plugin"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
const reservedNames = ['none', 'inherit', 'initial', 'revert', 'revert-layer', 'unset'];
const marpitContainerQueryPseudoMatcher = /\bsection:marpit-container-query\b/g;
/**
* Marpit PostCSS container query plugin.
*
* Add support of container queries for child elements of the `section` element.
* (`@container` at-rule, and `cqw` `cqh` `cqi` `cqb` `cqmin` `cqmax` units)
*
* @function meta
* @param {string|string[]} [containerName=undefined] Container name
* @param {boolean} [escape=true] Set whether to escape container name
*/
const containerQuery = exports.containerQuery = (0, _postcss_plugin.default)('marpit-postcss-container-query', (containerName = undefined, escape = true) => css => {
const containerNames = (Array.isArray(containerName) ? containerName : [containerName]).filter(name => name && !reservedNames.includes(name));
const containerNameDeclaration = containerNames.length > 0 ? `\n container-name: ${containerNames.map(name => escape ? (0, _cssesc.default)(name.toString(), {
isIdentifier: true
}) : name.toString()).join(' ')};` : '';
const style = `
section:marpit-container-query {
container-type: size;${containerNameDeclaration}
}
`.trim();
if (css.first) {
css.first.before(style);
} else {
css.append(style);
}
});
const postprocess = exports.postprocess = (0, _postcss_plugin.default)('marpit-postcss-container-query-postprocess', () => css => css.walkRules(marpitContainerQueryPseudoMatcher, rule => {
rule.selectors = rule.selectors.map(selector => selector.replace(marpitContainerQueryPseudoMatcher, ':where(section)'));
}));
var _default = exports.default = containerQuery;

View File

@@ -0,0 +1,51 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.importHoisting = exports.default = void 0;
var _postcss_plugin = _interopRequireDefault(require("../../helpers/postcss_plugin"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
/**
* Marpit PostCSS import hoisting plugin.
*
* Hoist `@charset` and `@import` at-rule to the beginning of CSS. Marpit is
* manipulating CSS with many PostCSS plugins, so sometimes a few at-rules
* cannot keep specification.
*
* This plugin takes care of hoisting for invalid at-rules.
*
* @function importHoisting
*/
const importHoisting = exports.importHoisting = (0, _postcss_plugin.default)('marpit-postcss-import-hoisting', () => css => {
const hoisted = {
charset: undefined,
imports: []
};
css.walkAtRules(rule => {
if (rule.name === 'charset') {
rule.remove();
if (!hoisted.charset) hoisted.charset = rule;
} else if (rule.name === 'import') {
hoisted.imports.push(rule.remove());
}
});
const {
first
} = css
// Hoist at-rules
;
[hoisted.charset, ...hoisted.imports].filter(r => r).forEach((rule, idx) => {
// Strip whitespace from the beginning of first at-rule
const prependRule = idx === 0 ? rule.clone({
raws: {
before: undefined
}
}) : rule;
first.before(prependRule);
});
});
var _default = exports.default = importHoisting;

View File

@@ -0,0 +1,80 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.importParse = exports.default = void 0;
var _postcss_plugin = _interopRequireDefault(require("../../helpers/postcss_plugin"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
/**
* @typedef {object} ImportMeta
* @prop {AtRule} node The at-rule node parsed by PostCSS.
* @prop {string} value The specified value.
*/
/**
* Marpit PostCSS import parse plugin.
*
* Parse `@import` and `@import-theme` rules that specify a plain string.
*
* The `@import` rule for Marpit theme follows CSS spec. It must precede all
* other statements. (excepted `@charset`)
*
* When you are using CSS preprocessors like Sass, `@import` would resolve path
* in compiling and would be lost definition. So you can use `@import-theme`
* rule alternatively.
*
* A specification of `@import-theme` has a bit different from `@import`. You
* can place `@import-theme` rule at any in the CSS root, and the content of
* imported theme will always append to the beginning of CSS.
*
* @function importParse
*/
const importParse = exports.importParse = (0, _postcss_plugin.default)('marpit-postcss-import-parse', () => (css, {
result
}) => {
const imports = {
import: [],
importTheme: []
};
let allowImport = true;
css.walk(node => {
if (node.type === 'atrule') {
const push = target => {
const [quote] = node.params;
if (quote !== '"' && quote !== "'") return;
const splitedValue = node.params.slice(1).split(quote);
let value = '';
splitedValue.every(v => {
if (v.endsWith('\\')) {
value = `${value}${v.slice(0, -1)}${quote}`;
return true;
}
value = `${value}${v}`;
return false;
});
node.marpitImportParse = value;
target.push({
node,
value
});
};
if (allowImport) {
if (node.name === 'import') {
push(imports.import);
} else if (node.name !== 'charset') {
allowImport = false;
}
}
if (node.name === 'import-theme' && node.parent.type === 'root') {
push(imports.importTheme);
}
} else if (node.type !== 'comment') {
allowImport = false;
}
});
result.marpitImport = [...imports.importTheme, ...imports.import];
});
var _default = exports.default = importParse;

View File

@@ -0,0 +1,48 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.importReplace = exports.default = void 0;
var _postcss_plugin = _interopRequireDefault(require("../../helpers/postcss_plugin"));
var _parse = _interopRequireDefault(require("./parse"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
/**
* Marpit PostCSS import replace plugin.
*
* Replace parsed `@import` / `@import-theme` rules.
*
* Please see {@link module:postcss/import/parse} about the specification of
* each syntax.
*
* @function importReplace
* @param {ThemeSet} themeSet ThemeSet instance.
*/
const importReplace = (themeSet, importedThemes = []) => (0, _postcss_plugin.default)('marpit-postcss-import-replace', () => ({
plugins: [(0, _parse.default)(), (0, _postcss_plugin.default)('marpit-postcss-import-replace-processor', () => (css, {
postcss
}) => {
const prepends = [];
css.walk(node => {
const name = node.marpitImportParse;
if (name) {
const theme = themeSet.get(name);
if (theme) {
if (importedThemes.includes(name)) throw new Error(`Circular "${name}" theme import is detected.`);
const processed = postcss([importReplace(themeSet, [...importedThemes, name])]).process(theme.css);
if (node.name === 'import') {
node.replaceWith(processed.root);
} else {
node.remove();
prepends.unshift(processed.root);
}
}
}
});
for (const root of prepends) css.first.before(root);
})()]
}));
exports.importReplace = importReplace;
var _default = exports.default = importReplace;

View File

@@ -0,0 +1,30 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.importSuppress = exports.default = void 0;
var _postcss_plugin = _interopRequireDefault(require("../../helpers/postcss_plugin"));
var _parse = _interopRequireDefault(require("./parse"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
/**
* Marpit PostCSS import suppress plugin.
*
* Comment out `@import` / `@import-theme` rules that have imported theme.
*
* This plugin is useful to prevent the inline style's rolled-up theme import by
* unexpected order.
*
* @function importSuppress
* @param {ThemeSet} themeSet ThemeSet instance.
*/
const importSuppress = exports.importSuppress = (0, _postcss_plugin.default)('marpit-postcss-import-suppress', themeSet => ({
plugins: [(0, _parse.default)(), (0, _postcss_plugin.default)('marpit-postcss-import-suppress', () => css => {
css.walk(node => {
if (node.marpitImportParse && themeSet.has(node.marpitImportParse)) node.replaceWith(`${node.raw('before')}/* ${node.toString()}; */`);
});
})()]
}));
var _default = exports.default = importSuppress;

37
node_modules/@marp-team/marpit/lib/postcss/meta.js generated vendored Normal file
View File

@@ -0,0 +1,37 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.meta = exports.default = void 0;
var _postcss_plugin = _interopRequireDefault(require("../helpers/postcss_plugin"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
/**
* Marpit PostCSS meta plugin.
*
* Parse CSS comment written in the format of `@key value`.
*
* @function meta
* @param {Object} [opts]
* @param {Object} [opts.metaType] An object for defined types for metadata.
*/
const meta = exports.meta = (0, _postcss_plugin.default)('marpit-postcss-meta', (opts = {}) => (css, {
result
}) => {
const metaType = opts.metaType || {};
result.marpitMeta = result.marpitMeta || {};
css.walkComments(comment => {
comment.text.slice(0).replace(/^[*!\s]*@([\w-]+)\s+(.+)$/gim, (_, metaName, value) => {
if (metaType[metaName] === Array) {
// Array meta
result.marpitMeta[metaName] = [...(result.marpitMeta[metaName] || []), value];
} else {
// String meta (default)
result.marpitMeta[metaName] = value;
}
});
});
});
var _default = exports.default = meta;

44
node_modules/@marp-team/marpit/lib/postcss/nesting.js generated vendored Normal file
View File

@@ -0,0 +1,44 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.nesting = exports.default = void 0;
var _postcssIsPseudoClass = _interopRequireDefault(require("@csstools/postcss-is-pseudo-class"));
var _postcssNesting = _interopRequireDefault(require("postcss-nesting"));
var _postcss_plugin = _interopRequireDefault(require("../helpers/postcss_plugin"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
const {
Rule: applyPostCSSNesting
} = (0, _postcssNesting.default)();
const matcher = /:is\((?:section|:root)\b/;
const nesting = exports.nesting = (0, _postcss_plugin.default)('marpit-postcss-nesting', () => (root, helpers) => {
const rules = [];
// Note: Use walk instead of walkRules to include nested rules
root.walk(node => {
if (node.type !== 'rule') return;
rules.push(node);
node.__marpitNestingOriginalSelector = node.selector;
});
// Apply postcss-nesting
root.walkRules(rule => applyPostCSSNesting(rule, helpers));
const {
Rule: applyPostCSSIsPseudoClass
} = (0, _postcssIsPseudoClass.default)({
onComplexSelector: 'warning'
}).prepare();
for (const rule of rules) {
if (rule.__marpitNestingOriginalSelector !== rule.selector && matcher.test(rule.selector)) {
// Apply postcss-is-pseudo-class only to transformed rules that is
// including `:is() selector starting from `section` element or `:root`
// pseudo-class
applyPostCSSIsPseudoClass(rule, helpers);
}
delete rule.__marpitNestingOriginalSelector;
}
});
var _default = exports.default = nesting;

View File

@@ -0,0 +1,30 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.pagination = exports.default = void 0;
var _postcss_plugin = _interopRequireDefault(require("../helpers/postcss_plugin"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
/**
* Marpit PostCSS pagination plugin.
*
* Marpit uses `section::after` to show the pagination on each slide. It defines
* in the scaffold theme.
*
* This plugin will comment out a `content` declaration defined in any
* `section::after` of the root, to prevent override the defined attribute for
* paginating.
*
* @function pagination
*/
const pagination = exports.pagination = (0, _postcss_plugin.default)('marpit-postcss-pagination', () => css => {
css.walkRules(rule => {
if (rule.selectors.some(selector => /^section(?![\w-])[^\s>+~]*::?after$/.test(selector.replace(/\[.*?\]/g, '')))) rule.walkDecls('content', decl => {
if (!decl.value.includes('attr(data-marpit-pagination)')) decl.replaceWith(`${decl.raw('before')}/* ${decl.toString()}; */`);
});
});
});
var _default = exports.default = pagination;

View File

@@ -0,0 +1,74 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.printable = exports.postprocess = exports.default = void 0;
var _postcss_plugin = _interopRequireDefault(require("../helpers/postcss_plugin"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
const marpitPrintContainerStyle = `
html, body {
background-color: #fff;
margin: 0;
page-break-inside: avoid;
break-inside: avoid-page;
}
`.trim();
/**
* Marpit PostCSS printable plugin.
*
* Make printable slide deck as PDF.
*
* @param {Object} opts
* @param {string} opts.width
* @param {string} opts.height
* @function printable
*/
const printable = exports.printable = (0, _postcss_plugin.default)('marpit-postcss-printable', opts => css => {
css.walkAtRules('media', rule => {
if (rule.params === 'marpit-print') rule.remove();
});
css.first.before(`
@page {
size: ${opts.width} ${opts.height};
margin: 0;
}
@media marpit-print {
section {
page-break-before: always;
break-before: page;
}
section, section * {
-webkit-print-color-adjust: exact !important;
animation-delay: 0s !important;
animation-duration: 0s !important;
color-adjust: exact !important;
print-color-adjust: exact !important;
transition: none !important;
}
:marpit-container > svg[data-marpit-svg] {
display: block;
height: 100vh;
width: 100vw;
}
}
`.trim());
});
/**
* The post-process PostCSS plugin of Marpit printable plugin.
*
* @function postprocess
*/
const postprocess = exports.postprocess = (0, _postcss_plugin.default)('marpit-postcss-printable-postprocess', () => css => css.walkAtRules('media', rule => {
if (rule.params !== 'marpit-print') return;
rule.params = 'print';
rule.first.before(marpitPrintContainerStyle);
}));
var _default = exports.default = printable;

View File

@@ -0,0 +1,31 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.pseudoSelectorPrepend = exports.default = void 0;
var _postcss_plugin = _interopRequireDefault(require("../../helpers/postcss_plugin"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
/**
* Marpit PostCSS pseudo selector prepending plugin.
*
* Prepend `:marpit-container > :marpit-slide` pseudo selector to each selector
* of Marpit theme CSS for modulized styling.
*
* @function pseudoSelectorPrepend
*/
const pseudoSelectorPrepend = exports.pseudoSelectorPrepend = (0, _postcss_plugin.default)('marpit-postcss-pseudo-selector-prepend', () => css => css.walkRules(rule => {
const {
type,
name
} = rule.parent || {};
if (type === 'atrule' && name === 'keyframes') return;
rule.selectors = rule.selectors.map(selector => {
if (/^section(?![\w-])/.test(selector)) return `:marpit-container > :marpit-slide${selector.slice(7)}`;
if (selector.startsWith(':marpit-container')) return selector;
return `:marpit-container > :marpit-slide ${selector}`;
});
}));
var _default = exports.default = pseudoSelectorPrepend;

View File

@@ -0,0 +1,43 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.pseudoSelectorReplace = exports.default = void 0;
var _cssesc = _interopRequireDefault(require("cssesc"));
var _postcss_plugin = _interopRequireDefault(require("../../helpers/postcss_plugin"));
var _wrap_array = require("../../helpers/wrap_array");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
const buildSelector = elms => elms.map(e => {
const classes = new Set((e.class || '').split(/\s+/).filter(c => c));
let element = [e.tag, ...classes].map(c => (0, _cssesc.default)(c, {
isIdentifier: true
})).join('.');
if (e.id) element += `#${(0, _cssesc.default)(e.id, {
isIdentifier: true
})}`;
return element;
}).join(' > ');
/**
* Marpit PostCSS pseudo selector replace plugin.
*
* Replace `:marpit-container` and `:marpit-slide` pseudo selector into
* container element(s).
*
* @function pseudoSelectorReplace
* @param {Element|Element[]} [elements] Container elements
* @param {Element|Element[]} [slideElements={ tag: 'section' }] Slide elements
*/
const pseudoSelectorReplace = exports.pseudoSelectorReplace = (0, _postcss_plugin.default)('marpit-postcss-pseudo-selector-replace', (elements, slideElements = {
tag: 'section'
}) => {
const container = buildSelector([...(0, _wrap_array.wrapArray)(elements)]);
const section = buildSelector([...(0, _wrap_array.wrapArray)(slideElements)]);
return css => css.walkRules(rule => {
rule.selectors = rule.selectors.map(selector => selector.replace(/:marpit-container(?![\w-])/g, container).replace(/:marpit-slide(?![\w-])/g, section).replace(/^\s*>\s*/, ''));
});
});
var _default = exports.default = pseudoSelectorReplace;

View File

@@ -0,0 +1,49 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.rootFontSizeCustomProp = exports.rootFontSize = exports.default = void 0;
var _postcss_plugin = _interopRequireDefault(require("../../helpers/postcss_plugin"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
const rootFontSizeCustomProp = exports.rootFontSizeCustomProp = '--marpit-root-font-size';
/**
* Marpit PostCSS root font size plugin.
*
* Inject CSS variable based on the root slide container `section` for correct
* calculation of `rem` unit in the context of Marpit.
*
* @function rootFontSize
*/
const rootFontSize = exports.rootFontSize = (0, _postcss_plugin.default)('marpit-postcss-root-font-size', () => (css, postcss) => css.walkRules(rule => {
const injectSelector = new Set();
for (const selector of rule.selectors) {
// Detect whether the selector is targeted to section
const parentSelectors = selector.split(/(\s+|\s*[>~+]\s*)/);
const targetSelector = parentSelectors.pop();
const delimiterMatched = targetSelector.match(/[.:#[]/);
const target = delimiterMatched ? targetSelector.slice(0, delimiterMatched.index) : targetSelector;
if (target === 'section' || target.endsWith('*') || target === '') {
// Generate selector for injection
injectSelector.add([...parentSelectors, target === 'section' ? 'section' : ':marpit-container > :marpit-slide section',
// Universal selector is targeted to the children `section` of root `section`
delimiterMatched ? targetSelector.slice(delimiterMatched.index) : ''].join(''));
}
}
if (injectSelector.size === 0) return;
// Inject CSS variable
const injectRule = postcss.rule({
selectors: [...injectSelector.values()]
});
rule.walkDecls('font-size', decl => {
injectRule.append(decl.clone({
prop: rootFontSizeCustomProp
}));
});
if (injectRule.nodes.length > 0) rule.parent.insertAfter(rule, injectRule);
}));
var _default = exports.default = rootFontSize;

View File

@@ -0,0 +1,27 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.rootIncreasingSpecificity = exports.pseudoClass = exports.default = void 0;
var _postcss_plugin = _interopRequireDefault(require("../../helpers/postcss_plugin"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
const pseudoClass = exports.pseudoClass = ':marpit-root';
const matcher = new RegExp(`\\b(?:section)?${pseudoClass}\\b`, 'g');
/**
* Marpit PostCSS root increasing specificity plugin.
*
* Replace specific pseudo-class selector to `:where(section):not([\20 root])`,
* to increase specificity. `:marpit-root` is always added to `section` selector
* by root replace plugin so `:where(section):not([\20 root])` must always match
* too (HTML does not allow U+0020 SPACE in the attribute name.).
*
* @function rootIncreasingSpecificity
*/
const rootIncreasingSpecificity = exports.rootIncreasingSpecificity = (0, _postcss_plugin.default)('marpit-postcss-root-increasing-specificity', () => css => css.walkRules(rule => {
rule.selectors = rule.selectors.map(selector => selector.replace(matcher, ':where(section):not([\\20 root])'));
}));
var _default = exports.default = rootIncreasingSpecificity;

27
node_modules/@marp-team/marpit/lib/postcss/root/rem.js generated vendored Normal file
View File

@@ -0,0 +1,27 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.rem = exports.default = void 0;
var _postcss_plugin = _interopRequireDefault(require("../../helpers/postcss_plugin"));
var _font_size = require("./font_size");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
const skipParsingMatcher = /("[^"]*"|'[^']*'|(?:attr|url|var)\([^)]*\))/g;
/**
* Marpit PostCSS rem plugin.
*
* Replace `rem` unit to calculated value from CSS variable.
*
* @function rem
*/
const rem = exports.rem = (0, _postcss_plugin.default)('marpit-postcss-rem', () => css => css.walkDecls(decl => {
decl.value = decl.value.split(skipParsingMatcher).map((v, i) => {
if (i % 2) return v;
return v.replace(/(\d*\.?\d+)rem\b/g, (_, num) => `calc(var(${_font_size.rootFontSizeCustomProp}, 1rem) * ${num})`);
}).join('');
}));
var _default = exports.default = rem;

View File

@@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.rootReplace = exports.default = void 0;
var _postcss_plugin = _interopRequireDefault(require("../../helpers/postcss_plugin"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
/**
* Marpit PostCSS root replace plugin.
*
* Replace `:root` pseudo-class selector into `section`. It can add custom
* pseudo class through `pseudoClass` option to make distinguishable from
* `section` selector.
*
* @function rootReplace
*/
const rootReplace = exports.rootReplace = (0, _postcss_plugin.default)('marpit-postcss-root-replace', ({
pseudoClass
} = {}) => css => css.walkRules(rule => {
// Replace `:root` pseudo-class selectors into `section`
rule.selectors = rule.selectors.map(selector => selector.replace(/(^|[\s>+~(])(?:section)?:root\b/g, (_, s) => `${s}section${pseudoClass || ''}`));
}));
var _default = exports.default = rootReplace;

View File

@@ -0,0 +1,56 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.sectionSize = exports.default = void 0;
var _postcss_plugin = _interopRequireDefault(require("../helpers/postcss_plugin"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
/**
* Marpit PostCSS section size plugin.
*
* Parse width and height declartaion on `section` selector.
*
* @function sectionSize
*/
const sectionSize = exports.sectionSize = (0, _postcss_plugin.default)('marpit-postcss-section-size', ({
preferedPseudoClass
} = {}) => {
const rootSectionMatcher = new RegExp(`^section${preferedPseudoClass ? `(${preferedPseudoClass})?` : ''}$`);
return (css, {
result
}) => {
const originalSize = result.marpitSectionSize || {};
const detectedSize = {};
const preferedSize = {};
let matched;
css.walkRules(rule => {
if (rule.selectors.some(s => {
matched = s.match(rootSectionMatcher);
return !!matched;
})) {
rule.walkDecls(/^(width|height)$/, decl => {
const {
prop
} = decl;
const value = decl.value.trim();
if (matched[1]) {
preferedSize[prop] = value;
} else {
detectedSize[prop] = value;
}
});
}
});
const width = preferedSize.width || detectedSize.width || originalSize.width;
const height = preferedSize.height || detectedSize.height || originalSize.height;
result.marpitSectionSize = {
...originalSize
};
if (width) result.marpitSectionSize.width = width;
if (height) result.marpitSectionSize.height = height;
};
});
var _default = exports.default = sectionSize;

View File

@@ -0,0 +1,74 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.svgBackdrop = exports.default = void 0;
var _postcss_plugin = _interopRequireDefault(require("../helpers/postcss_plugin"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
const backdropMatcher = /(?:\b|^)::backdrop$/;
/**
* Marpit PostCSS SVG backdrop plugin.
*
* Retarget `::backdrop` and `section::backdrop` selector to
* `@media screen { :marpit-container > svg[data-marpit-svg] { .. } }`. It means
* `::backdrop` targets the SVG container in inline SVG mode.
*
* It's useful for setting style of the letterbox and pillarbox in the SVG
* scaled slide.
*
* ```css
* ::backdrop {
* background-color: #448;
* }
* ```
*
* The original definition will remain to support an original usage of
* `::backdrop`.
*
* The important differences from an original `::backdrop` are following:
*
* - In original spec, `::backdrop` creates a separated layer from the target
* element, but Marpit's `::backdrop` does not. The slide elements still
* become the child of `::backdrop` so setting some properties that are
* inherited may make broken slide rendering.
* - Even if the browser is not fullscreen, `::backdrop` will match to SVG
* container whenever matched to `@media screen` media query.
*
* If concerned to conflict with the style provided by the app, consider to
* disable the selector support by `inlineSVG: { backdropSelector: false }`.
*
* @see https://developer.mozilla.org/docs/Web/CSS/::backdrop
* @function svgBackdrop
*/
const svgBackdrop = exports.svgBackdrop = (0, _postcss_plugin.default)('marpit-postcss-svg-backdrop', () => (css, postcss) => {
css.walkRules(rule => {
const injectSelectors = new Set();
for (const selector of rule.selectors) {
// Detect pseudo-element (must appear after the simple selectors)
if (!selector.match(backdropMatcher)) continue;
// Detect whether the selector is targeted to section
const delimiterMatched = selector.match(/[.:#[]/); // must match
const target = selector.slice(0, delimiterMatched.index);
if (target === 'section' || target === '') {
const delimiter = selector.slice(delimiterMatched.index, -10);
injectSelectors.add(`:marpit-container > svg[data-marpit-svg]${delimiter}`);
}
}
if (injectSelectors.size > 0 && rule.nodes.length > 0) {
rule.parent.insertAfter(rule, postcss.atRule({
name: 'media',
params: 'screen',
nodes: [postcss.rule({
selectors: [...injectSelectors.values()],
nodes: rule.nodes
})]
}));
}
});
});
var _default = exports.default = svgBackdrop;