detach-code-blocks.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import { BasicInterceptor } from 'crowi-pluginkit';
  4. class DetachCodeBlockUtil {
  5. static createReplaceStr(replaceId) {
  6. return `<pre>${replaceId}</pre>`;
  7. }
  8. }
  9. /**
  10. * The interceptor that detach code blocks
  11. */
  12. export class DetachCodeBlockInterceptor extends BasicInterceptor {
  13. constructor(crowi) {
  14. super();
  15. this.crowi = crowi;
  16. this.crowiForJquery = crowi.getCrowiForJquery();
  17. }
  18. /**
  19. * @inheritdoc
  20. */
  21. isInterceptWhen(contextName) {
  22. return (
  23. contextName === 'prePreProcess'
  24. );
  25. }
  26. /**
  27. * @inheritdoc
  28. */
  29. process(contextName, ...args) {
  30. const context = Object.assign(args[0]); // clone
  31. const markdown = context.markdown;
  32. const currentPagePath = context.currentPagePath;
  33. context.dcbContextMap = {};
  34. // see: https://regex101.com/r/8PAEcC/1
  35. context.markdown = markdown.replace(/```(.|[\r\n])*?```/gm, (all) => {
  36. // create ID
  37. const replaceId = 'dcb-' + this.createRandomStr(8);
  38. // register to context
  39. let dcbContext = {};
  40. dcbContext.content = all;
  41. dcbContext.substituteContent = DetachCodeBlockUtil.createReplaceStr(replaceId);
  42. context.dcbContextMap[replaceId] = dcbContext;
  43. // return substituteContent
  44. return dcbContext.substituteContent;
  45. });
  46. // resolve
  47. return Promise.resolve(context);
  48. }
  49. /**
  50. * @see http://qiita.com/ryounagaoka/items/4736c225bdd86a74d59c
  51. *
  52. * @param {number} length
  53. * @return random strings
  54. */
  55. createRandomStr(length) {
  56. const bag = "abcdefghijklmnopqrstuvwxyz0123456789";
  57. let generated = "";
  58. for (var i = 0; i < length; i++) {
  59. generated += bag[Math.floor(Math.random() * bag.length)];
  60. }
  61. return generated;
  62. }
  63. }
  64. /**
  65. * The interceptor that restore detached code blocks
  66. */
  67. export class RestoreCodeBlockInterceptor extends BasicInterceptor {
  68. constructor(crowi) {
  69. super();
  70. this.crowi = crowi;
  71. this.crowiForJquery = crowi.getCrowiForJquery();
  72. }
  73. /**
  74. * @inheritdoc
  75. */
  76. isInterceptWhen(contextName) {
  77. return (
  78. contextName === 'postPreProcess'
  79. );
  80. }
  81. /**
  82. * @inheritdoc
  83. */
  84. process(contextName, ...args) {
  85. const context = Object.assign(args[0]); // clone
  86. // forEach keys of dcbContextMap
  87. Object.keys(context.dcbContextMap).forEach((replaceId) => {
  88. // get context object from context
  89. let dcbContext = context.dcbContextMap[replaceId];
  90. context.markdown = context.markdown.replace(dcbContext.substituteContent, dcbContext.content);
  91. });
  92. // resolve
  93. return Promise.resolve(context);
  94. }
  95. }