marp-team / marp-core

The core of Marp converter
MIT License
774 stars 129 forks source link

Support for prism js #194

Closed asm0dey closed 2 years ago

asm0dey commented 4 years ago

Please, add option to replace highlightjs with prism for highlighting. It adds much more useful and consistent highlighting for kotlin, current state may be found in this repo: https://github.com/asm0dey/kotlin-spark/

Sometimes code blocks are almost not highlighted and sometimes they are being highlighted inconsistently. Prismjs has lots of plugins and support for lots of languages.

yhatt commented 4 years ago

We had tried to replace the highlgihter to Prism.js once by an other reason: has less bundle size than highlight.js if we had not bundled unpopular languages. It's popular also in other markdown processors so we think using Prism.js in Marp has a worth.

If you have already tried to use custom engine of Marp CLI, you can try to replace the highlighter to Prism.js manually. Override highlighter() method of a marp instance, and follow the usage of Prism.js for Node.js: https://prismjs.com/#basic-usage-node

Here is the example to override highlighter. It's for highlight.js plugin but still useful in Prism.js.

asm0dey commented 4 years ago

Thank you! And what's the best way to add CSS?

yhatt commented 4 years ago

Include Prism's CSS in Marp's theme CSS.

asm0dey commented 4 years ago

It works! And next question: what's the way to support line highlighting? Prism suggests to set attribute on pre block, but it looks like it's not available to me

yhatt commented 4 years ago

Uh, I don't want to take care of personal support because we are following our support guideline. This issue is a ticket about replacing Marp Core's highlighter.

asm0dey commented 4 years ago

Agreed, sorry for disturbing. Let this issue be about replacement highlightjs with prism.

Thank you for help!

yhatt commented 3 years ago

By discussion in marp-team/marp#103, we are more likely to take better highlighter instead of highlight.js in future. It can provide easy to customize the color scheme by combination with CSS variables.

This change may break existing slide style so the new highlighter would be adopted in the future major update of Marp Core.

codingluke commented 2 years ago

Hello @yhatt, I am wondering if you already know https://shiki.matsu.io/. Looks like some static site generators are switching to this at the moment, https://github.com/withastro/astro/issues/1212.

Thanks for your work!

yhatt commented 2 years ago

Yes, I know! Shiki is completely ready for server-side highlighting, and already used in other Markdown slide tool Slidev.

An only blocker is what markdown-it Markdown processor used by Marp is not compatible with Promise (async/await). This fact actually makes difficult to integrate Shiki highlighter with Marp. https://github.com/markdown-it/markdown-it/blob/master/docs/development.md#i-need-async-rule-how-to-do-it

To accept more highlighters, we are planning the next-gen engine of Marpit framework that is supporting asynchronous Markdown parsing.

codingluke commented 2 years ago

Great to see it is on your roadmap :)

It looks like the folks from slidev also use markdown-it and wrote a shiki plugin which is using a workaround to handle async

Anyway, I am not too into the codebase. Might be that it works for them as they are starting a whole webserver with vite and co..

yhatt commented 2 years ago

Nice. markdown-it-shiki is already working in Marp, and css-variables theme is the closest approach what we wanted. :sparkles:

// engine.js
const { default: markdownItShiki } = require('markdown-it-shiki');

module.exports = ({ marp }) =>
  marp.use(markdownItShiki, { theme: 'css-variables' })
npm i --save @marp-team/marp-core@next @marp-team/marp-cli markdown-it-shiki
npx @marp-team/marp-cli --engine ./engine.js markdown.md

This integration looks like promising than old-fashioned Prism.

yhatt commented 2 years ago

Let us discuss continously about new highlighter architecture at #296.

Marp Core still keeps highlighter changeable via markdown-it plugins. Prism.js integration would be better to do as Marp/markdown-it plugin (e.g. https://www.npmjs.com/package/markdown-it-prism).

kyle-west commented 1 year ago

For what it is worth: I was able to switch to PrismJS by changing the highlighter in the engine.js file like was mentioned. Below are the steps I took.

npm i @marp-team/marp-core prismjs
// engine.js

const { Marp } = require('@marp-team/marp-core')
const Prism = require('prismjs');

// you may need to load the language you want to use
// see: https://prismjs.com/#supported-languages
const loadLanguages = require('prismjs/components/');
loadLanguages(['jsx', 'tsx']);

function getLanguageConfig(lang) {
  if (lang && Prism.languages[lang]) {
    return [Prism.languages[lang], lang]
  }
  return [Prism.languages.plaintext, 'plaintext']
}

module.exports = (opts) => {
  const marp = new Marp(opts)

  marp.highlighter = (code, lang) => Prism.highlight(code, ...getLanguageConfig(lang))

  return marp
}

Hooking the CSS up was as easy as copying one of prismjs/themes files under node modules into my project themes folder and adding /* @theme prism-base */ to the top so I could use it in marp. It worked great with the dracula prism theme as well!

Note: I had a hard time getting marp --engine engine.js to work, it turns out that it needed a ./, I changed it to marp --engine ./engine.js and it worked right away.

ChiMaoShuPhy commented 1 week ago

Nice. markdown-it-shiki is already working in Marp, and css-variables theme is the closest approach what we wanted. ✨

// engine.js
const { default: markdownItShiki } = require('markdown-it-shiki');

module.exports = ({ marp }) =>
  marp.use(markdownItShiki, { theme: 'css-variables' })
npm i --save @marp-team/marp-core@next @marp-team/marp-cli markdown-it-shiki
npx @marp-team/marp-cli --engine ./engine.js markdown.md

This integration looks like promising than old-fashioned Prism.

I'm wondering whether this approach still works in the latest marp-cli (v3.4.0)? I have tried this example but the code block are not getting rendered.

yhatt commented 1 week ago

markdown-it-shiki has been deprecated. Try the official markdown-it plugin https://shiki.style/packages/markdown-it instead.