marp-team / marp-cli

A CLI interface for Marp and Marpit based converters
MIT License
1.84k stars 105 forks source link

defining md.renderer.rules in custom engine with markdown-it-plugins #226

Closed simonmaris closed 4 years ago

simonmaris commented 4 years ago

I am trying to create a custom engine combining marp-core and markdown-it-footnote to use with marp-cli. Currently my engine.js file looks like this:

const { Marp } = require('@marp-team/marp-core')
const markdownItFootnote = require('markdown-it-footnote')

const md = require('markdown-it')().use(require('markdown-it-footnote'));

This works great, but I would like to customize the markdown-it-footnote output, however I am struggling to add this the right way.

const md = require('markdown-it')().use(require('markdown-it-footnote'));

md.renderer.rules.footnote_block_open = () => (
  '<h4 class="mt-3">Footnotes</h4>\n' +
  '<section class="footnotes">\n' +
  '<ol class="footnotes-list">\n'
);

I couldn't find any examples of a custom engine that extends md.renderer.rules. I saw the official plugins like math using marpitPlugin, would this be the way to go?

I would be very grateful for a pointer or basic example!

yhatt commented 4 years ago

Thanks for helping to manage issues (https://github.com/marp-team/marp-cli/issues/224#issuecomment-622926920). Try this if using Marp CLI's custom engine:

// custom-engine.js
const { Marp } = require('@marp-team/marp-core')
const markdownItFootnote = require('markdown-it-footnote')

module.exports = (opts) => {
  const md = new Marp(opts).use(markdownItFootnote)

  // Customize renderer
  md.renderer.rules.footnote_block_open = () => (
    '<h4 class="mt-3">Footnotes</h4>\n' +
    '<section class="footnotes">\n' +
    '<ol class="footnotes-list">\n'
  );

  return md
}

NOTE: markdown-it-footnote is known as one of plugin not compatible with Marp / Marpit. Probably it would not work as you expected.

simonmaris commented 4 years ago

Thank you, I changed md.renderer.rules.footnote_block_open = … to md.markdown.renderer.rules.footnote_block_open = … and it worked. But yes, I obviously should have thought about the issue of footnote insertion in general more before going down this road.. I see it was disussed earlier here.

Is this still on the roadmap to get something like footnotes on a slide/section basis?

Another idea I had was to add a directive, sort of like footer and header, that way it would at least be easy to have a box somewhere on the slide to but image credits / links etc into. In a presentation that would be all I would use footnotes for. The styling and positioning would be much easier this way.

yhatt commented 4 years ago

Marpit and Marp Core must follow CommonMark, and footnote is not part of CommonMark so we have not any plan for built-in support. Marp team has a policy that we should not break CommonMark as far as possible.

We have well-documented Marpit API to help making third-party plugins by our community. I wish that community develops and provides Marpit plugin for footnote per each slides.

FYI Marp community has a precedent using markdown-it-container as a footnote block: guoxue-study/tongjian (Chinese). The definition of engine.js is here.

yhatt commented 4 years ago

About markdown-it-footnote is off-topic in this issue. Close to mark as resolved the original question.

simonmaris commented 4 years ago

The link to tongijan looks like a good workaround, I will explore it further!

Thank you so much for your help today and yesterday! I was going to close, you beat me by seconds :)

StefanZander commented 4 years ago

Hi @simonmaris, I have a rather similar workflow and also would like to use footnotes in my markdonw-based slides. So my question is: how did you manage to get the footnote-plugin to work with marp-cli and are footnotes placed on only on the slides on which they were defined?

Can you, maybe, post your solution?

When I added footnotes to one slide, they are rendered adjacent to the header and footer section on every slide and listed only on the last slide.

Thanks in advance!

jtppragg commented 3 years ago

Hi @StefanZander, maybe this solution works also for you: https://github.com/marp-team/marp-cli/issues/300#issuecomment-727890849

spkane commented 4 months ago

This was mentioned in the comments above, but for easier discovery, there is a typo in the original code block example.

md.renderer.rules.footnote_block_open should read md.markdown.renderer.rules.footnote_block_open

// custom-engine.js
const { Marp } = require('@marp-team/marp-core')
const markdownItFootnote = require('markdown-it-footnote')

module.exports = (opts) => {
  const md = new Marp(opts).use(markdownItFootnote)

  // Customize renderer
  md.markdown.renderer.rules.footnote_block_open = () => (
    '<h4 class="mt-3">Footnotes</h4>\n' +
    '<section class="footnotes">\n' +
    '<ol class="footnotes-list">\n'
  );

  return md
}