1
0

add initial marp implementation with sample content and build configuration

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

View File

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