Skip to content

Conversation

@yhatt
Copy link
Member

@yhatt yhatt commented Oct 10, 2025

Enables the use of PostCSS plugins via Marpit#use.

import { Marpit } from '@marp-team/marpit'
import postcssOrderedValues from 'postcss-ordered-values'
import postcssNormalizeString from 'postcss-normalize-string'

// Simple
const simple = new Marpit()
  .use(postcssOrderedValues)
  .render('<style>h1 { border: solid 1px red; }</style>')

console.log(simple.css.includes('border: solid 1px red;')) // false (not ordered)
console.log(simple.css.includes('border: 1px solid red;')) // true (ordered)

// With options
const withOpts = new Marpit()
  .use(postcssNormalizeString, { preferredQuote: 'single' })
  .render('<style>h1 { content: "test \\"test\\""; }</style>')

console.log(withOpts.css.includes(`content: "test \\"test\\"";`)) // false (not normalized)
console.log(withOpts.css.includes(`content: 'test "test"';`)) // true (normalized)

// With generated plugin
const generatedPlugin = postcssNormalizeString({ preferredQuote: 'single' })
const withGen = new Marpit()
  .use(generatedPlugin)
  .render('<style>h1 { content: "test \\"test\\""; }</style>')

console.log(withGen.css.includes(`content: "test \\"test\\"";`)) // false (not normalized)
console.log(withGen.css.includes(`content: 'test "test"';`)) // true (normalized)

Previously Marpit only allowed markdown-it plugins. By enabling post-processors for CSS with the same interface, users can customize styles more flexibly.

Currently, Marp Core applies post-processors to the rendered styles by overloading a Marpit's class method #renderStyle. This was an inefficient implementation because 2 instances of PostCSS were held in Marp Core.
https://github.com/marp-team/marp-core/blob/c20422eb2f18e0bde36bd610ca66c1d9c9f68903/src/marp.ts#L110-L120

This change is expected to make style post-processing in Marp Core and 3rd party Marpit-based engines smarter.

Close #418.

@yhatt yhatt requested a review from Copilot October 10, 2025 17:55
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR enables the use of PostCSS plugins via the Marpit#use method, expanding the plugin system beyond markdown-it plugins to include CSS post-processing capabilities. This allows users to customize styles more flexibly and makes style post-processing more efficient in Marpit-based engines.

  • Added support for PostCSS plugins in the Marpit#use method with automatic detection
  • Refactored theme CSS processing to consolidate plugin management in ThemeSet
  • Updated documentation to reflect the expanded plugin system capabilities

Reviewed Changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/marpit.js Enhanced use() method to detect and handle PostCSS plugins alongside markdown-it plugins
src/theme_set.js Added plugin management system and refactored CSS processing to use dedicated PostCSS modules
src/postcss/after.js New PostCSS plugin for appending styles after current CSS
src/postcss/before.js New PostCSS plugin for prepending styles before current CSS
src/postcss/scaffold.js New PostCSS plugin for scaffold theme CSS insertion
src/postcss/import/suppress.js Updated comment to clarify plugin purpose
test/marpit.js Added comprehensive tests for PostCSS plugin functionality
docs/usage.md Updated documentation to include PostCSS plugin usage examples

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@yhatt yhatt merged commit 77b8ee7 into main Oct 10, 2025
4 checks passed
@yhatt yhatt deleted the use-postcss-plugin branch October 10, 2025 18:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Pluggable PostCSS plugins with use()

2 participants