growi-marpit.ts 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. import { Marp, MarpOptions } from '@marp-team/marp-core';
  2. import { Element } from '@marp-team/marpit';
  3. export const MARP_CONTAINER_CLASS_NAME = 'marpit';
  4. // Add data-line to Marp slide.
  5. // https://github.com/marp-team/marp-vscode/blob/d9af184ed12b65bb28c0f328e250955d548ac1d1/src/plugins/line-number.ts
  6. const sourceMapIgnoredTypesForElements = ['inline', 'marpit_slide_open'];
  7. const lineNumber = (md) => {
  8. const { marpit_slide_containers_open: marpitSlideContainersOpen } = md.renderer.rules;
  9. // Enable line sync by per slides
  10. md.renderer.rules.marpit_slide_containers_open = (tks, i, opts, env, slf) => {
  11. const slide = tks.slice(i + 1).find(t => t.type === 'marpit_slide_open');
  12. if (slide?.map?.length) {
  13. tks[i].attrJoin('class', 'has-data-line');
  14. tks[i].attrSet('data-line', slide.map[0]);
  15. }
  16. const renderer = marpitSlideContainersOpen || slf.renderToken;
  17. return renderer.call(slf, tks, i, opts, env, slf);
  18. };
  19. // Enables line sync per elements
  20. md.core.ruler.push('marp_growi_source_map_attr', (state) => {
  21. for (const token of state.tokens) {
  22. if (
  23. token.map?.length
  24. && !sourceMapIgnoredTypesForElements.includes(token.type)
  25. ) {
  26. token.attrJoin('class', 'has-data-line');
  27. token.attrSet('data-line', token.map[0]);
  28. }
  29. }
  30. });
  31. };
  32. const marpitOption: MarpOptions = {
  33. container: [
  34. new Element('div', { class: `slides ${MARP_CONTAINER_CLASS_NAME}` }),
  35. ],
  36. inlineSVG: true,
  37. emoji: undefined,
  38. html: false,
  39. math: false,
  40. };
  41. const slideMarpitOption = marpitOption;
  42. slideMarpitOption.slideContainer = (
  43. [new Element('section', { class: 'shadow rounded m-2' })]
  44. );
  45. export const slideMarpit = new Marp(slideMarpitOption).use(lineNumber);
  46. const presentationMarpitOption = marpitOption;
  47. presentationMarpitOption.slideContainer = (
  48. [new Element('section', { class: 'm-2' })]
  49. );
  50. export const presentationMarpit = new Marp(presentationMarpitOption);