@marp-team/marpit
Advanced tools
Comparing version 0.0.3 to 0.0.4
@@ -5,2 +5,8 @@ # Change Log | ||
## v0.0.4 - 2018-05-05 | ||
* Implement CSS filter for image and advanced backgrounds ([#14](https://github.com/marp-team/marpit/pull/14)) | ||
* Fix PostCSS printable plugin to allow printing the advanced backgrounds ([#15](https://github.com/marp-team/marpit/pull/15)) | ||
* Implement split backgrounds in advanced background mode ([#16](https://github.com/marp-team/marpit/pull/16)) | ||
## v0.0.3 - 2018-05-02 | ||
@@ -17,3 +23,3 @@ | ||
* Add [JSDoc documentation to `ThemeSet` class methods](https://marpit.netlify.com/themeset) ([#7](https://github.com/marp-team/marpit/pull/7)) | ||
* Improve the sweep logic of blank paragraphs by splitted into another plugin ([#8](https://github.com/marp-team/marpit/pull/8)) | ||
* Improve the sweep logic of blank paragraphs by split into another plugin ([#8](https://github.com/marp-team/marpit/pull/8)) | ||
@@ -20,0 +26,0 @@ ## v0.0.1 - 2018-03-28 |
@@ -35,3 +35,3 @@ 'use strict'; | ||
* In addition to the basic background implementation, it supports multiple | ||
* background images and filters by using SVG. | ||
* background images, filters, and split background. | ||
* | ||
@@ -52,2 +52,4 @@ * @alias module:markdown/background_image | ||
if (bgSizeKeywords[opt]) t.meta.marpitImage.backgroundSize = bgSizeKeywords[opt]; | ||
if (opt === 'left' || opt === 'right') t.meta.marpitImage.backgroundSplit = opt; | ||
}); | ||
@@ -76,2 +78,3 @@ } | ||
open: current.open, | ||
split: current.split, | ||
width: current.svgContent.attrGet('width') | ||
@@ -98,10 +101,21 @@ } | ||
if (t.type !== 'image') return; | ||
const { background, backgroundSize, size, url } = t.meta.marpitImage; | ||
const { | ||
background, | ||
backgroundSize, | ||
backgroundSplit, | ||
filter, | ||
size, | ||
url | ||
} = t.meta.marpitImage; | ||
if (background && !url.match(/^\s*$/)) { | ||
current.images = [...(current.images || []), { | ||
url, | ||
size: size || backgroundSize || undefined | ||
size: size || backgroundSize || undefined, | ||
filter | ||
}]; | ||
} | ||
if (backgroundSplit) current.split = backgroundSplit; | ||
}); | ||
@@ -126,10 +140,22 @@ }); | ||
advancedBgs = (0, _wrap_tokens2.default)('marpit_advanced_background_foreign_boejct', { tag: 'foreignObject', width, height }, (0, _wrap_tokens2.default)('marpit_advanced_background_section', Object.assign({}, open.attrs.reduce((o, [k, v]) => Object.assign({}, o, { [k]: v }), {}), { | ||
const splitSide = foreignObject.meta.marpitBackground.split; | ||
if (splitSide) { | ||
open.attrSet('data-marpit-advanced-background-split', splitSide); | ||
foreignObject.attrSet('width', '50%'); | ||
if (splitSide === 'left') foreignObject.attrSet('x', '50%'); | ||
} | ||
advancedBgs = (0, _wrap_tokens2.default)('marpit_advanced_background_foreign_object', { tag: 'foreignObject', width, height }, (0, _wrap_tokens2.default)('marpit_advanced_background_section', Object.assign({}, open.attrs.reduce((o, [k, v]) => Object.assign({}, o, { [k]: v }), {}), { | ||
tag: 'section', | ||
id: undefined, | ||
'data-marpit-advanced-background': 'background' | ||
}), images.reduce((imgArr, img) => [...imgArr, ...(0, _wrap_tokens2.default)('marpit_advanced_background_image', { | ||
}), (0, _wrap_tokens2.default)('marpit_advanced_background_image_container', { | ||
tag: 'div', | ||
'data-marpit-advanced-background-container': true | ||
}, images.reduce((imgArr, img) => [...imgArr, ...(0, _wrap_tokens2.default)('marpit_advanced_background_image', { | ||
tag: 'figure', | ||
style: `background-image:url("${img.url}");${img.size ? `background-size:${img.size};` : ''}` | ||
})], []))); | ||
style: [`background-image:url("${img.url}");`, img.size && `background-size:${img.size};`, img.filter && `filter:${img.filter};`].filter(s => s).join('') | ||
})], [])))); | ||
} | ||
@@ -136,0 +162,0 @@ |
@@ -7,2 +7,3 @@ 'use strict'; | ||
/** @module */ | ||
const escapeStyle = target => target.replace(/[\\;:()]/g, matched => `\\${matched[0]}`); | ||
@@ -18,4 +19,56 @@ /** | ||
* @param {MarkdownIt} md markdown-it instance. | ||
* @param {Object} [opts] | ||
* @param {boolean} [opts.filters=true] Switch feature to support CSS filters. | ||
*/ | ||
function parseImage(md) { | ||
function parseImage(md, opts = {}) { | ||
const pluginOptions = Object.assign({ filters: true }, opts); | ||
const optionMatchers = new Map(); | ||
// The scale percentage for resize | ||
// TODO: Implement cross-browser image zoom without affecting DOM tree | ||
// (Pre-released Marp uses `zoom` but it has not supported in Firefox) | ||
optionMatchers.set(/^(\d*\.)?\d+%$/, matches => ({ size: matches[0] })); | ||
if (pluginOptions.filters) { | ||
// CSS filters | ||
optionMatchers.set(/^blur(?::(.+))?$/, (matches, meta) => ({ | ||
filters: [...meta.filters, ['blur', escapeStyle(matches[1] || '10px')]] | ||
})); | ||
optionMatchers.set(/^brightness(?::(.+))?$/, (matches, meta) => ({ | ||
filters: [...meta.filters, ['brightness', escapeStyle(matches[1] || '1.5')]] | ||
})); | ||
optionMatchers.set(/^contrast(?::(.+))?$/, (matches, meta) => ({ | ||
filters: [...meta.filters, ['contrast', escapeStyle(matches[1] || '2')]] | ||
})); | ||
optionMatchers.set(/^drop-shadow(?::(.+?),(.+?)(?:,(.+?))?(?:,(.+?))?)?$/, (matches, meta) => { | ||
const args = matches.slice(1).filter(v => v).map(arg => { | ||
const colorFunc = arg.match(/^(rgba?|hsla?)\((.*)\)$/); | ||
return colorFunc ? `${colorFunc[1]}(${escapeStyle(colorFunc[2])})` : escapeStyle(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', escapeStyle(matches[1] || '1')]] | ||
})); | ||
optionMatchers.set(/^hue-rotate(?::(.+))?$/, (matches, meta) => ({ | ||
filters: [...meta.filters, ['hue-rotate', escapeStyle(matches[1] || '180deg')]] | ||
})); | ||
optionMatchers.set(/^invert(?::(.+))?$/, (matches, meta) => ({ | ||
filters: [...meta.filters, ['invert', escapeStyle(matches[1] || '1')]] | ||
})); | ||
optionMatchers.set(/^opacity(?::(.+))?$/, (matches, meta) => ({ | ||
filters: [...meta.filters, ['opacity', escapeStyle(matches[1] || '.5')]] | ||
})); | ||
optionMatchers.set(/^saturate(?::(.+))?$/, (matches, meta) => ({ | ||
filters: [...meta.filters, ['saturate', escapeStyle(matches[1] || '2')]] | ||
})); | ||
optionMatchers.set(/^sepia(?::(.+))?$/, (matches, meta) => ({ | ||
filters: [...meta.filters, ['sepia', escapeStyle(matches[1] || '1')]] | ||
})); | ||
} | ||
md.inline.ruler2.push('marpit_parse_image', ({ tokens }) => { | ||
@@ -33,6 +86,17 @@ tokens.forEach(token => { | ||
options.forEach(opt => { | ||
// TODO: Implement cross-browser image zoom without affecting DOM tree | ||
// (Pre-released Marp uses `zoom` but it has not supported in Firefox) | ||
if (opt.match(/^(\d*\.)?\d+%$/)) token.meta.marpitImage.size = opt; | ||
optionMatchers.forEach((mergeFunc, regexp) => { | ||
const matched = opt.match(regexp); | ||
if (matched) token.meta.marpitImage = Object.assign({}, token.meta.marpitImage, mergeFunc(matched, Object.assign({ | ||
filters: [] | ||
}, token.meta.marpitImage))); | ||
}); | ||
}); | ||
// Build and apply filter style | ||
if (token.meta.marpitImage.filters) { | ||
token.meta.marpitImage.filter = token.meta.marpitImage.filters.reduce((arr, fltrs) => [...arr, `${fltrs[0]}(${fltrs[1]})`], []).join(' '); | ||
token.attrJoin('style', `filter:${token.meta.marpitImage.filter};`); | ||
} | ||
} | ||
@@ -39,0 +103,0 @@ }); |
@@ -66,2 +66,3 @@ 'use strict'; | ||
container: _element.marpitContainer, | ||
filters: true, | ||
markdown: 'commonmark', | ||
@@ -83,6 +84,8 @@ printable: true, | ||
* directives about background image. If `inlineSVG` is enabled, it | ||
* supports multiple image layouting. | ||
* supports the advanced backgrounds. | ||
* @param {Element|Element[]} | ||
* [opts.container={@link module:element.marpitContainer}] Container | ||
* element(s) wrapping whole slide deck. | ||
* @param {boolean} [opts.filters=true] Support filter syntax for markdown | ||
* image. It can apply to inline image and the advanced backgrounds. | ||
* @param {string|Object|Array} [opts.markdown='commonmark'] markdown-it | ||
@@ -131,3 +134,3 @@ * initialize option(s). | ||
applyMarkdownItPlugins(md = this.markdown) { | ||
md.use(_comment2.default).use(_slide2.default).use(_parse2.default, this).use(_apply2.default).use(_slide_container2.default, this.slideContainers).use(_container2.default, this.containers).use(_parse_image2.default).use(_sweep2.default).use(_inline_svg2.default, this); | ||
md.use(_comment2.default).use(_slide2.default).use(_parse2.default, this).use(_apply2.default).use(_slide_container2.default, this.slideContainers).use(_container2.default, this.containers).use(_parse_image2.default, { filters: this.options.filters }).use(_sweep2.default).use(_inline_svg2.default, this); | ||
@@ -134,0 +137,0 @@ if (this.options.backgroundSyntax) md.use(_background_image2.default); |
@@ -37,10 +37,13 @@ 'use strict'; | ||
page-break-before: always; | ||
-webkit-print-color-adjust: exact; | ||
color-adjust: exact; | ||
} | ||
section, section * { | ||
-webkit-print-color-adjust: exact !important; | ||
color-adjust: exact !important; | ||
} | ||
:marpit-container > svg { | ||
display: block; | ||
height: 100vh; | ||
width: 100vw; | ||
height: 100vh; | ||
} | ||
@@ -47,0 +50,0 @@ } |
@@ -11,2 +11,6 @@ 'use strict'; | ||
var _advanced_background = require('./postcss/advanced_background'); | ||
var _advanced_background2 = _interopRequireDefault(_advanced_background); | ||
var _inline_svg_workaround = require('./postcss/inline_svg_workaround'); | ||
@@ -184,3 +188,3 @@ | ||
height: this.getThemeProp(theme, 'height') | ||
}), theme !== _scaffold2.default && (css => css.first.before(_scaffold2.default.css)), _prepend2.default, (0, _replace2.default)(opts.containers, slideElements), opts.inlineSVG === 'workaround' && _inline_svg_workaround2.default].filter(p => p)); | ||
}), theme !== _scaffold2.default && (css => css.first.before(_scaffold2.default.css)), opts.inlineSVG && _advanced_background2.default, _prepend2.default, (0, _replace2.default)(opts.containers, slideElements), opts.inlineSVG === 'workaround' && _inline_svg_workaround2.default].filter(p => p)); | ||
@@ -187,0 +191,0 @@ return packer.process(theme.css).css; |
@@ -29,22 +29,2 @@ 'use strict'; | ||
} | ||
/* Advanced background support */ | ||
section[data-marpit-advanced-background="background"] { | ||
display: flex !important; | ||
flex-direction: row !important; | ||
margin: 0 !important; | ||
padding: 0 !important; | ||
} | ||
section[data-marpit-advanced-background="background"] > figure { | ||
all: initial; | ||
background-position: center; | ||
background-repeat: no-repeat; | ||
background-size: cover; | ||
flex: auto; | ||
} | ||
section[data-marpit-advanced-background="content"] { | ||
background: transparent !important; | ||
} | ||
`.trim(); | ||
@@ -58,3 +38,2 @@ | ||
* - Normalize `<h1>` heading style. | ||
* - Support advanced background on inline SVG mode. | ||
* | ||
@@ -61,0 +40,0 @@ * @alias module:theme/scaffold |
{ | ||
"name": "@marp-team/marpit", | ||
"version": "0.0.3", | ||
"version": "0.0.4", | ||
"description": "The skinny framework for creating slide deck from Markdown", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
@@ -55,4 +55,6 @@ <div align="center"> | ||
You can disable by `backgroundSyntax: false` in Marpit constructor option. | ||
When you defined 2 or more background images in a slide, Marpit will show the last defined image only. If you want to show multiple images, try [the advanced backgrounds](#advanced-backgrounds-with-inline-svg-mode) by enabling [inline SVG mode](#inline-svg-slide-experimental). | ||
You can disable by `backgroundSyntax: false` in Marpit constructor option if you not want the `bg` syntax. | ||
#### Resize images | ||
@@ -112,5 +114,7 @@ | ||
The advanced backgrounds will work only with [`inlineSVG: true`](#inline-svg-slide-experimental). It supports multiple background images. | ||
The advanced backgrounds will work _only with [`inlineSVG: true`](#inline-svg-slide-experimental)_. It supports multiple background images, image filters, and split backgrounds. | ||
``` | ||
##### Multiple background images | ||
```markdown | ||
 | ||
@@ -122,5 +126,62 @@  | ||
##### Split backgrounds | ||
The `left` or `right` keyword with `bg` keyword make a space for the background to the specified side. It has a half of slide size, and the space of a slide content will shrink too. | ||
```markdown | ||
 | ||
# Slide contents | ||
The space of a slide content will shrink to the right side. | ||
--- | ||
<!-- Multiple background images will work well in the specified background side. --> | ||
 | ||
 | ||
# Slide contents | ||
The space of a slide content will shrink to the left side. | ||
``` | ||
This feature is similar to [Deckset's Split Slides](https://docs.decksetapp.com/English.lproj/Images%20and%20Videos/01-background-images.html). | ||
> Marpit uses a last defined keyword in a slide when `left` and `right` keyword is mixed in the same slide by using multiple background images. | ||
### Image filters | ||
You can apply CSS filters to image through markdown image syntax. Include `<filter-name>(:<param>(,<params>...))` to the space-separated alternate text of image syntax. | ||
Filters can use in the inline image and [the advanced backgrounds](#advanced-backgrounds-with-inline-svg-mode). You can disable this feature with `filters: false` in Marpit constructor option. | ||
#### Filters | ||
We are following the function of the [`filter` style](https://developer.mozilla.org/en-US/docs/Web/CSS/filter). | ||
| Markdown | (with arguments) | `filter` style | | ||
| ------------------ | -------------------------------------------- | ------------------------------------------- | | ||
| `![blur]()` | `![blur:10px]()` | `blur(10px)` | | ||
| `![brightness]()` | `![brightness:1.5]()` | `brightness(1.5)` | | ||
| `![contrast]()` | `![contrast:200%]()` | `contrast(200%)` | | ||
| `![drop-shadow]()` | `![drop-shadow:0,5px,10px,rgba(0,0,0,.4)]()` | `drop-shadow(0 5px 10px rgba(0, 0, 0, .4))` | | ||
| `![grayscale]()` | `![grayscale:1]()` | `grayscale(1)` | | ||
| `![hue-rotate]()` | `![hue-rotate:180deg]()` | `hue-rotate(180deg)` | | ||
| `![invert]()` | `![invert:100%]()` | `invert(100%)` | | ||
| `![opacity]()` | `![opacity:.5]()` | `opacity(.5)` | | ||
| `![saturate]()` | `![saturate:2.0]()` | `saturate(2.0)` | | ||
| `![sepia]()` | `![sepia:1.0]()` | `sepia(1.0)` | | ||
Marpit will use the default arguments shown in above when you omit arguments. | ||
Naturally multiple filters can apply to a image. | ||
```markdown | ||
 | ||
``` | ||
### ToDo | ||
* [ ] Background filters in advanced backgrounds | ||
* [ ] Header and footer directive | ||
@@ -127,0 +188,0 @@ * [ ] Slide page number |
74737
31
1522
291