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

21
node_modules/@marp-team/marpit/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018- Marp team (marp-team@marp.app)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

81
node_modules/@marp-team/marpit/README.md generated vendored Normal file
View File

@@ -0,0 +1,81 @@
<p align="center">
<img src="docs/marpit.png#gh-light-mode-only" alt="Marpit" width="500" />
<img src="docs/marpit-dark.png#gh-dark-mode-only" alt="Marpit" width="500" />
</p>
<p align="center">
<strong>Marpit</strong>: Markdown slide deck framework
</p>
<p align="center">
<a href="https://circleci.com/gh/marp-team/marpit/"><img src="https://img.shields.io/circleci/project/github/marp-team/marpit/main.svg?style=flat-square&logo=circleci" alt="CircleCI" /></a>
<a href="https://codecov.io/gh/marp-team/marpit"><img src="https://img.shields.io/codecov/c/github/marp-team/marpit/main.svg?style=flat-square&logo=codecov" alt="Codecov" /></a>
<a href="https://www.npmjs.com/package/@marp-team/marpit"><img src="https://img.shields.io/npm/v/@marp-team/marpit.svg?style=flat-square&logo=npm" alt="npm" /></a>
<a href="./LICENSE"><img src="https://img.shields.io/github/license/marp-team/marpit.svg?style=flat-square" alt="LICENSE" /></a>
</p>
<div align="center">
### [🗒 Documentation](https://marpit.marp.app/) | [⚙ API](https://marpit-api.marp.app/)
</div>
---
**Marpit** /mɑːrpɪt/ is the skinny framework for creating slide deck from Markdown. It can transform Markdown and CSS theme(s) to slide deck composed of static HTML and CSS and create a web page convertible into slide PDF by printing.
Marpit is designed to _output minimum assets for the slide deck_. You can use the bare assets as a logicless slide deck, but mainly we expect to integrate output with other tools and applications.
In fact, this framework is created for using as the base of [a core converter][marp-core] in [Marp ecosystem][marp].
[marp]: https://github.com/marp-team/marp/
[marp-core]: https://github.com/marp-team/marp-core/
## Features
### [:pencil: **Marpit Markdown**](https://marpit.marp.app/markdown)
We have extended several features into [markdown-it](https://github.com/markdown-it/markdown-it) parser to support writing awesome slides, such as [_Directives_](https://marpit.marp.app/directives) and [_Slide backgrounds_](https://marpit.marp.app/image-syntax?id=slide-backgrounds). Additional syntaxes place importance on a compatibility with general Markdown documents.
### [:art: **Theme CSS by clean markup**](https://marpit.marp.app/theme-css)
Marpit has the CSS theming system that can design slides everything. Unlike other slide frameworks, there are not any predefined classes and mixins. You have only to focus styling HTML elements by pure CSS. Marpit would take care of the selected theme's necessary conversion.
### [:triangular_ruler: **Inline SVG slide**](https://marpit.marp.app/inline-svg) _(Experimental)_
Optionally `<svg>` element can use as the container of each slide page. It can be realized the pixel-perfect scaling of the slide only by CSS, so handling slides in integrated apps become simplified. The isolated layer made by `<foreignObject>` can provide [_advanced backgrounds_](https://marpit.marp.app/image-syntax?id=advanced-backgrounds) for the slide with keeping the original Markdown DOM structure.
> We not provide any themes because Marpit is just a framework. You can use [@marp-team/marp-core][marp-core] if you want. It has the official themes, and practical features extended from Marpit.
## Getting started
See [the documentation of Marpit](https://marpit.marp.app/?id=getting-started) to get started.
- **[Documentation](https://marpit.marp.app/)**
- [API (JSDoc)](https://marpit-api.marp.app/)
## Contributing
Are you interested in contributing? See [CONTRIBUTING.md](.github/CONTRIBUTING.md) and [the common contributing guideline for Marp team](https://github.com/marp-team/.github/blob/master/CONTRIBUTING.md).
### Development
```bash
git clone https://github.com/marp-team/marpit
cd marpit
npm install
npm run build
```
## Sub-projects
- **[@marp-team/marpit-svg-polyfill](https://github.com/marp-team/marpit-svg-polyfill)** - A polyfill of the inline SVG slide in Safari based browsers.
## Author
Managed by [@marp-team](https://github.com/marp-team).
- <img src="https://github.com/yhatt.png" width="16" height="16"/> Yuki Hattori ([@yhatt](https://github.com/yhatt))
## License
This framework releases under the [MIT License](LICENSE).

167
node_modules/@marp-team/marpit/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,167 @@
declare namespace MarpitEnv {
interface HTMLAsArray {
htmlAsArray: true
[key: string]: any
}
}
declare namespace Marpit {
interface Options {
anchor?: boolean | AnchorCallback
container?: false | Element | Element[]
cssContainerQuery?: boolean | string | string[]
cssNesting?: boolean
headingDivider?: false | HeadingDivider | HeadingDivider[]
lang?: string
looseYAML?: boolean
markdown?: any
printable?: boolean
slideContainer?: false | Element | Element[]
inlineSVG?: boolean | InlineSVGOptions
}
type AnchorCallback = (index: number) => string
type HeadingDivider = 1 | 2 | 3 | 4 | 5 | 6
type InlineSVGOptions = {
enabled?: boolean
backdropSelector?: boolean
}
type RenderResult<T = string> = {
html: T
css: string
comments: string[][]
}
type DirectiveDefinitions = {
[directive: string]: (
value: string | object | (string | object)[],
marpit?: Marpit,
) => { [meta: string]: any }
}
type Plugin<P extends any[], T extends {} = {}> = (
this: Marpit['markdown'] & T,
md: Marpit['markdown'] & T,
...params: P
) => void
type ThemeMetaType = {
[key: string]: StringConstructor | ArrayConstructor
}
type ThemeReservedMeta = {
theme: string
}
interface ThemeSetOptions {
cssNesting?: boolean
}
type ThemeOptions = {
cssNesting?: boolean
metaType?: ThemeMetaType
}
type ThemeSetPackOptions = {
after?: string
before?: string
containers?: Element[]
printable?: boolean
inlineSVG?: boolean
}
type PluginFactory = <P extends any[]>(
plugin: Plugin<P, { marpit: Marpit }>,
) => Plugin<P, { marpit: Marpit }>
export class Marpit {
constructor(opts?: Options)
markdown: any
themeSet: ThemeSet
readonly customDirectives: {
global: DirectiveDefinitions
local: DirectiveDefinitions
}
readonly options: Options
protected lastComments: RenderResult['comments'] | undefined
protected lastGlobalDirectives: { [directive: string]: any } | undefined
protected lastSlideTokens: any[] | undefined
protected lastStyles: string[] | undefined
render(markdown: string, env: MarpitEnv.HTMLAsArray): RenderResult<string[]>
render(markdown: string, env?: any): RenderResult
use<P extends any[]>(plugin: Plugin<P>, ...params: P): this
protected applyMarkdownItPlugins(md: any): void
protected renderMarkdown(markdown: string, env?: any): string
protected renderStyle(theme?: string): string
protected themeSetPackOptions(): ThemeSetPackOptions
}
export class Element {
constructor(tag: string, attributes?: {})
[index: string]: any
tag: string
}
export class Theme {
protected constructor(name: string, css: string)
static fromCSS(cssString: string, opts?: ThemeOptions): Readonly<Theme>
css: string
height: string
importRules: {
node: any
value: string
}[]
meta: Readonly<ThemeReservedMeta & Record<string, string | string[]>>
name: string
width: string
readonly heightPixel: number | undefined
readonly widthPixel: number | undefined
}
export class ThemeSet {
constructor(opts?: ThemeSetOptions)
cssNesting: boolean
default: Theme | undefined
metaType: ThemeMetaType
readonly size: number
private readonly themeMap: Map<string, Theme>
add(css: string): Theme
addTheme(theme: Theme): void
clear(): void
delete(name: string): boolean
get(name: string, fallback?: boolean): Theme | undefined
getThemeMeta(
theme: string | Theme,
meta: string,
): string | string[] | undefined
getThemeProp(theme: string | Theme, prop: string): any
has(name: string): boolean
pack(name: string, opts: ThemeSetPackOptions): string
themes(): IterableIterator<Theme>
}
}
declare module '@marp-team/marpit' {
export = Marpit
}
declare module '@marp-team/marpit/plugin' {
export const marpitPlugin: Marpit.PluginFactory
export default marpitPlugin
}

66
node_modules/@marp-team/marpit/lib/element.js generated vendored Normal file
View File

@@ -0,0 +1,66 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.marpitContainer = exports.default = void 0;
/** @module */
/**
* Marpit element class.
*
* @alias Element
*/
class Element {
/**
* Create a Element instance.
*
* Element instance has compatibility with a plain object that is consists by
* `tag` key and pairs of attribute names and values. A difference is whether
* object has been frozen.
*
* ```js
* import assert from 'assert'
* import { Element } from 'marpit'
*
* const obj = { tag: 'div', class: 'marpit' }
* const elm = new Element('div', { class: 'marpit' })
*
* // This assertion would pass.
* assert.deepStrictEqual(obj, { ...elm })
* ```
*
* @param {string} tag Tag name
* @param {Object} [attributes={}] Tag attributes
*/
constructor(tag, attributes = {}) {
Object.defineProperties(this, {
attributes: {
value: attributes
},
tag: {
enumerable: true,
value: tag
}
});
for (const attr of Object.keys(attributes)) {
Object.defineProperty(this, attr, {
enumerable: true,
value: attributes[attr]
});
}
Object.freeze(this);
}
}
/**
* Marpit's default container.
*
* It would output `<div class="marpit"></div>`.
*
* @alias module:element.marpitContainer
* @type {Element}
*/
const marpitContainer = exports.marpitContainer = new Element('div', {
class: 'marpit'
});
var _default = exports.default = Element;

View File

@@ -0,0 +1,92 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _postcss = _interopRequireDefault(require("postcss"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/**
* InlineStyle helper class.
*
* This is the declarative builder of an inline style using PostCSS. The output
* string by `toString()` is sanitized unexpected declarations.
*
* @module
* @alias module:helpers/inline_style
*/
class InlineStyle {
/**
* Create an InlineStyle instance.
*
* @function constructor
* @param {Object|String|InlineStyle} [initialDecls] The initial declarations.
*/
constructor(initialDecls) {
this.decls = {};
if (initialDecls) {
if (initialDecls instanceof InlineStyle || typeof initialDecls === 'string') {
const root = _postcss.default.parse(initialDecls.toString(), {
from: undefined
});
root.each(node => {
if (node.type === 'decl') this.decls[node.prop] = node.value;
});
} else {
this.decls = {
...initialDecls
};
}
}
}
/**
* Delete declaration.
*
* @param {string} prop A property name of declaration.
* @returns {InlineStyle} Returns myself for chaining methods.
*/
delete(prop) {
delete this.decls[prop];
return this;
}
/**
* Set declaration.
*
* @param {string} prop A property name of declaration.
* @param {string} value A value of declaration.
* @returns {InlineStyle} Returns myself for chaining methods.
*/
set(prop, value) {
this.decls[prop] = value;
return this;
}
/**
* Build a string of declarations for the inline style.
*
* The unexpected declarations will strip to prevent a style injection.
*/
toString() {
let built = '';
for (const prop of Object.keys(this.decls)) {
let parsed;
try {
parsed = _postcss.default.parse(`${prop}:${this.decls[prop]}`, {
from: undefined
});
} catch {
// A declaration that have value it cannot parse will ignore.
}
if (parsed) {
parsed.each(node => {
if (node.type !== 'decl' || node.prop !== prop) node.remove();
});
built += `${parsed.toString()};`;
}
}
return built;
}
}
exports.default = InlineStyle;

View File

@@ -0,0 +1,32 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
exports.plugin = plugin;
/** @module */
/**
* Generate PostCSS plugin.
*
* This is a glue code generator to migrate existed plugins to support
* PostCSS 8.
*
* @param {string} name Plugin name.
* @param {(Function|Object)} func Function with PostCSS plugin interface.
* @returns {Function} A PostCSS plugin.
*/
function plugin(name, func) {
return Object.defineProperty(function intrface(...args) {
const retFunc = func.apply(this, args);
return Object.defineProperty(typeof retFunc === 'function' ? {
Once: retFunc
} : retFunc, 'postcssPlugin', {
value: name
});
}, 'postcss', {
value: true
});
}
var _default = exports.default = plugin;

35
node_modules/@marp-team/marpit/lib/helpers/split.js generated vendored Normal file
View File

@@ -0,0 +1,35 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
exports.split = split;
/** @module */
/**
* Split array into multiple arrays by specified condition.
*
* @param {Array} arr Target array.
* @param {splitCallback} func Callback to split array.
* @param {boolean} [keepSplitedValue=false] Keep splited value. The split
* point is before the matched value.
* @returns {Array[]} Splited array.
*/
function split(arr, func, keepSplitedValue = false) {
const ret = [[]];
for (const value of arr) {
/**
* Return true at the split point.
*
* @callback splitCallback
* @param {*} value
*/
if (func(value)) {
ret.push(keepSplitedValue ? [value] : []);
} else {
ret[ret.length - 1].push(value);
}
}
return ret;
}
var _default = exports.default = split;

View File

@@ -0,0 +1,21 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.wrapArray = exports.default = void 0;
/** @module */
/**
* Wrap value in array if it is not an array.
*
* @function wrapArray
* @param {*} valOrArr
* @return {Array}
*/
const wrapArray = valOrArr => {
if (valOrArr == null || valOrArr === false) return [];
if (valOrArr instanceof Array) return valOrArr;
return [valOrArr];
};
exports.wrapArray = wrapArray;
var _default = exports.default = wrapArray;

View File

@@ -0,0 +1,47 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
exports.wrapTokens = wrapTokens;
/** @module */
/**
* Wrap array of tokens by specified container object.
*
* @param {Token} Token markdown-it's Token class.
* @param {String} type Token type. It will be suffixed by `_open` / `_close`.
* @param {Object} container A container object to wrap tokens, includes tag
* name and attributes.
* @param {String} container.tag The name of container element.
* @param {Object} [container.open] The object assigning to an opening token.
* @param {Object} [container.close] The object assigning to a closing token.
* @param {Token[]} [tokens=[]] Wrapping tokens.
* @returns {Token[]} Wrapped tokens.
*/
function wrapTokens(Token, type, container, tokens = []) {
const {
tag
} = container;
// Update nesting level of wrapping tokens
for (const t of tokens) t.level += 1;
// Create markdown-it tokens
const open = new Token(`${type}_open`, tag, 1);
const close = new Token(`${type}_close`, tag, -1);
Object.assign(open, {
...(container.open || {})
});
Object.assign(close, {
...(container.close || {})
});
// Assign attributes
for (const attr of Object.keys(container)) {
if (!['open', 'close', 'tag'].includes(attr) && container[attr] != null) open.attrSet(attr, container[attr]);
}
return [open, ...tokens, close];
}
var _default = exports.default = wrapTokens;

36
node_modules/@marp-team/marpit/lib/index.js generated vendored Normal file
View File

@@ -0,0 +1,36 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "Element", {
enumerable: true,
get: function () {
return _element.default;
}
});
Object.defineProperty(exports, "Marpit", {
enumerable: true,
get: function () {
return _marpit.default;
}
});
Object.defineProperty(exports, "Theme", {
enumerable: true,
get: function () {
return _theme.default;
}
});
Object.defineProperty(exports, "ThemeSet", {
enumerable: true,
get: function () {
return _theme_set.default;
}
});
exports.default = void 0;
var _element = _interopRequireDefault(require("./element"));
var _marpit = _interopRequireDefault(require("./marpit"));
var _theme = _interopRequireDefault(require("./theme"));
var _theme_set = _interopRequireDefault(require("./theme_set"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
var _default = exports.default = _marpit.default;

View File

@@ -0,0 +1,36 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.backgroundImage = void 0;
var _plugin = _interopRequireDefault(require("../plugin"));
var _advanced = _interopRequireDefault(require("./background_image/advanced"));
var _apply = _interopRequireDefault(require("./background_image/apply"));
var _parse = _interopRequireDefault(require("./background_image/parse"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
/**
* Marpit background image plugin.
*
* Convert image token to backgrounds when the alternate text includes `bg`.
*
* When Marpit inline SVG mode is disabled, the image will convert to
* `backgroundImage` and `backgroundSize` spot directive. It supports only
* single background and resizing by using CSS.
*
* When inline SVG mode is enabled, the plugin enables advanced background mode.
* In addition to the basic background implementation, it supports multiple
* background images, filters, and split background.
*
* @function backgroundImage
* @param {MarkdownIt} md markdown-it instance.
*/
function _backgroundImage(md) {
(0, _parse.default)(md);
(0, _apply.default)(md);
(0, _advanced.default)(md);
}
const backgroundImage = exports.backgroundImage = (0, _plugin.default)(_backgroundImage);
var _default = exports.default = backgroundImage;

View File

@@ -0,0 +1,142 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.advancedBackground = void 0;
var _inline_style = _interopRequireDefault(require("../../helpers/inline_style"));
var _wrap_tokens = require("../../helpers/wrap_tokens");
var _plugin = _interopRequireDefault(require("../../plugin"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
/**
* Marpit advanced background image plugin.
*
* Support the advanced features for background image, by using `<figure>`
* element(s) instead of CSS backgrounds. It works by creating the isolated
* layer into inline SVG.
*
* @function advancedBackground
* @param {MarkdownIt} md markdown-it instance.
*/
function _advancedBackground(md) {
md.core.ruler.after('marpit_directives_apply', 'marpit_advanced_background', state => {
let current;
const newTokens = [];
for (const t of state.tokens) {
if (t.type === 'marpit_inline_svg_content_open' && t.meta && t.meta.marpitBackground) {
current = t;
const {
height,
images,
open,
width
} = t.meta.marpitBackground;
open.attrSet('data-marpit-advanced-background', 'content');
// Aligned direction
const direction = t.meta.marpitBackground.direction || 'horizontal';
// Split backgrounds
const splitSide = t.meta.marpitBackground.split;
if (splitSide) {
open.attrSet('data-marpit-advanced-background-split', splitSide);
const splitBgSize = t.meta.marpitBackground.splitSize || '50%';
t.attrSet('width', `${100 - Number.parseFloat(splitBgSize.slice(0, -1))}%`);
if (splitSide === 'left') t.attrSet('x', splitBgSize);
const style = new _inline_style.default(open.attrGet('style'));
style.set('--marpit-advanced-background-split', splitBgSize);
open.attrSet('style', style.toString());
}
// Add the isolated layer for background image
newTokens.push(...(0, _wrap_tokens.wrapTokens)(state.Token, 'marpit_advanced_background_foreign_object', {
tag: 'foreignObject',
width,
height
}, (0, _wrap_tokens.wrapTokens)(state.Token, 'marpit_advanced_background_section', {
...open.attrs.reduce((o, [k, v]) => ({
...o,
[k]: v
}), {}),
tag: 'section',
id: undefined,
'data-marpit-advanced-background': 'background'
}, (0, _wrap_tokens.wrapTokens)(state.Token, 'marpit_advanced_background_image_container', {
tag: 'div',
'data-marpit-advanced-background-container': true,
'data-marpit-advanced-background-direction': direction
}, (() => {
const imageTokens = [];
// Add multiple image elements
for (const img of images) {
const style = new _inline_style.default({
'background-image': `url("${img.url}")`
});
// Image sizing
if (img.size) style.set('background-size', img.size);
// Image filter for backgrounds (Only in advanced BG)
if (img.filter) style.set('filter', img.filter);
imageTokens.push(...(0, _wrap_tokens.wrapTokens)(state.Token, 'marpit_advanced_background_image', {
tag: 'figure',
style: style.toString(),
open: {
meta: {
marpitBackgroundAlt: img.alt
}
}
}));
}
return imageTokens;
})()))), t);
} else if (current && t.type === 'marpit_inline_svg_content_close') {
const {
open,
height,
width
} = current.meta.marpitBackground;
// Apply styles
const style = new _inline_style.default();
if (open.meta && open.meta.marpitDirectives && open.meta.marpitDirectives.color) style.set('color', open.meta.marpitDirectives.color);
// Add the isolated layer for pseudo contents (e.g. Page number)
newTokens.push(t, ...(0, _wrap_tokens.wrapTokens)(state.Token, 'marpit_advanced_background_foreign_object', {
tag: 'foreignObject',
width,
height,
'data-marpit-advanced-background': 'pseudo'
}, (0, _wrap_tokens.wrapTokens)(state.Token, 'marpit_advanced_pseudo_section', {
...open.attrs.reduce((o, [k, v]) => ({
...o,
[k]: v
}), {}),
tag: 'section',
id: undefined,
style: style.toString(),
'data-marpit-advanced-background': 'pseudo'
})));
current = undefined;
} else {
newTokens.push(t);
}
}
state.tokens = newTokens;
});
// Renderer for advanced background image
md.renderer.rules.marpit_advanced_background_image_open = (tokens, idx, options, _env, self) => {
const token = tokens[idx];
const open = self.renderToken(tokens, idx, options);
if (token.meta?.marpitBackgroundAlt) {
return `${open}<figcaption>${md.utils.escapeHtml(token.meta.marpitBackgroundAlt)}</figcaption>`;
}
return open;
};
}
const advancedBackground = exports.advancedBackground = (0, _plugin.default)(_advancedBackground);
var _default = exports.default = advancedBackground;

View File

@@ -0,0 +1,111 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.backgroundImageApply = void 0;
var _plugin = _interopRequireDefault(require("../../plugin"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
/**
* Marpit background image apply plugin.
*
* Apply parsed meta for background image / color into directives of each page.
*
* When inline SVG is enabled, it will reshape meta for advanced process instead
* of converting to directives.
*
* @function backgroundImageApply
* @param {MarkdownIt} md markdown-it instance.
*/
function _backgroundImageApply(md) {
md.core.ruler.after('marpit_inline_svg', 'marpit_apply_background_image', ({
inlineMode,
tokens
}) => {
if (inlineMode) return;
let current = {};
for (const tb of tokens) {
if (tb.type === 'marpit_slide_open') current.open = tb;
if (tb.type === 'marpit_inline_svg_content_open') current.svgContent = tb;
if (tb.type === 'marpit_slide_close') {
if (current.images && current.images.length > 0) {
if (current.svgContent) {
// Reshape meta for advanced background
current.svgContent.meta = {
...(current.svgContent.meta || {}),
marpitBackground: {
direction: current.direction,
height: current.svgContent.attrGet('height'),
images: current.images,
open: current.open,
split: current.split,
splitSize: current.splitSize,
width: current.svgContent.attrGet('width')
}
};
} else {
// Apply simple CSS background
const img = current.images[current.images.length - 1];
current.open.meta.marpitDirectives = {
...(current.open.meta.marpitDirectives || {}),
backgroundImage: `url("${img.url}")`
};
if (img.size) current.open.meta.marpitDirectives.backgroundSize = img.size;
}
}
current = {};
}
// Collect parsed inline image meta
if (current.open && tb.type === 'inline') for (const t of tb.children) {
if (t.type === 'image') {
const {
background,
backgroundDirection,
backgroundSize,
backgroundSplit,
backgroundSplitSize,
color,
filter,
height,
size,
url,
width,
options
} = t.meta.marpitImage;
if (background && !url.match(/^\s*$/)) {
if (color) {
// Background color
current.open.meta.marpitDirectives = {
...(current.open.meta.marpitDirectives || {}),
backgroundColor: color
};
} else {
// Background image
let altText = '';
for (const opt of options) if (!opt.consumed) altText += opt.leading + opt.content;
current.images = [...(current.images || []), {
filter,
height,
size: (() => {
const s = size || backgroundSize || undefined;
return !['contain', 'cover'].includes(s) && (width || height) ? `${width || s || 'auto'} ${height || s || 'auto'}` : s;
})(),
url,
width,
alt: altText.trimStart()
}];
}
}
if (backgroundDirection) current.direction = backgroundDirection;
if (backgroundSplit) current.split = backgroundSplit;
if (backgroundSplitSize) current.splitSize = backgroundSplitSize;
}
}
}
});
}
const backgroundImageApply = exports.backgroundImageApply = (0, _plugin.default)(_backgroundImageApply);
var _default = exports.default = backgroundImageApply;

View File

@@ -0,0 +1,77 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.backgroundImageParse = void 0;
var _plugin = _interopRequireDefault(require("../../plugin"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
const bgSizeKeywords = {
auto: 'auto',
contain: 'contain',
cover: 'cover',
fit: 'contain'
};
const splitSizeMatcher = /^(left|right)(?::((?:\d*\.)?\d+%))?$/;
/**
* Marpit background image parse plugin.
*
* Parse Marpit's image token and mark as background image when the alternate
* text includes `bg`. The marked images will not show as the regular image.
*
* Furthermore, it parses additional keywords needed for background image.
*
* @function backgroundImageParse
* @param {MarkdownIt} md markdown-it instance.
*/
function _backgroundImageParse(md) {
md.inline.ruler2.after('marpit_parse_image', 'marpit_background_image', ({
tokens
}) => {
for (const t of tokens) {
if (t.type === 'image') {
const {
marpitImage
} = t.meta;
if (marpitImage.options.some(v => !v.consumed && v.content === 'bg')) {
marpitImage.background = true;
t.hidden = true;
for (const opt of marpitImage.options) {
if (opt.consumed) continue;
let consumed = false;
// bg keyword
if (opt.content === 'bg') consumed = true;
// Background size keyword
if (bgSizeKeywords[opt.content]) {
marpitImage.backgroundSize = bgSizeKeywords[opt.content];
consumed = true;
}
// Split background keyword
const matched = opt.content.match(splitSizeMatcher);
if (matched) {
const [, splitSide, splitSize] = matched;
marpitImage.backgroundSplit = splitSide;
marpitImage.backgroundSplitSize = splitSize;
consumed = true;
}
// Background aligned direction
if (opt.content === 'vertical' || opt.content === 'horizontal') {
marpitImage.backgroundDirection = opt.content;
consumed = true;
}
if (consumed) opt.consumed = true;
}
}
}
}
});
}
const backgroundImageParse = exports.backgroundImageParse = (0, _plugin.default)(_backgroundImageParse);
var _default = exports.default = backgroundImageParse;

59
node_modules/@marp-team/marpit/lib/markdown/collect.js generated vendored Normal file
View File

@@ -0,0 +1,59 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.collect = void 0;
var _plugin = _interopRequireDefault(require("../plugin"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
/**
* Marpit collect plugin.
*
* Collect parsed tokens per slide and comments except marked as used for
* internally. These will store to lastSlideTokens and lastComments member of
* Marpit instance. It would use in the returned object from
* {@link Marpit#render}.
*
* @function collect
* @param {MarkdownIt} md markdown-it instance.
*/
function _collect(md) {
const {
marpit
} = md;
md.core.ruler.push('marpit_collect', state => {
if (state.inlineMode) return;
marpit.lastComments = [];
marpit.lastSlideTokens = [];
let currentPage;
let pageIdx = -1;
const collectComment = token => {
if (currentPage >= 0 && !(token.meta && token.meta.marpitCommentParsed !== undefined)) marpit.lastComments[currentPage].push(token.content);
};
const collectable = () => currentPage >= 0 && marpit.lastSlideTokens[currentPage] !== undefined;
for (const token of state.tokens) {
if (token.meta && token.meta.marpitSlideElement === 1) {
pageIdx += 1;
currentPage = pageIdx;
if (marpit.lastSlideTokens[currentPage] === undefined) {
marpit.lastSlideTokens[currentPage] = [token];
marpit.lastComments[currentPage] = [];
}
} else if (token.meta && token.meta.marpitSlideElement === -1) {
if (collectable()) marpit.lastSlideTokens[currentPage].push(token);
currentPage = undefined;
} else {
if (collectable()) marpit.lastSlideTokens[currentPage].push(token);
if (token.type === 'marpit_comment') {
collectComment(token);
} else if (token.type === 'inline') {
for (const t of token.children) if (t.type === 'marpit_comment') collectComment(t);
}
}
}
});
}
const collect = exports.collect = (0, _plugin.default)(_collect);
var _default = exports.default = collect;

108
node_modules/@marp-team/marpit/lib/markdown/comment.js generated vendored Normal file
View File

@@ -0,0 +1,108 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.comment = void 0;
exports.markAsParsed = markAsParsed;
var _plugin = _interopRequireDefault(require("../plugin"));
var _yaml = require("./directives/yaml");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
const commentMatcher = /<!--+\s*([\s\S]*?)\s*--+>/;
const commentMatcherOpening = /^<!--/;
const commentMatcherClosing = /-->/;
const magicCommentMatchers = [
// Prettier
/^prettier-ignore(-(start|end))?$/,
// markdownlint
/^markdownlint-((disable|enable).*|capture|restore)$/,
// remark-lint (remark-message-control)
/^lint (disable|enable|ignore).*$/];
function markAsParsed(token, kind) {
token.meta = token.meta || {};
token.meta.marpitCommentParsed = kind;
}
/**
* Marpit comment plugin.
*
* Parse HTML comment as token. Comments will strip regardless of html setting
* provided by markdown-it.
*
* @function comment
* @param {MarkdownIt} md markdown-it instance.
*/
function _comment(md) {
const parse = (token, content) => {
const parsed = (0, _yaml.yaml)(content, !!md.marpit.options.looseYAML);
token.meta = token.meta || {};
token.meta.marpitParsedDirectives = parsed === false ? {} : parsed;
// Mark well-known magic comments as parsed comment
for (const magicCommentMatcher of magicCommentMatchers) {
if (magicCommentMatcher.test(content.trim())) {
markAsParsed(token, 'well-known-magic-comment');
break;
}
}
};
md.block.ruler.before('html_block', 'marpit_comment', (state, startLine, endLine, silent) => {
// Fast fail
let pos = state.bMarks[startLine] + state.tShift[startLine];
if (state.src.charCodeAt(pos) !== 0x3c) return false;
let max = state.eMarks[startLine];
let line = state.src.slice(pos, max);
// Match to opening element
if (!commentMatcherOpening.test(line)) return false;
if (silent) return true;
// Parse ending element
let nextLine = startLine + 1;
if (!commentMatcherClosing.test(line)) {
while (nextLine < endLine) {
if (state.sCount[nextLine] < state.blkIndent) break;
pos = state.bMarks[nextLine] + state.tShift[nextLine];
max = state.eMarks[nextLine];
line = state.src.slice(pos, max);
nextLine += 1;
if (commentMatcherClosing.test(line)) break;
}
}
state.line = nextLine;
// Create token
const token = state.push('marpit_comment', '', 0);
token.map = [startLine, nextLine];
token.markup = state.getLines(startLine, nextLine, state.blkIndent, true);
token.hidden = true;
const matchedContent = commentMatcher.exec(token.markup);
token.content = matchedContent ? matchedContent[1].trim() : '';
parse(token, token.content);
return true;
});
md.inline.ruler.before('html_inline', 'marpit_inline_comment', (state, silent) => {
const {
posMax,
src
} = state;
// Quick fail by checking `<` and `!`
if (state.pos + 2 >= posMax || src.charCodeAt(state.pos) !== 0x3c || src.charCodeAt(state.pos + 1) !== 0x21) return false;
const match = src.slice(state.pos).match(commentMatcher);
if (!match) return false;
if (!silent) {
const token = state.push('marpit_comment', '', 0);
token.hidden = true;
token.markup = src.slice(state.pos, state.pos + match[0].length);
token.content = match[1].trim();
parse(token, token.content);
}
state.pos += match[0].length;
return true;
});
}
const comment = exports.comment = (0, _plugin.default)(_comment);
var _default = exports.default = comment;

View File

@@ -0,0 +1,29 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.container = void 0;
var _wrap_array = require("../helpers/wrap_array");
var _wrap_tokens = require("../helpers/wrap_tokens");
var _plugin = _interopRequireDefault(require("../plugin"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
/**
* Marpit container plugin.
*
* @function container
* @param {MarkdownIt} md markdown-it instance.
*/
function _container(md) {
const containers = (0, _wrap_array.wrapArray)(md.marpit.options.container);
if (!containers) return;
const target = [...containers].reverse();
md.core.ruler.push('marpit_containers', state => {
if (state.inlineMode) return;
for (const cont of target) state.tokens = (0, _wrap_tokens.wrapTokens)(state.Token, 'marpit_containers', cont, state.tokens);
});
}
const container = exports.container = (0, _plugin.default)(_container);
var _default = exports.default = container;

View File

@@ -0,0 +1,98 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.apply = void 0;
var _lodash = _interopRequireDefault(require("lodash.kebabcase"));
var _inline_style = _interopRequireDefault(require("../../helpers/inline_style"));
var _plugin = _interopRequireDefault(require("../../plugin"));
var _directives = _interopRequireDefault(require("./directives"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
/**
* Apply parsed Marpit directives to markdown-it tokens.
*
* @function apply
* @param {MarkdownIt} md markdown-it instance.
* @param {Object} [opts]
* @param {boolean} [opts.dataset=true] Assigns directives as HTML data
* attributes of each section tag.
* @param {boolean} [opts.css=true] Assigns directives as CSS Custom Properties
* of each section tag.
*/
function _apply(md, opts = {}) {
const {
marpit
} = md;
const {
lang
} = marpit.options;
const dataset = opts.dataset === undefined ? true : !!opts.dataset;
const css = opts.css === undefined ? true : !!opts.css;
const {
global,
local
} = marpit.customDirectives;
const directives = [...Object.keys(global), ...Object.keys(local), ..._directives.default];
md.core.ruler.after('marpit_directives_parse', 'marpit_directives_apply', state => {
if (state.inlineMode) return;
let pageNumber = 0;
const tokensForPaginationTotal = [];
for (const token of state.tokens) {
const {
marpitDirectives
} = token.meta || {};
if (token.type === 'marpit_slide_open') {
// `skip` and `hold` disable increment of the page number
if (!(marpitDirectives?.paginate === 'skip' || marpitDirectives?.paginate === 'hold')) {
pageNumber += 1;
}
}
if (marpitDirectives) {
const style = new _inline_style.default(token.attrGet('style'));
for (const dir of Object.keys(marpitDirectives)) {
if (directives.includes(dir)) {
const value = marpitDirectives[dir];
if (value) {
const kebabCaseDir = (0, _lodash.default)(dir);
if (dataset) token.attrSet(`data-${kebabCaseDir}`, value);
if (css) style.set(`--${kebabCaseDir}`, value);
}
}
}
// Apply attribute to token
if (marpitDirectives.lang || lang) token.attrSet('lang', marpitDirectives.lang || lang);
if (marpitDirectives.class) token.attrJoin('class', marpitDirectives.class);
if (marpitDirectives.color) style.set('color', marpitDirectives.color);
if (marpitDirectives.backgroundColor) style.set('background-color', marpitDirectives.backgroundColor).set('background-image', 'none');
if (marpitDirectives.backgroundImage) {
style.set('background-image', marpitDirectives.backgroundImage).set('background-position', 'center').set('background-repeat', 'no-repeat').set('background-size', 'cover');
if (marpitDirectives.backgroundPosition) style.set('background-position', marpitDirectives.backgroundPosition);
if (marpitDirectives.backgroundRepeat) style.set('background-repeat', marpitDirectives.backgroundRepeat);
if (marpitDirectives.backgroundSize) style.set('background-size', marpitDirectives.backgroundSize);
}
if (marpitDirectives.paginate && marpitDirectives.paginate !== 'skip') {
// If the page number was still not incremented, mark this page as
// the first page.
if (pageNumber <= 0) pageNumber = 1;
token.attrSet('data-marpit-pagination', pageNumber);
tokensForPaginationTotal.push(token);
}
if (marpitDirectives.header) token.meta.marpitHeader = marpitDirectives.header;
if (marpitDirectives.footer) token.meta.marpitFooter = marpitDirectives.footer;
const styleStr = style.toString();
if (styleStr !== '') token.attrSet('style', styleStr);
}
}
// Set total page number to each slide page that has pagination attribute
for (const token of tokensForPaginationTotal) {
token.attrSet('data-marpit-pagination-total', pageNumber);
}
});
}
const apply = exports.apply = (0, _plugin.default)(_apply);
var _default = exports.default = apply;

View File

@@ -0,0 +1,126 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.locals = exports.globals = exports.default = void 0;
/**
* The definition of Marpit directives
* @module
*/
/**
* @typedef {Function} Directive
* @param {string} value Parsed value.
* @param {Marpit} marpit Marpit instance.
* @returns {Object} Assigning object to token meta.
*/
/**
* Global directives.
*
* Each global directive assigns to the whole slide deck. If you wrote a same
* directive many times, Marpit only recognizes the last value.
*
* @prop {Directive} headingDivider Specify heading divider option.
* @prop {Directive} style Specify the CSS style to apply additionally.
* @prop {Directive} theme Specify theme of the slide deck.
* @prop {Directive} lang Specify the language of the slide deck. It will
* assign as `lang` attribute for each slide.
*/
const globals = exports.globals = Object.assign(Object.create(null), {
headingDivider: value => {
const headings = [1, 2, 3, 4, 5, 6];
const toInt = v => Array.isArray(v) || Number.isNaN(v) ? v : Number.parseInt(v, 10);
const converted = toInt(value);
if (Array.isArray(converted)) {
const convertedArr = converted.map(toInt);
return {
headingDivider: headings.filter(v => convertedArr.includes(v))
};
}
if (value === 'false') return {
headingDivider: false
};
if (headings.includes(converted)) return {
headingDivider: converted
};
return {};
},
style: v => ({
style: v
}),
theme: (v, marpit) => marpit.themeSet.has(v) ? {
theme: v
} : {},
lang: v => ({
lang: v
})
});
/**
* Local directives.
*
* Mainly these are used to change settings each slide page. By default, a
* local directive applies to the defined page and followed pages.
*
* If you want to set a local directive to single page only, you can add the
* prefix `_` (underbar) to directive name. (Spot directives)
*
* @prop {Directive} backgroundColor Specify background-color style.
* @prop {Directive} backgroundImage Specify background-image style.
* @prop {Directive} backgroundPosition Specify background-position style. The
* default value while setting backgroundImage is `center`.
* @prop {Directive} backgroundRepeat Specify background-repeat style. The
* default value while setting backgroundImage is `no-repeat`.
* @prop {Directive} backgroundSize Specify background-size style. The default
* value while setting backgroundImage is `cover`.
* @prop {Directive} class Specify HTML class of section element(s).
* @prop {Directive} color Specify color style (base text color).
* @prop {Directive} footer Specify the content of slide footer. It will insert
* a `<footer>` element to the last of each slide contents.
* @prop {Directive} header Specify the content of slide header. It will insert
* a `<header>` element to the first of each slide contents.
* @prop {Directive} paginate Show page number on the slide if you set `true`.
* `hold` and `skip` are also available to disable increment of the page
* number.
*/
const locals = exports.locals = Object.assign(Object.create(null), {
backgroundColor: v => ({
backgroundColor: v
}),
backgroundImage: v => ({
backgroundImage: v
}),
backgroundPosition: v => ({
backgroundPosition: v
}),
backgroundRepeat: v => ({
backgroundRepeat: v
}),
backgroundSize: v => ({
backgroundSize: v
}),
class: v => ({
class: Array.isArray(v) ? v.join(' ') : v
}),
color: v => ({
color: v
}),
footer: v => typeof v === 'string' ? {
footer: v
} : {},
header: v => typeof v === 'string' ? {
header: v
} : {},
paginate: v => {
const normalized = (v || '').toLowerCase();
if (['hold', 'skip'].includes(normalized)) return {
paginate: normalized
};
return {
paginate: normalized === 'true'
};
}
});
var _default = exports.default = [...Object.keys(globals), ...Object.keys(locals)];

View File

@@ -0,0 +1,182 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.parse = exports.default = void 0;
var _markdownItFrontMatter = _interopRequireDefault(require("markdown-it-front-matter"));
var _plugin = _interopRequireDefault(require("../../plugin"));
var _comment = require("../comment");
var directives = _interopRequireWildcard(require("./directives"));
var _yaml = require("./yaml");
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
const isDirectiveComment = token => token.type === 'marpit_comment' && token.meta.marpitParsedDirectives;
/**
* Parse Marpit directives and store result to the slide token meta.
*
* Marpit comment plugin ans slide plugin requires already loaded to
* markdown-it instance.
*
* @function parse
* @param {MarkdownIt} md markdown-it instance.
* @param {Object} [opts]
* @param {boolean} [opts.frontMatter=true] Switch feature to support YAML
* front-matter. If true, you can use Jekyll style directive setting to the
* first page.
*/
function _parse(md, opts = {}) {
const {
marpit
} = md;
const applyBuiltinDirectives = (newProps, builtinDirectives) => {
let ret = {};
for (const prop of Object.keys(newProps)) {
if (builtinDirectives[prop]) {
ret = {
...ret,
...builtinDirectives[prop](newProps[prop], marpit)
};
} else {
ret[prop] = newProps[prop];
}
}
return ret;
};
// Front-matter support
const frontMatter = opts.frontMatter === undefined ? true : !!opts.frontMatter;
let frontMatterObject = {};
if (frontMatter) {
md.core.ruler.before('block', 'marpit_directives_front_matter', state => {
frontMatterObject = {};
if (!state.inlineMode) marpit.lastGlobalDirectives = {};
});
md.use(_markdownItFrontMatter.default, fm => {
frontMatterObject.text = fm;
const parsed = (0, _yaml.yaml)(fm, marpit.options.looseYAML ? [...Object.keys(marpit.customDirectives.global), ...Object.keys(marpit.customDirectives.local)] : false);
if (parsed !== false) frontMatterObject.yaml = parsed;
});
}
// Parse global directives
md.core.ruler.after('inline', 'marpit_directives_global_parse', state => {
if (state.inlineMode) return;
let globalDirectives = {};
const applyDirectives = obj => {
let recognized = false;
for (const key of Object.keys(obj)) {
if (directives.globals[key]) {
recognized = true;
globalDirectives = {
...globalDirectives,
...directives.globals[key](obj[key], marpit)
};
} else if (marpit.customDirectives.global[key]) {
recognized = true;
globalDirectives = {
...globalDirectives,
...applyBuiltinDirectives(marpit.customDirectives.global[key](obj[key], marpit), directives.globals)
};
}
}
return recognized;
};
if (frontMatterObject.yaml) applyDirectives(frontMatterObject.yaml);
for (const token of state.tokens) {
if (isDirectiveComment(token) && applyDirectives(token.meta.marpitParsedDirectives)) {
(0, _comment.markAsParsed)(token, 'directive');
} else if (token.type === 'inline') {
for (const t of token.children) {
if (isDirectiveComment(t) && applyDirectives(t.meta.marpitParsedDirectives)) (0, _comment.markAsParsed)(t, 'directive');
}
}
}
marpit.lastGlobalDirectives = {
...globalDirectives
};
});
// Parse local directives and apply meta to slide
md.core.ruler.after('marpit_slide', 'marpit_directives_parse', state => {
if (state.inlineMode) return;
const slides = [];
const cursor = {
slide: undefined,
local: {},
spot: {}
};
const applyDirectives = obj => {
let recognized = false;
for (const key of Object.keys(obj)) {
if (directives.locals[key]) {
recognized = true;
cursor.local = {
...cursor.local,
...directives.locals[key](obj[key], marpit)
};
} else if (marpit.customDirectives.local[key]) {
recognized = true;
cursor.local = {
...cursor.local,
...applyBuiltinDirectives(marpit.customDirectives.local[key](obj[key], marpit), directives.locals)
};
}
// Spot directives
// (Apply local directive to only current slide by prefix "_")
if (key.startsWith('_')) {
const spotKey = key.slice(1);
if (directives.locals[spotKey]) {
recognized = true;
cursor.spot = {
...cursor.spot,
...directives.locals[spotKey](obj[key], marpit)
};
} else if (marpit.customDirectives.local[spotKey]) {
recognized = true;
cursor.spot = {
...cursor.spot,
...applyBuiltinDirectives(marpit.customDirectives.local[spotKey](obj[key], marpit), directives.locals)
};
}
}
}
return recognized;
};
if (frontMatterObject.yaml) applyDirectives(frontMatterObject.yaml);
for (const token of state.tokens) {
if (token.meta && token.meta.marpitSlideElement === 1) {
// Initialize Marpit directives meta
token.meta.marpitDirectives = {};
slides.push(token);
cursor.slide = token;
} else if (token.meta && token.meta.marpitSlideElement === -1) {
// Assign local and spot directives to meta
cursor.slide.meta.marpitDirectives = {
...cursor.slide.meta.marpitDirectives,
...cursor.local,
...cursor.spot
};
cursor.spot = {};
} else if (isDirectiveComment(token) && applyDirectives(token.meta.marpitParsedDirectives)) {
(0, _comment.markAsParsed)(token, 'directive');
} else if (token.type === 'inline') {
for (const t of token.children) {
if (isDirectiveComment(t) && applyDirectives(t.meta.marpitParsedDirectives)) (0, _comment.markAsParsed)(t, 'directive');
}
}
}
// Assign global directives to meta
for (const token of slides) token.meta.marpitDirectives = {
...token.meta.marpitDirectives,
...marpit.lastGlobalDirectives
};
});
}
const parse = exports.parse = (0, _plugin.default)(_parse);
var _default = exports.default = parse;

View File

@@ -0,0 +1,62 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.yaml = exports.default = void 0;
var _jsYaml = require("js-yaml");
var _directives = _interopRequireDefault(require("./directives"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
const createPatterns = keys => {
const set = new Set();
for (const k of keys) {
const normalized = '_?' + k.replace(/[.*+?^=!:${}()|[\]\\/]/g, '\\$&');
set.add(normalized);
set.add(`"${normalized}"`);
set.add(`'${normalized}'`);
}
return [...set.values()];
};
const yamlSpecialChars = `["'{|>~&*`;
function parse(text) {
try {
const obj = (0, _jsYaml.load)(text, {
schema: _jsYaml.FAILSAFE_SCHEMA
});
if (obj === null || typeof obj !== 'object') return false;
return obj;
} catch {
return false;
}
}
function convertLoose(text, looseDirectives) {
const keyPattern = `(?:${createPatterns(looseDirectives).join('|')})`;
const looseMatcher = new RegExp(`^(${keyPattern}\\s*:)(.+)$`);
let normalized = '';
for (const line of text.split(/\r?\n/)) normalized += `${line.replace(looseMatcher, (original, prop, value) => {
const trimmed = value.trim();
if (trimmed.length === 0 || yamlSpecialChars.includes(trimmed[0])) return original;
const spaceLength = value.length - value.trimLeft().length;
const spaces = value.substring(0, spaceLength);
return `${prop}${spaces}"${trimmed.split('"').join('\\"')}"`;
})}\n`;
return normalized.trim();
}
/**
* Parse text as YAML by using js-yaml's FAILSAFE_SCHEMA.
*
* @function yaml
* @param {String} text Target text.
* @param {boolean|string[]} [looseDirectives=false] By setting `true`, it try
* to parse as loose YAML only in defined Marpit built-in directives. You
* may also extend target keys for loose parsing by passing an array of
* strings.
* @returns {Object|false} Return parse result, or `false` when failed to parse.
*/
const yaml = (text, looseDirectives = false) => parse(looseDirectives ? convertLoose(text, [..._directives.default, ...(Array.isArray(looseDirectives) ? looseDirectives : [])]) : text);
exports.yaml = yaml;
var _default = exports.default = yaml;

View File

@@ -0,0 +1,55 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.fragment = exports.default = void 0;
var _plugin = _interopRequireDefault(require("../plugin"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
const fragmentedListMarkups = ['*', ')'];
/**
* Marpit fragment plugin.
*
* @function fragment
* @param {MarkdownIt} md markdown-it instance.
*/
function _fragment(md) {
// Fragmented list
md.core.ruler.after('marpit_directives_parse', 'marpit_fragment', state => {
if (state.inlineMode) return;
for (const token of state.tokens) {
if (token.type === 'list_item_open' && fragmentedListMarkups.includes(token.markup)) {
token.meta = token.meta || {};
token.meta.marpitFragment = true;
}
}
});
// Add data-marpit-fragment(s) attributes to token
md.core.ruler.after('marpit_fragment', 'marpit_apply_fragment', state => {
if (state.inlineMode) return;
const fragments = {
slide: undefined,
count: 0
};
for (const token of state.tokens) {
if (token.meta && token.meta.marpitSlideElement === 1) {
fragments.slide = token;
fragments.count = 0;
} else if (token.meta && token.meta.marpitSlideElement === -1) {
if (fragments.slide && fragments.count > 0) {
fragments.slide.attrSet('data-marpit-fragments', fragments.count);
}
} else if (token.meta && token.meta.marpitFragment) {
fragments.count += 1;
token.meta.marpitFragment = fragments.count;
token.attrSet('data-marpit-fragment', fragments.count);
}
}
});
}
const fragment = exports.fragment = (0, _plugin.default)(_fragment);
var _default = exports.default = fragment;

View File

@@ -0,0 +1,57 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.headerAndFooter = exports.default = void 0;
var _wrap_tokens = require("../helpers/wrap_tokens");
var _plugin = _interopRequireDefault(require("../plugin"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
/**
* Marpit header and footer plugin.
*
* At each slide, add header and footer that are provided by directives.
*
* @function headerAndFooter
* @param {MarkdownIt} md markdown-it instance.
*/
function _headerAndFooter(md) {
md.core.ruler.after('marpit_directives_apply', 'marpit_header_and_footer', state => {
if (state.inlineMode) return;
const parsedInlines = new Map();
const getParsed = markdown => {
let parsed = parsedInlines.get(markdown);
if (!parsed) {
parsed = md.parseInline(markdown, state.env);
delete parsed.map;
parsedInlines.set(markdown, parsed);
}
return parsed;
};
const createMarginalTokens = (tag, markdown) => (0, _wrap_tokens.wrapTokens)(state.Token, `marpit_${tag}`, {
tag,
close: {
block: true
}
}, getParsed(markdown));
let current;
const newTokens = [];
for (const token of state.tokens) {
if (token.type === 'marpit_slide_open') {
current = token;
newTokens.push(token);
if (current.meta && current.meta.marpitHeader) newTokens.push(...createMarginalTokens('header', current.meta.marpitHeader));
} else if (token.type === 'marpit_slide_close') {
if (current.meta && current.meta.marpitFooter) newTokens.push(...createMarginalTokens('footer', current.meta.marpitFooter));
newTokens.push(token);
} else {
newTokens.push(token);
}
}
state.tokens = newTokens;
});
}
const headerAndFooter = exports.headerAndFooter = (0, _plugin.default)(_headerAndFooter);
var _default = exports.default = headerAndFooter;

View File

@@ -0,0 +1,48 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.headingDivider = exports.default = void 0;
var _split = require("../helpers/split");
var _plugin = _interopRequireDefault(require("../plugin"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
/**
* Marpit heading divider plugin.
*
* Start a new slide page at before of headings by prepending hidden `<hr>`
* elements.
*
* @function headingDivider
* @param {MarkdownIt} md markdown-it instance.
*/
function _headingDivider(md) {
const {
marpit
} = md;
md.core.ruler.before('marpit_slide', 'marpit_heading_divider', state => {
let target = marpit.options.headingDivider;
if (marpit.lastGlobalDirectives && Object.prototype.hasOwnProperty.call(marpit.lastGlobalDirectives, 'headingDivider')) target = marpit.lastGlobalDirectives.headingDivider;
if (state.inlineMode || target === false) return;
if (Number.isInteger(target) && target >= 1 && target <= 6) target = [...Array(target).keys()].map(i => i + 1);
if (!Array.isArray(target)) return;
const splitTag = target.map(i => `h${i}`);
const splitFunc = t => t.type === 'heading_open' && splitTag.includes(t.tag);
const newTokens = [];
for (const slideTokens of (0, _split.split)(state.tokens, splitFunc, true)) {
const [token] = slideTokens;
if (token && splitFunc(token) && newTokens.some(t => !t.hidden)) {
const hr = new state.Token('hr', '', 0);
hr.hidden = true;
hr.map = token.map;
newTokens.push(hr);
}
newTokens.push(...slideTokens);
}
state.tokens = newTokens;
});
}
const headingDivider = exports.headingDivider = (0, _plugin.default)(_headingDivider);
var _default = exports.default = headingDivider;

24
node_modules/@marp-team/marpit/lib/markdown/image.js generated vendored Normal file
View File

@@ -0,0 +1,24 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.image = exports.default = void 0;
var _plugin = _interopRequireDefault(require("../plugin"));
var _apply = _interopRequireDefault(require("./image/apply"));
var _parse = _interopRequireDefault(require("./image/parse"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
/**
* Marpit image plugin.
*
* @function image
* @param {MarkdownIt} md markdown-it instance.
*/
function _image(md) {
(0, _parse.default)(md);
(0, _apply.default)(md);
}
const image = exports.image = (0, _plugin.default)(_image);
var _default = exports.default = image;

View File

@@ -0,0 +1,48 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.applyImage = void 0;
var _inline_style = _interopRequireDefault(require("../../helpers/inline_style"));
var _plugin = _interopRequireDefault(require("../../plugin"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
/**
* Marpit image apply plugin.
*
* Apply image style and color spot directive based on parsed meta.
*
* @function applyImage
* @param {MarkdownIt} md markdown-it instance.
*/
function _applyImage(md) {
// Build and apply image style
md.inline.ruler2.push('marpit_apply_image', ({
tokens
}) => {
for (const token of tokens) {
if (token.type === 'image') {
const {
filters,
height,
width
} = token.meta.marpitImage;
const style = new _inline_style.default(token.attrGet('style'));
if (width && !width.endsWith('%')) style.set('width', width);
if (height && !height.endsWith('%')) style.set('height', height);
if (filters) {
const filterStyle = [];
for (const fltrs of filters) filterStyle.push(`${fltrs[0]}(${fltrs[1]})`);
token.meta.marpitImage.filter = filterStyle.join(' ');
style.set('filter', token.meta.marpitImage.filter);
}
const stringified = style.toString();
if (stringified) token.attrSet('style', stringified);
}
}
});
}
const applyImage = exports.applyImage = (0, _plugin.default)(_applyImage);
var _default = exports.default = applyImage;

View File

@@ -0,0 +1,175 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.parseImage = exports.default = void 0;
var _plugin = _interopRequireDefault(require("../../plugin"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
const escape = target => target.replace(/[\\;:()]/g, matched => `\\${matched[0].codePointAt(0).toString(16)} `);
const optionMatchers = new Map();
// The scale percentage for resize background
optionMatchers.set(/^(\d*\.)?\d+%$/, matches => ({
size: matches[0]
}));
// width and height
const normalizeLength = v => `${v}${/^(\d*\.)?\d+$/.test(v) ? 'px' : ''}`;
optionMatchers.set(/^w(?:idth)?:((?:\d*\.)?\d+(?:%|ch|cm|em|ex|in|mm|pc|pt|px)?|auto)$/, matches => ({
width: normalizeLength(matches[1])
}));
optionMatchers.set(/^h(?:eight)?:((?:\d*\.)?\d+(?:%|ch|cm|em|ex|in|mm|pc|pt|px)?|auto)$/, matches => ({
height: normalizeLength(matches[1])
}));
// CSS filters
optionMatchers.set(/^blur(?::(.+))?$/, (matches, meta) => ({
filters: [...meta.filters, ['blur', escape(matches[1] || '10px')]]
}));
optionMatchers.set(/^brightness(?::(.+))?$/, (matches, meta) => ({
filters: [...meta.filters, ['brightness', escape(matches[1] || '1.5')]]
}));
optionMatchers.set(/^contrast(?::(.+))?$/, (matches, meta) => ({
filters: [...meta.filters, ['contrast', escape(matches[1] || '2')]]
}));
optionMatchers.set(/^drop-shadow(?::(.+?),(.+?)(?:,(.+?))?(?:,(.+?))?)?$/, (matches, meta) => {
const args = [];
for (const arg of matches.slice(1)) {
if (arg) {
const colorFunc = arg.match(/^(rgba?|hsla?|hwb|(?:ok)?(?:lab|lch)|color)\((.*)\)$/);
args.push(colorFunc ? `${colorFunc[1]}(${escape(colorFunc[2])})` : escape(arg));
}
}
return {
filters: [...meta.filters, ['drop-shadow', args.join(' ') || '0 5px 10px rgba(0,0,0,.4)']]
};
});
optionMatchers.set(/^grayscale(?::(.+))?$/, (matches, meta) => ({
filters: [...meta.filters, ['grayscale', escape(matches[1] || '1')]]
}));
optionMatchers.set(/^hue-rotate(?::(.+))?$/, (matches, meta) => ({
filters: [...meta.filters, ['hue-rotate', escape(matches[1] || '180deg')]]
}));
optionMatchers.set(/^invert(?::(.+))?$/, (matches, meta) => ({
filters: [...meta.filters, ['invert', escape(matches[1] || '1')]]
}));
optionMatchers.set(/^opacity(?::(.+))?$/, (matches, meta) => ({
filters: [...meta.filters, ['opacity', escape(matches[1] || '.5')]]
}));
optionMatchers.set(/^saturate(?::(.+))?$/, (matches, meta) => ({
filters: [...meta.filters, ['saturate', escape(matches[1] || '2')]]
}));
optionMatchers.set(/^sepia(?::(.+))?$/, (matches, meta) => ({
filters: [...meta.filters, ['sepia', escape(matches[1] || '1')]]
}));
/**
* Marpit image parse plugin.
*
* Parse image tokens and store the result into `marpitImage` meta. It has an
* image url and options. The alternative text is regarded as space-separated
* options.
*
* @function parseImage
* @param {MarkdownIt} md markdown-it instance.
*/
function _parseImage(md) {
const {
process
} = md.core;
let refCount = 0;
const finalizeTokenAttr = (token, state) => {
// Apply finalization recursively to inline tokens
if (token.type === 'inline') {
for (const t of token.children) finalizeTokenAttr(t, state);
}
// Re-generate the alt text of image token to remove Marpit specific options
if (token.type === 'image' && token.meta && token.meta.marpitImage) {
let updatedAlt = '';
let hasConsumed = false;
for (const opt of token.meta.marpitImage.options) {
if (opt.consumed) {
hasConsumed = true;
} else {
updatedAlt += opt.leading + opt.content;
}
}
if (hasConsumed) {
let newTokens = [];
md.inline.parse(updatedAlt.trimStart(), state.md, state.env, newTokens);
token.children = newTokens;
}
}
};
md.core.process = state => {
try {
refCount += 1;
return process.call(md.core, state);
} finally {
refCount -= 1;
if (refCount === 0) {
// Apply finalization for every tokens
for (const token of state.tokens) finalizeTokenAttr(token, state);
}
}
};
md.inline.ruler2.push('marpit_parse_image', ({
tokens
}) => {
for (const token of tokens) {
if (token.type === 'image') {
// Parse alt text as options
const optsBase = token.content.split(/(\s+)/);
let currentIdx = 0;
let leading = '';
const options = optsBase.reduce((acc, opt, i) => {
if (i % 2 === 0 && opt.length > 0) {
currentIdx += leading.length;
acc.push({
content: opt,
index: currentIdx,
leading,
consumed: false
});
leading = '';
currentIdx += opt.length;
} else {
leading += opt;
}
return acc;
}, []);
const url = token.attrGet('src');
token.meta = token.meta || {};
token.meta.marpitImage = {
...(token.meta.marpitImage || {}),
url: url.toString(),
options
};
// Parse keyword through matchers
for (const opt of options) {
for (const [regexp, mergeFunc] of optionMatchers) {
if (opt.consumed) continue;
const matched = opt.content.match(regexp);
if (matched) {
opt.consumed = true;
token.meta.marpitImage = {
...token.meta.marpitImage,
...mergeFunc(matched, {
filters: [],
...token.meta.marpitImage
})
};
}
}
}
}
}
});
}
const parseImage = exports.parseImage = (0, _plugin.default)(_parseImage);
var _default = exports.default = parseImage;

View File

@@ -0,0 +1,60 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.inlineSVG = exports.default = void 0;
var _split = require("../helpers/split");
var _wrap_tokens = require("../helpers/wrap_tokens");
var _plugin = _interopRequireDefault(require("../plugin"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
/**
* Marpit Inline SVG plugin.
*
* @function inlineSVG
* @param {MarkdownIt} md markdown-it instance.
*/
function _inlineSVG(md) {
const {
marpit
} = md;
md.core.ruler.after('marpit_directives_parse', 'marpit_inline_svg', state => {
if (!(marpit.inlineSVGOptions && marpit.inlineSVGOptions.enabled) || state.inlineMode) return;
const {
themeSet,
lastGlobalDirectives
} = marpit;
const w = themeSet.getThemeProp(lastGlobalDirectives.theme, 'widthPixel');
const h = themeSet.getThemeProp(lastGlobalDirectives.theme, 'heightPixel');
const newTokens = [];
for (const tokens of (0, _split.split)(state.tokens, t => t.meta && t.meta.marpitSlideElement === 1, true)) {
if (tokens.length > 0) {
for (const t of tokens) if (t.meta && t.meta.marpitSlideElement) delete t.meta.marpitSlideElement;
newTokens.push(...(0, _wrap_tokens.wrapTokens)(state.Token, 'marpit_inline_svg', {
tag: 'svg',
'data-marpit-svg': '',
viewBox: `0 0 ${w} ${h}`,
open: {
meta: {
marpitSlideElement: 1
}
},
close: {
meta: {
marpitSlideElement: -1
}
}
}, (0, _wrap_tokens.wrapTokens)(state.Token, 'marpit_inline_svg_content', {
tag: 'foreignObject',
width: w,
height: h
}, tokens)));
}
}
state.tokens = newTokens;
});
}
const inlineSVG = exports.inlineSVG = (0, _plugin.default)(_inlineSVG);
var _default = exports.default = inlineSVG;

73
node_modules/@marp-team/marpit/lib/markdown/slide.js generated vendored Normal file
View File

@@ -0,0 +1,73 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.slide = exports.defaultAnchorCallback = exports.default = void 0;
var _split = require("../helpers/split");
var _wrap_tokens = require("../helpers/wrap_tokens");
var _plugin = _interopRequireDefault(require("../plugin"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
const defaultAnchorCallback = i => `${i + 1}`;
/**
* Marpit slide plugin.
*
* Split markdown-it tokens into the slides by horizontal rule. Each slides
* will be wrapped by section element.
*
* @function slide
* @param {MarkdownIt} md markdown-it instance.
* @param {Object} [opts]
* @param {Object} [opts.attributes] The `<section>` element attributes by
* key-value pairs.
* @param {(boolean|Marpit~AnchorCallback)} [opts.anchor=true] If true, assign
* the anchor with the page number starting from 1. You can customize anchor
* name by passing callback function.
*/
exports.defaultAnchorCallback = defaultAnchorCallback;
function _slide(md, opts = {}) {
const anchor = opts.anchor === undefined ? true : opts.anchor;
const anchorCallback = (() => {
if (typeof anchor === 'function') return anchor;
if (anchor) return defaultAnchorCallback;
return () => undefined;
})();
md.core.ruler.push('marpit_slide', state => {
if (state.inlineMode) return;
const splittedTokens = (0, _split.split)(state.tokens, t => t.type === 'hr' && t.level === 0, true);
const {
length: marpitSlideTotal
} = splittedTokens;
state.tokens = splittedTokens.reduce((arr, slideTokens, marpitSlide) => {
const firstHr = slideTokens[0] && slideTokens[0].type === 'hr' ? slideTokens[0] : undefined;
const mapTarget = firstHr || slideTokens.find(t => t.map);
return [...arr, ...(0, _wrap_tokens.wrapTokens)(state.Token, 'marpit_slide', {
...(opts.attributes || {}),
tag: 'section',
id: anchorCallback(marpitSlide),
open: {
block: true,
meta: {
marpitSlide,
marpitSlideTotal,
marpitSlideElement: 1
},
map: mapTarget ? mapTarget.map : [0, 1]
},
close: {
block: true,
meta: {
marpitSlide,
marpitSlideTotal,
marpitSlideElement: -1
}
}
}, slideTokens.slice(firstHr ? 1 : 0))];
}, []);
});
}
const slide = exports.slide = (0, _plugin.default)(_slide);
var _default = exports.default = slide;

View File

@@ -0,0 +1,34 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.slideContainer = exports.default = void 0;
var _split = require("../helpers/split");
var _wrap_array = require("../helpers/wrap_array");
var _wrap_tokens = require("../helpers/wrap_tokens");
var _plugin = _interopRequireDefault(require("../plugin"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
/**
* Marpit slide container plugin.
*
* @function slideContainer
* @param {MarkdownIt} md markdown-it instance.
*/
function _slideContainer(md) {
const containers = (0, _wrap_array.wrapArray)(md.marpit.options.slideContainer);
if (!containers) return;
const target = [...containers].reverse();
md.core.ruler.push('marpit_slide_containers', state => {
if (state.inlineMode) return;
const newTokens = [];
for (const tokens of (0, _split.split)(state.tokens, t => t.meta && t.meta.marpitSlideElement === 1, true)) {
if (tokens.length > 0) newTokens.push(...target.reduce((slides, conts) => (0, _wrap_tokens.wrapTokens)(state.Token, 'marpit_slide_containers', conts, slides), tokens));
}
state.tokens = newTokens;
});
}
const slideContainer = exports.slideContainer = (0, _plugin.default)(_slideContainer);
var _default = exports.default = slideContainer;

View File

@@ -0,0 +1,128 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.assign = void 0;
var _postcss = _interopRequireDefault(require("postcss"));
var _postcss_plugin = _interopRequireDefault(require("../../helpers/postcss_plugin"));
var _plugin = _interopRequireDefault(require("../../plugin"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
const uniqKeyChars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
const uniqKeyCharsLength = uniqKeyChars.length;
const generateScopeAttr = uniqKey => `data-marpit-scope-${uniqKey}`;
const generateUniqKey = (length = 8) => {
let ret = '';
for (let i = 0; i < length; i += 1) ret += uniqKeyChars[Math.floor(Math.random() * uniqKeyCharsLength)];
return ret;
};
const injectScopePostCSSplugin = (0, _postcss_plugin.default)('marpit-style-assign-postcss-inject-scope', (key, keyframeSet) => css => css.each(function inject(node) {
const {
type,
name
} = node;
if (type === 'atrule') {
if (name === 'keyframes' && node.params) {
keyframeSet.add(node.params);
node.params += `-${key}`;
} else if (name === 'media' || name === 'supports') {
node.each(inject);
}
} else if (type === 'rule') {
node.selectors = node.selectors.map(selector => {
const injectSelector = /^section(?![\w-])/.test(selector) ? selector.slice(7) : ` ${selector}`;
return `section[${generateScopeAttr(key)}]${injectSelector}`;
});
}
}));
const scopeKeyframesPostCSSPlugin = (0, _postcss_plugin.default)('marpit-style-assign-postcss-scope-keyframes', (key, keyframeSet) => css => {
if (keyframeSet.size === 0) return;
const keyframeMatcher = new RegExp(`\\b(${[...keyframeSet.values()].map(kf => kf.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&')).join('|')})(?!\\()\\b`);
css.walkDecls(/^animation(-name)?$/, decl => {
decl.value = decl.value.replace(keyframeMatcher, kf => `${kf}-${key}`);
});
});
/**
* Marpit style assign plugin.
*
* Assign style global directive and parsed styles to Marpit instance's
* `lastStyles' property.
*
* @function assign
* @param {MarkdownIt} md markdown-it instance.
*/
function _assign(md) {
const {
marpit
} = md;
md.core.ruler.after('marpit_slide', 'marpit_style_assign', state => {
if (state.inlineMode) return;
const directives = marpit.lastGlobalDirectives || {};
marpit.lastStyles = directives.style ? [directives.style] : [];
let current;
for (const token of state.tokens) {
if (token.meta && token.meta.marpitSlideElement === 1) {
current = token;
} else if (token.meta && token.meta.marpitSlideElement === -1) {
if (current.meta && current.meta.marpitStyleScoped) {
const {
key,
keyframeSet,
styles
} = current.meta.marpitStyleScoped;
// Rewrite keyframes name in animation decls
const processor = (0, _postcss.default)([scopeKeyframesPostCSSPlugin(key, keyframeSet)]);
current.meta.marpitStyleScoped.styles = styles.map(style => {
try {
return processor.process(style).css;
} catch {
return style;
}
});
// Assign scoped styles
marpit.lastStyles.push(...current.meta.marpitStyleScoped.styles);
}
current = undefined;
} else if (token.type === 'marpit_style') {
const {
content
} = token;
// Scoped style
const {
marpitStyleScoped
} = token.meta || {};
if (current && marpitStyleScoped) {
current.meta = current.meta || {};
current.meta.marpitStyleScoped = current.meta.marpitStyleScoped || {};
let {
key
} = current.meta.marpitStyleScoped;
if (!key) {
key = generateUniqKey();
current.meta.marpitStyleScoped.key = key;
current.attrSet(generateScopeAttr(key), '');
}
current.meta.marpitStyleScoped.styles = current.meta.marpitStyleScoped.styles || [];
current.meta.marpitStyleScoped.keyframeSet = current.meta.marpitStyleScoped.keyframeSet || new Set();
const processor = (0, _postcss.default)([injectScopePostCSSplugin(key, current.meta.marpitStyleScoped.keyframeSet)]);
try {
current.meta.marpitStyleScoped.styles.push(processor.process(content).css);
} catch {
// No ops
}
} else if (content) {
// Global style
marpit.lastStyles.push(content);
}
}
}
});
}
const assign = exports.assign = (0, _plugin.default)(_assign);
var _default = exports.default = assign;

View File

@@ -0,0 +1,74 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.parse = exports.default = void 0;
var _plugin = _interopRequireDefault(require("../../plugin"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
const styleMatcher = /<style([\s\S]*?)>([\s\S]*?)<\/style>/i;
const styleMatcherOpening = /^<style(?=(\s|>|$))/i;
const styleMatcherClosing = /<\/style>/i;
const styleMatcherScoped = /\bscoped\b/i;
/**
* Marpit style parse plugin.
*
* Parse `<style>` elements as the hidden `marpit_style` token. The parsed style
* will use in {@link ThemeSet#pack} to append the style additionally.
*
* `<style>` elements will strip regardless of html setting provided by
* markdown-it.
*
* @function parse
* @param {MarkdownIt} md markdown-it instance.
*/
function _parse(md) {
/**
* Based on markdown-it html_block rule
* https://github.com/markdown-it/markdown-it/blob/master/lib/rules_block/html_block.js
*/
md.block.ruler.before('html_block', 'marpit_style_parse', (state, startLine, endLine, silent) => {
// Fast fail
let pos = state.bMarks[startLine] + state.tShift[startLine];
if (state.src.charCodeAt(pos) !== 0x3c) return false;
let max = state.eMarks[startLine];
let line = state.src.slice(pos, max);
// Match to opening element
if (!styleMatcherOpening.test(line)) return false;
if (silent) return true;
// Parse ending element
let nextLine = startLine + 1;
if (!styleMatcherClosing.test(line)) {
while (nextLine < endLine) {
if (state.sCount[nextLine] < state.blkIndent) break;
pos = state.bMarks[nextLine] + state.tShift[nextLine];
max = state.eMarks[nextLine];
line = state.src.slice(pos, max);
nextLine += 1;
if (styleMatcherClosing.test(line)) break;
}
}
state.line = nextLine;
// Create token
const token = state.push('marpit_style', '', 0);
token.map = [startLine, nextLine];
token.markup = state.getLines(startLine, nextLine, state.blkIndent, true);
token.meta = {};
token.hidden = true;
const matchedContent = styleMatcher.exec(token.markup);
if (matchedContent) {
const [, attrStr, contentStr] = matchedContent;
token.content = contentStr.trim();
token.meta.marpitStyleScoped = styleMatcherScoped.test(attrStr.trim());
}
return true;
});
}
const parse = exports.parse = (0, _plugin.default)(_parse);
var _default = exports.default = parse;

59
node_modules/@marp-team/marpit/lib/markdown/sweep.js generated vendored Normal file
View File

@@ -0,0 +1,59 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.sweep = exports.default = void 0;
var _plugin = _interopRequireDefault(require("../plugin"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
/**
* Marpit sweep plugin.
*
* Hide blank paragraphs. For better support of the background image syntax and
* directives through HTML comment, Marpit will sweep paragraphs included only
* whitespace by setting `hidden: true`.
*
* It also sweep the inline token marked as hidden forcely. Please notice that
* plugins executed after this cannot handle hidden inline tokens.
*
* @function sweep
* @param {MarkdownIt} md markdown-it instance.
*/
function _sweep(md) {
md.core.ruler.after('inline', 'marpit_sweep', state => {
if (state.inlineMode) return;
for (const token of state.tokens) {
if (token.type === 'html_block' && token.content.match(/^\s*$/) || token.type === 'inline' && token.children.filter(t => !(t.hidden || t.type === 'softbreak')).every(t => t.type === 'text' && t.content.match(/^\s*$/))) token.hidden = true;
}
});
md.core.ruler.push('marpit_sweep_paragraph', state => {
if (state.inlineMode) return;
const current = {
open: [],
tokens: {}
};
for (const token of state.tokens) {
if (token.type === 'inline' && token.hidden) {
// markdown-it's "inline" type is not following a `hidden` flag. Marpit
// changes the token type to unique name to hide token forcely.
token.type = 'marpit_hidden_inline';
} else if (token.type === 'paragraph_open') {
current.open.push(token);
current.tokens[token] = [];
} else if (token.type === 'paragraph_close') {
const openToken = current.open.pop();
if (current.tokens[openToken].every(t => t.hidden)) {
openToken.hidden = true;
token.hidden = true;
}
} else {
const len = current.open.length;
if (len > 0) current.tokens[current.open[len - 1]].push(token);
}
}
});
}
const sweep = exports.sweep = (0, _plugin.default)(_sweep);
var _default = exports.default = sweep;

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

@@ -0,0 +1,291 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _markdownIt = _interopRequireDefault(require("markdown-it"));
var _element = require("./element");
var _wrap_array = require("./helpers/wrap_array");
var _background_image = _interopRequireDefault(require("./markdown/background_image"));
var _collect = _interopRequireDefault(require("./markdown/collect"));
var _comment = _interopRequireDefault(require("./markdown/comment"));
var _container = _interopRequireDefault(require("./markdown/container"));
var _apply = _interopRequireDefault(require("./markdown/directives/apply"));
var _parse = _interopRequireDefault(require("./markdown/directives/parse"));
var _fragment = _interopRequireDefault(require("./markdown/fragment"));
var _header_and_footer = _interopRequireDefault(require("./markdown/header_and_footer"));
var _heading_divider = _interopRequireDefault(require("./markdown/heading_divider"));
var _image = _interopRequireDefault(require("./markdown/image"));
var _inline_svg = _interopRequireDefault(require("./markdown/inline_svg"));
var _slide = _interopRequireWildcard(require("./markdown/slide"));
var _slide_container = _interopRequireDefault(require("./markdown/slide_container"));
var _assign = _interopRequireDefault(require("./markdown/style/assign"));
var _parse2 = _interopRequireDefault(require("./markdown/style/parse"));
var _sweep = _interopRequireDefault(require("./markdown/sweep"));
var _theme_set = _interopRequireDefault(require("./theme_set"));
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const defaultOptions = {
anchor: true,
container: _element.marpitContainer,
cssContainerQuery: false,
cssNesting: true,
headingDivider: false,
lang: undefined,
looseYAML: false,
markdown: undefined,
printable: true,
slideContainer: false,
inlineSVG: false
};
const defaultInlineSVGOptions = {
enabled: true,
backdropSelector: true
};
/**
* Parse Marpit Markdown and render to the slide HTML/CSS.
*/
class Marpit {
#markdown = undefined;
/**
* @typedef {Object} Marpit~InlineSVGOptions
* @property {boolean} [enabled=true] Whether inline SVG mode is enabled.
* @property {boolean} [backdropSelector=true] Whether `::backdrop` selector
* support is enabled. If enabled, the `::backdrop` CSS selector will
* match to the SVG container element.
*/
/**
* Convert slide page index into anchor string.
*
* @callback Marpit~AnchorCallback
* @param {number} index Slide page index, beginning from zero.
* @returns {string} The text of anchor for id attribute, without prefix `#`.
*/
/**
* Create a Marpit instance.
*
* @param {Object} [opts]
* @param {boolean|Marpit~AnchorCallback} [opts.anchor=true] Set the page
* number as anchor of each slides (`id` attribute). You can customize the
* anchor text by defining a custom callback function.
* @param {false|Element|Element[]}
* [opts.container={@link module:element.marpitContainer}] Container
* element(s) wrapping whole slide deck.
* @param {boolean|string|string[]} [opts.cssContainerQuery=false] Set whether
* to enable CSS container query (`@container`). By setting the string or
* string array, you can specify the container name(s) for the CSS
* container.
* @param {boolean} [opts.cssNesting=false] Enable CSS nesting support. If
* enabled, Marpit will try to make flatten the CSS with nested rules
* before rendering, to make it compatible with Marpit preprocessings.
* @param {false|number|number[]} [opts.headingDivider=false] Start a new
* slide page at before of headings. it would apply to headings whose
* larger than or equal to the specified level if a number is given, or
* ONLY specified levels if a number array.
* @param {string} [opts.lang] Set the default `lang` attribute of each slide.
* It can override by `lang` global directive in the Markdown.
* @param {boolean} [opts.looseYAML=false] Allow loose YAML parsing in
* built-in directives, and custom directives defined in current instance.
* @param {MarkdownIt|string|Object|Array} [opts.markdown] An instance of
* markdown-it or its constructor option(s) for wrapping. Marpit will
* create its instance based on CommonMark when omitted.
* @param {boolean} [opts.printable=true] Make style printable to PDF.
* @param {false|Element|Element[]} [opts.slideContainer] Container element(s)
* wrapping each slide sections.
* @param {boolean|Marpit~InlineSVGOptions} [opts.inlineSVG=false] Wrap each
* slide sections by inline SVG. _(Experimental)_
*/
constructor(opts = {}) {
/**
* The current options for this instance.
*
* This property is read-only and marked as immutable. You cannot change the
* value of options after creating instance.
*
* @member {Object} options
* @memberOf Marpit#
* @readonly
*/
Object.defineProperty(this, 'options', {
enumerable: true,
value: Object.freeze({
...defaultOptions,
...opts
})
});
/**
* Definitions of the custom directive.
*
* It has the assignable `global` and `local` object. They have consisted of
* the directive name as a key, and parser function as a value. The parser
* should return the validated object for updating meta of markdown-it
* token.
*
* @member {Object} customDirectives
* @memberOf Marpit#
* @readonly
*/
Object.defineProperty(this, 'customDirectives', {
value: Object.seal({
global: Object.create(null),
local: Object.create(null)
})
});
/**
* @type {ThemeSet}
*/
this.themeSet = new _theme_set.default({
cssNesting: this.options.cssNesting
});
this.applyMarkdownItPlugins((() => {
// Use CommonMark based instance by default
if (!this.options.markdown) return new _markdownIt.default('commonmark');
// Detect markdown-it features
if (typeof this.options.markdown === 'object' && typeof this.options.markdown.parse === 'function' && typeof this.options.markdown.renderer === 'object') return this.options.markdown;
// Create instance with passed argument(s)
return new _markdownIt.default(...(0, _wrap_array.wrapArray)(this.options.markdown));
})());
}
/**
* @type {MarkdownIt}
*/
get markdown() {
return this.#markdown;
}
set markdown(md) {
if (this.#markdown && this.#markdown.marpit) delete this.#markdown.marpit;
this.#markdown = md;
if (md) {
Object.defineProperty(md, 'marpit', {
configurable: true,
value: this
});
}
}
/** @private */
applyMarkdownItPlugins(md) {
this.markdown = md;
const slideAnchorCallback = (...args) => {
const {
anchor
} = this.options;
if (typeof anchor === 'function') return anchor(...args);
if (anchor) return (0, _slide.defaultAnchorCallback)(...args);
return undefined;
};
md.use(_comment.default).use(_parse2.default).use(_slide.default, {
anchor: slideAnchorCallback
}).use(_parse.default).use(_apply.default).use(_header_and_footer.default).use(_heading_divider.default).use(_slide_container.default).use(_container.default).use(_inline_svg.default).use(_image.default).use(_background_image.default).use(_sweep.default).use(_assign.default).use(_fragment.default).use(_collect.default);
}
/**
* @typedef {Object} Marpit~RenderResult
* @property {string|string[]} html Rendered HTML.
* @property {string} css Rendered CSS.
* @property {string[][]} comments Parsed HTML comments per slide pages,
* excepted YAML for directives. It would be useful for presenter notes.
*/
/**
* Render Markdown into HTML and CSS string.
*
* @param {string} markdown A Markdown string.
* @param {Object} [env={}] Environment object for passing to markdown-it.
* @param {boolean} [env.htmlAsArray=false] Output rendered HTML as array per
* slide.
* @returns {Marpit~RenderResult} An object of rendering result.
*/
render(markdown, env = {}) {
return {
html: this.renderMarkdown(markdown, env),
css: this.renderStyle(this.lastGlobalDirectives.theme),
comments: this.lastComments
};
}
/**
* Render Markdown by using `markdownIt#render`.
*
* This method is for internal. You can override this method if you have to
* render with customized way.
*
* @private
* @param {string} markdown A Markdown string.
* @param {Object} [env] Environment object for passing to markdown-it.
* @param {boolean} [env.htmlAsArray=false] Output rendered HTML as array per
* slide.
* @returns {string|string[]} The result string(s) of rendering Markdown.
*/
renderMarkdown(markdown, env = {}) {
const tokens = this.markdown.parse(markdown, env);
if (env.htmlAsArray) {
return this.lastSlideTokens.map(slideTokens => this.markdown.renderer.render(slideTokens, this.markdown.options, env));
}
return this.markdown.renderer.render(tokens, this.markdown.options, env);
}
/**
* Render style by using `themeSet#pack`.
*
* This method is for internal.
*
* @private
* @param {string|undefined} theme Theme name.
* @returns {string} The result string of rendering style.
*/
renderStyle(theme) {
return this.themeSet.pack(theme, this.themeSetPackOptions());
}
/** @private */
themeSetPackOptions() {
return {
after: this.lastStyles ? this.lastStyles.join('\n') : undefined,
containers: [...(0, _wrap_array.wrapArray)(this.options.container), ...(0, _wrap_array.wrapArray)(this.options.slideContainer)],
containerQuery: this.options.cssContainerQuery,
inlineSVG: this.inlineSVGOptions,
printable: this.options.printable
};
}
/**
* @private
* @returns {Marpit~InlineSVGOptions} Options for inline SVG.
*/
get inlineSVGOptions() {
if (typeof this.options.inlineSVG === 'object') {
return {
...defaultInlineSVGOptions,
...this.options.inlineSVG
};
}
return {
...defaultInlineSVGOptions,
enabled: !!this.options.inlineSVG
};
}
/**
* Load the specified markdown-it plugin with given parameters.
*
* @param {Function} plugin markdown-it plugin.
* @param {...*} params Params to pass into plugin.
* @returns {Marpit} The called {@link Marpit} instance for chainable.
*/
use(plugin, ...params) {
plugin.call(this.markdown, this.markdown, ...params);
return this;
}
}
var _default = exports.default = Marpit;

47
node_modules/@marp-team/marpit/lib/plugin.js generated vendored Normal file
View File

@@ -0,0 +1,47 @@
"use strict";
/** @module */
/**
* Create Marpit plugin.
*
* Generate Marpit plugin from passed markdown-it plugin. Marpit plugin needs
* markdown-it instance with `marpit` member.
*
* @example
* import { marpitPlugin } from '@marp-team/marpit/plugin'
*
* export default marpitPlugin((md) => {
* // Compatible with markdown-it plugin
* md.renderer.rules.your_rule = (tokens, idx, options, env, self) => {
* // ...
* }
*
* // And accessible to Marpit instance as `md.marpit`
* const { marpit } = md
*
* marpit.customDirectives.local.yourDirective = (value) => {
* return { yourDirective: value }
* }
* })
*
* @function marpitPlugin
* @param {Function} plugin Base plugin for markdown-it.
* @returns {Function} Generated Marpit plugin.
*/
function marpitPlugin(plugin) {
return function (md, ...args) {
if (md.marpit) return plugin.call(this, md, ...args);
throw new Error('Marpit plugin has detected incompatible markdown-it instance.');
};
}
Object.defineProperty(marpitPlugin, '__esModule', {
value: true
});
Object.defineProperty(marpitPlugin, 'default', {
value: marpitPlugin
});
Object.defineProperty(marpitPlugin, 'marpitPlugin', {
value: marpitPlugin
});
module.exports = marpitPlugin;

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;

168
node_modules/@marp-team/marpit/lib/theme.js generated vendored Normal file
View File

@@ -0,0 +1,168 @@
"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;

64
node_modules/@marp-team/marpit/lib/theme/scaffold.js generated vendored Normal file
View File

@@ -0,0 +1,64 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.scaffoldTheme = exports.default = void 0;
var _theme = _interopRequireDefault(require("../theme"));
var _symbol = _interopRequireDefault(require("./symbol"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** @module */
const css = `
section {
width: 1280px;
height: 720px;
box-sizing: border-box;
overflow: hidden;
position: relative;
scroll-snap-align: center center;
-webkit-text-size-adjust: 100%;
text-size-adjust: 100%;
}
section::after {
bottom: 0;
content: attr(data-marpit-pagination);
padding: inherit;
pointer-events: none;
position: absolute;
right: 0;
}
section:not([data-marpit-pagination])::after {
display: none;
}
/* Normalization */
h1 {
font-size: 2em;
margin-block: 0.67em;
}
video::-webkit-media-controls {
will-change: transform;
}
`.trim();
/**
* The scaffold theme. It includes these features:
*
* - Define the default slide size.
* - Set default style for `<section>`.
* - Normalize `<h1>` heading style.
* - Apply workaround for glitched video control on Chromium (https://github.com/marp-team/marpit/issues/205)
*
* @type {Theme}
*/
const scaffoldTheme = exports.scaffoldTheme = _theme.default.fromCSS(css, {
[_symbol.default]: true
});
var _default = exports.default = scaffoldTheme;

8
node_modules/@marp-team/marpit/lib/theme/symbol.js generated vendored Normal file
View File

@@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
// This symbol is for internal to skip name validation when creating theme.
var _default = exports.default = Symbol('skipThemeValidation');

321
node_modules/@marp-team/marpit/lib/theme_set.js generated vendored Normal file
View File

@@ -0,0 +1,321 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _postcss = _interopRequireDefault(require("postcss"));
var _postcss_plugin = _interopRequireDefault(require("./helpers/postcss_plugin"));
var _advanced_background = _interopRequireDefault(require("./postcss/advanced_background"));
var _container_query = _interopRequireWildcard(require("./postcss/container_query"));
var _hoisting = _interopRequireDefault(require("./postcss/import/hoisting"));
var _replace = _interopRequireDefault(require("./postcss/import/replace"));
var _suppress = _interopRequireDefault(require("./postcss/import/suppress"));
var _nesting = _interopRequireDefault(require("./postcss/nesting"));
var _pagination = _interopRequireDefault(require("./postcss/pagination"));
var _printable = _interopRequireWildcard(require("./postcss/printable"));
var _prepend = _interopRequireDefault(require("./postcss/pseudo_selector/prepend"));
var _replace2 = _interopRequireDefault(require("./postcss/pseudo_selector/replace"));
var _font_size = _interopRequireDefault(require("./postcss/root/font_size"));
var _increasing_specificity = _interopRequireWildcard(require("./postcss/root/increasing_specificity"));
var _rem = _interopRequireDefault(require("./postcss/root/rem"));
var _replace3 = _interopRequireDefault(require("./postcss/root/replace"));
var _svg_backdrop = _interopRequireDefault(require("./postcss/svg_backdrop"));
var _theme = _interopRequireDefault(require("./theme"));
var _scaffold = _interopRequireDefault(require("./theme/scaffold"));
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const defaultOptions = {
cssNesting: false
};
/**
* Marpit theme set class.
*/
class ThemeSet {
/**
* Create a ThemeSet instance.
*
* @param {Object} [opts]
* @param {boolean} [opts.cssNesting=true] Enable CSS nesting support.
*/
constructor(opts = defaultOptions) {
/**
* An instance of default theme.
*
* While running {@link ThemeSet#pack}, ThemeSet will use this theme when
* the definition of theme directive or the theme with specified name is not
* found.
*
* By default, Marpit does not provide default theme (`undefined`).
*
* @type {Theme|undefined}
*/
this.default = undefined;
/**
* The default type settings for theme metadata added by
* {@link ThemeSet#add}.
*
* A key of object is the name of metadata and a value is the type which of
* `String` and `Array`. You have to set `Array` if the theme allows
* multi-time definitions in same meta key.
*
* ```css
* /**
* * @theme example
* * @foo Single value
* * @foo allows only one string
* * @bar Multiple value 1
* * @bar Multiple value 2
* * @bar Multiple value 3
* * ...
* ```
*
* ```js
* const themeSet = new ThemeSet()
*
* themeSet.metaType = {
* foo: String,
* bar: Array,
* }
*
* themeSet.add(css)
*
* console.log(themeSet.getThemeMeta('example', 'foo'))
* // => 'allows only one string'
*
* console.log(themeSet.getThemeMeta('example', 'bar'))
* // => ['Multiple value 1', 'Multiple value 2', 'Multiple value 3']
* ```
*
* @type {Object}
*/
this.metaType = {};
/**
* A boolean value indicating whether the theme set is enabling CSS nesting
* or not.
*
* @type {boolean}
*/
this.cssNesting = !!opts.cssNesting;
Object.defineProperty(this, 'themeMap', {
value: new Map()
});
}
/**
* Return the number of themes.
*
* @type {number}
* @readonly
*/
get size() {
return this.themeMap.size;
}
/**
* Add theme CSS from string.
*
* @param {string} css The theme CSS string.
* @returns {Theme} A created {@link Theme} instance.
* @throws Will throw an error if the theme name is not specified by `@theme`
* metadata.
*/
add(css) {
const theme = _theme.default.fromCSS(css, {
metaType: this.metaType,
cssNesting: this.cssNesting
});
this.addTheme(theme);
return theme;
}
/**
* Add theme instance.
*
* @param {Theme} theme The theme instance.
* @throws Will throw an error if the theme name is not specified.
*/
addTheme(theme) {
if (!(theme instanceof _theme.default)) throw new Error('ThemeSet can add only an instance of Theme.');
if (typeof theme.name !== 'string') throw new Error('An instance of Theme requires name.');
this.themeMap.set(theme.name, theme);
}
/**
* Removes all themes from a {@link themeSet} object.
*/
clear() {
return this.themeMap.clear();
}
/**
* Remove a specific named theme from a {@link themeSet} object.
*
* @param {string} name The theme name to delete.
* @returns {boolean} Returns `true` if a theme in current {@link ThemeSet}
* existed and has been removed, or `false` if the theme does not exist.
*/
delete(name) {
return this.themeMap.delete(name);
}
/**
* Returns a specific named theme.
*
* @param {string} name The theme name to get.
* @param {boolean} [fallback=false] If true, return instance's default theme
* or scaffold theme when specified theme cannot find.
* @returns {Theme|undefined} Returns specified or fallbacked theme, or
* `undefined` if `fallback` is false and the specified theme has not
* existed.
*/
get(name, fallback = false) {
const theme = this.themeMap.get(name);
return fallback ? theme || this.default || _scaffold.default : theme;
}
/**
* Returns value(s) of specified metadata from a theme. It considers `@import`
* and `@import-theme` rules in getting meta value. On the other hand, the
* default theme specified by the instance is not considered.
*
* To support metadata with array type, it will merge into a flatten array
* when the all of got valid values that includes imported themes are array.
*
* @param {string|Theme} theme The theme name or instance.
* @param {string} meta The meta name to get.
* @returns {string|string[]|undefined}
*/
getThemeMeta(theme, meta) {
const themeInstance = theme instanceof _theme.default ? theme : this.get(theme);
const metas = themeInstance ? this.resolveImport(themeInstance).map(t => t.meta[meta]).filter(m => m) : [];
// Flatten in order of definitions when the all of valid values are array
if (metas.length > 0 && metas.every(m => Array.isArray(m))) {
const mergedArray = [];
for (const m of metas) mergedArray.unshift(...m);
return mergedArray;
}
return metas[0];
}
/**
* Returns the value of specified property name from a theme. It considers
* `@import` and `@import-theme` rules in getting value.
*
* It will fallback the reference object into the instance's default theme or
* scaffold theme when the specified theme is `undefined`.
*
* @param {string|Theme} theme The theme name or instance.
* @param {string} prop The property name to get.
* @returns {*}
*/
getThemeProp(theme, prop) {
const themeInstance = theme instanceof _theme.default ? theme : this.get(theme);
const props = themeInstance ? this.resolveImport(themeInstance).map(t => t[prop]) : [];
return [...props, this.default && this.default[prop], _scaffold.default[prop]].find(t => t);
}
/**
* Returns a boolean indicating whether a specific named theme exists or not.
*
* @param {string} name The theme name.
* @returns {boolean} Returns `true` if a specific named theme exists,
* otherwise `false`.
*/
has(name) {
return this.themeMap.has(name);
}
/**
* Convert registered theme CSS into usable in the rendered markdown by
* {@link Marpit#render}.
*
* **This method is designed for internal use by {@link Marpit} class.** Use
* {@link Marpit#render} instead unless there is some particular reason.
*
* @param {string} name The theme name. It will use the instance's default
* theme or scaffold theme when a specific named theme does not exist.
* @param {Object} [opts] The option object passed by {@link Marpit#render}.
* @param {string} [opts.after] A CSS string to append into after theme.
* @param {string} [opts.before] A CSS string to prepend into before theme.
* @param {Element[]} [opts.containers] Container elements wrapping whole
* slide deck.
* @param {boolean|string|string[]} [opts.containerQuery] Enable CSS container
* query by setting `true`. You can also specify the name of container for
* CSS container query used by the `@container` at-rule in child elements.
* @param {boolean} [opts.printable] Make style printable to PDF.
* @param {Marpit~InlineSVGOptions} [opts.inlineSVG] Apply a hierarchy of
* inline SVG to CSS selector by setting `true`. _(Experimental)_
* @return {string} The converted CSS string.
*/
pack(name, opts = {}) {
const slideElements = [{
tag: 'section'
}];
const theme = this.get(name, true);
const inlineSVGOpts = opts.inlineSVG || {};
if (inlineSVGOpts.enabled) {
slideElements.unshift({
tag: 'svg'
}, {
tag: 'foreignObject'
});
}
const runPostCSS = (css, plugins) => (0, _postcss.default)([this.cssNesting && (0, _nesting.default)(), ...plugins].filter(p => p)).process(css).css;
const additionalCSS = css => {
if (!css) return undefined;
try {
return runPostCSS(css, [(0, _suppress.default)(this)]);
} catch {
return undefined;
}
};
const after = additionalCSS(opts.after);
const before = additionalCSS(opts.before);
const containerName = typeof opts.containerQuery === 'string' || Array.isArray(opts.containerQuery) ? opts.containerQuery : undefined;
return runPostCSS(theme.css, [before && (0, _postcss_plugin.default)('marpit-pack-before', () => css => css.first.before(before)), after && (0, _postcss_plugin.default)('marpit-pack-after', () => css => {
css.last.after(after);
}), opts.containerQuery && (0, _container_query.default)(containerName), _hoisting.default, (0, _replace.default)(this), opts.printable && (0, _printable.default)({
width: this.getThemeProp(theme, 'width'),
height: this.getThemeProp(theme, 'height')
}), theme !== _scaffold.default && (0, _postcss_plugin.default)('marpit-pack-scaffold', () => css => css.first.before(_scaffold.default.css)), inlineSVGOpts.enabled && _advanced_background.default, inlineSVGOpts.enabled && inlineSVGOpts.backdropSelector && _svg_backdrop.default, _pagination.default, (0, _replace3.default)({
pseudoClass: _increasing_specificity.pseudoClass
}), _font_size.default, _prepend.default, (0, _replace2.default)(opts.containers, slideElements), _increasing_specificity.default, opts.printable && _printable.postprocess, opts.containerQuery && _container_query.postprocess, _rem.default, _hoisting.default]);
}
/**
* Returns a `Iterator` object that contains registered themes to current
* instance.
*
* @returns {Iterator.<Theme>}
*/
themes() {
return this.themeMap.values();
}
/**
* Resolves `@import` and `@import-theme` and returns an array of using theme
* instances.
*
* @private
* @param {Theme} theme Theme instance
* @returns {Theme[]}
*/
resolveImport(theme, importedThemes = []) {
const {
name
} = theme;
if (importedThemes.includes(name)) throw new Error(`Circular "${name}" theme import is detected.`);
const resolvedThemes = [theme];
theme.importRules.forEach(m => {
const importTheme = this.get(m.value);
if (importTheme) resolvedThemes.push(...this.resolveImport(importTheme, [...importedThemes, name].filter(n => n)));
});
return resolvedThemes.filter(v => v);
}
}
var _default = exports.default = ThemeSet;

104
node_modules/@marp-team/marpit/package.json generated vendored Normal file
View File

@@ -0,0 +1,104 @@
{
"name": "@marp-team/marpit",
"version": "3.1.3",
"description": "The skinny framework for creating slide deck from Markdown",
"license": "MIT",
"author": {
"name": "Marp team",
"url": "https://github.com/marp-team"
},
"homepage": "https://marpit.marp.app/",
"contributors": [
{
"name": "Yuki Hattori",
"url": "https://github.com/yhatt"
}
],
"keywords": [
"marp",
"markdown",
"parser",
"slide",
"deck",
"presentation"
],
"repository": {
"type": "git",
"url": "https://github.com/marp-team/marpit"
},
"engines": {
"node": ">=18"
},
"main": "lib/index.js",
"types": "index.d.ts",
"files": [
"lib/",
"index.d.ts",
"plugin.js"
],
"prettier": {
"semi": false,
"singleQuote": true
},
"scripts": {
"build": "npm -s run clean && babel src --out-dir lib",
"check:audit": "npm audit",
"check:format": "npm -s run format -- -c",
"clean": "rimraf lib",
"docs": "node ./docsify/serve.js",
"docs:style": "node ./docsify/build.js",
"format": "prettier \"**/*.{css,html,js,json,md,scss,ts,yaml,yml}\"",
"jsdoc": "rimraf jsdoc && jsdoc src -c .jsdoc.json",
"lint:js": "eslint",
"lint:css": "stylelint \"./**/*.{css,scss}\"",
"prepack": "npm-run-all --parallel check:* lint:* test:coverage --sequential build",
"preversion": "run-p check:* lint:* test:coverage",
"test": "jest",
"test:coverage": "jest --coverage",
"version": "curl https://raw.githubusercontent.com/marp-team/actions/v1/lib/scripts/version.js | node && git add -A CHANGELOG.md",
"watch": "babel src --out-dir lib -w --verbose"
},
"devDependencies": {
"@babel/cli": "^7.27.2",
"@babel/core": "^7.27.1",
"@babel/eslint-parser": "^7.27.1",
"@babel/preset-env": "^7.27.2",
"autoprefixer": "^10.4.21",
"cheerio": "^1.0.0",
"chokidar": "^4.0.3",
"clean-jsdoc-theme": "^4.3.0",
"cssnano": "^7.0.7",
"dedent": "^1.6.0",
"docsify-themeable": "^0.9.0",
"eslint": "^9.26.0",
"eslint-config-prettier": "^10.1.5",
"eslint-plugin-import-x": "^4.11.1",
"globals": "^16.1.0",
"jest": "^29.7.0",
"jest-junit": "^16.0.0",
"jsdoc": "^4.0.4",
"npm-check-updates": "^18.0.1",
"npm-run-all2": "^8.0.1",
"postcss-selector-parser": "^7.1.0",
"prettier": "^3.5.3",
"rimraf": "^6.0.1",
"sass": "1.88.0",
"serve-handler": "^6.1.6",
"stylelint": "^16.19.1",
"stylelint-config-standard-scss": "^15.0.0",
"ws": "^8.18.2"
},
"dependencies": {
"@csstools/postcss-is-pseudo-class": "^5.0.1",
"cssesc": "^3.0.0",
"js-yaml": "^4.1.0",
"lodash.kebabcase": "^4.1.1",
"markdown-it": "^14.1.0",
"markdown-it-front-matter": "^0.2.4",
"postcss": "^8.5.3",
"postcss-nesting": "^13.0.1"
},
"publishConfig": {
"access": "public"
}
}

1
node_modules/@marp-team/marpit/plugin.js generated vendored Normal file
View File

@@ -0,0 +1 @@
module.exports = require('./lib/plugin')