Skip to content

Commit

Permalink
Add Marpit PostCSS container query plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
yhatt committed Oct 15, 2023
1 parent 0d274b9 commit 4ae86da
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/marpit.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import ThemeSet from './theme_set'
const defaultOptions = {
anchor: true,
container: marpitContainer,
cssContainerQuery: false,
headingDivider: false,
lang: undefined,
looseYAML: false,
Expand Down Expand Up @@ -68,6 +69,10 @@ class Marpit {
* @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 {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
Expand Down Expand Up @@ -264,6 +269,7 @@ class Marpit {
],
inlineSVG: this.inlineSVGOptions,
printable: this.options.printable,
containerQuery: this.options.cssContainerQuery,
}
}

Expand Down
53 changes: 53 additions & 0 deletions src/postcss/container_query.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/** @module */
import cssesc from 'cssesc'
import postcssPlugin from '../helpers/postcss_plugin'

const reservedNames = [
'none',
'inherit',
'initial',
'revert',
'revert-layer',
'unset',
]

/**
* 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
*/
export const containerQuery = postcssPlugin(
'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
? cssesc(name.toString(), { isIdentifier: true })
: name.toString(),
)
.join(' ')};`
: ''

css.first.before(
`
:where(section) {
container-type: size;${containerNameDeclaration}
}
`.trim(),
)
},
)

export default containerQuery
11 changes: 11 additions & 0 deletions src/theme_set.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import postcss from 'postcss'
import postcssPlugin from './helpers/postcss_plugin'
import postcssAdvancedBackground from './postcss/advanced_background'
import postcssContainerQuery from './postcss/container_query'
import postcssImportHoisting from './postcss/import/hoisting'
import postcssImportReplace from './postcss/import/replace'
import postcssImportSuppress from './postcss/import/suppress'
Expand Down Expand Up @@ -236,6 +237,9 @@ class ThemeSet {
* @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)_
Expand Down Expand Up @@ -263,6 +267,12 @@ class ThemeSet {
const after = additionalCSS(opts.after)
const before = additionalCSS(opts.before)

const containerName =
typeof opts.containerQuery === 'string' ||
Array.isArray(opts.containerQuery)
? opts.containerQuery
: undefined

const packer = postcss(
[
before &&
Expand All @@ -274,6 +284,7 @@ class ThemeSet {
postcssPlugin('marpit-pack-after', () => (css) => {
css.last.after(after)
}),
opts.containerQuery && postcssContainerQuery(containerName),
postcssImportHoisting,
postcssImportReplace(this),
opts.printable &&
Expand Down

0 comments on commit 4ae86da

Please sign in to comment.