growi-renderer.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import GrowiRenderer from '../../GrowiRenderer';
  2. /**
  3. * reveal.js growi-renderer plugin.
  4. */
  5. (function(root, factory) {
  6. // parent window DOM (crowi.js) of presentation window.
  7. const parentWindow = window.parent;
  8. // create GrowiRenderer instance and setup.
  9. const growiRenderer = new GrowiRenderer(parentWindow.crowi, parentWindow.crowiRenderer, { mode: 'editor' });
  10. const growiRendererPlugin = factory(growiRenderer);
  11. growiRendererPlugin.initialize();
  12. }(this, (growiRenderer) => {
  13. /* eslint-disable no-useless-escape */
  14. const DEFAULT_SLIDE_SEPARATOR = '^\r?\n---\r?\n$';
  15. const DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR = '\\\.element\\\s*?(.+?)$';
  16. const DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR = '\\\.slide:\\\s*?(\\\S.+?)$';
  17. /* eslint-enable no-useless-escape */
  18. let marked;
  19. /**
  20. * Add data separator before lines
  21. * starting with '#' to markdown.
  22. */
  23. function divideSlides() {
  24. const sections = document.querySelectorAll('[data-markdown]');
  25. for (let i = 0, len = sections.length; i < len; i++) {
  26. const section = sections[i];
  27. const markdown = marked.getMarkdownFromSlide(section);
  28. const context = { markdown };
  29. const interceptorManager = growiRenderer.crowi.interceptorManager;
  30. let dataSeparator = section.getAttribute('data-separator') || DEFAULT_SLIDE_SEPARATOR;
  31. // replace string '\n' to LF code.
  32. dataSeparator = dataSeparator.replace(/\\n/g, '\n');
  33. const replaceValue = `${dataSeparator}#`;
  34. // detach code block.
  35. interceptorManager.process('prePreProcess', context);
  36. // if there is only '\n' in the first line, replace it.
  37. context.markdown = context.markdown.replace(/^\n/, '');
  38. // add data separator to markdown.
  39. context.markdown = context.markdown.replace(/[\n]+#/g, replaceValue);
  40. // restore code block.
  41. interceptorManager.process('postPreProcess', context);
  42. section.innerHTML = marked.createMarkdownSlide(context.markdown);
  43. }
  44. }
  45. /**
  46. * Converts data-markdown slides to HTML slides by GrowiRenderer.
  47. */
  48. function convertSlides() {
  49. const sections = document.querySelectorAll('[data-markdown]');
  50. let markdown;
  51. const interceptorManager = growiRenderer.crowi.interceptorManager;
  52. for (let i = 0, len = sections.length; i < len; i++) {
  53. const section = sections[i];
  54. // Only parse the same slide once
  55. if (!section.getAttribute('data-markdown-parsed')) {
  56. section.setAttribute('data-markdown-parsed', 'true');
  57. const notes = section.querySelector('aside.notes');
  58. markdown = marked.getMarkdownFromSlide(section);
  59. const context = { markdown };
  60. interceptorManager.process('preRender', context)
  61. .then(() => { return interceptorManager.process('prePreProcess', context) })
  62. .then(() => {
  63. context.markdown = growiRenderer.preProcess(context.markdown);
  64. })
  65. .then(() => { return interceptorManager.process('postPreProcess', context) })
  66. .then(() => {
  67. context.parsedHTML = growiRenderer.process(context.markdown);
  68. })
  69. .then(() => { return interceptorManager.process('prePostProcess', context) })
  70. .then(() => {
  71. context.parsedHTML = growiRenderer.postProcess(context.parsedHTML);
  72. })
  73. .then(() => { return interceptorManager.process('postPostProcess', context) })
  74. .then(() => { return interceptorManager.process('preRenderHtml', context) })
  75. .then(() => { return interceptorManager.process('postRenderHtml', context) })
  76. .then(() => {
  77. section.innerHTML = context.parsedHTML;
  78. });
  79. marked.addAttributes(section, section, null, section.getAttribute('data-element-attributes')
  80. || section.parentNode.getAttribute('data-element-attributes')
  81. || DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR,
  82. section.getAttribute('data-attributes')
  83. || section.parentNode.getAttribute('data-attributes')
  84. || DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR);
  85. // If there were notes, we need to re-add them after
  86. // having overwritten the section's HTML
  87. if (notes) {
  88. section.appendChild(notes);
  89. }
  90. }
  91. }
  92. }
  93. // API
  94. return {
  95. async initialize() {
  96. growiRenderer.setup();
  97. marked = require('./markdown').default(growiRenderer.process);
  98. divideSlides();
  99. marked.processSlides();
  100. convertSlides();
  101. },
  102. };
  103. }));