html.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /**
  2. * @import {HtmlOptions as Options} from 'micromark-extension-math'
  3. * @import {HtmlExtension} from 'micromark-util-types'
  4. */
  5. import katex from 'katex';
  6. const renderToString = katex.renderToString;
  7. /**
  8. * Create an extension for `micromark` to support math when serializing to
  9. * HTML.
  10. *
  11. * > 👉 **Note**: this uses KaTeX to render math.
  12. *
  13. * @param {Options | null | undefined} [options={}]
  14. * Configuration (default: `{}`).
  15. * @returns {HtmlExtension}
  16. * Extension for `micromark` that can be passed in `htmlExtensions`, to
  17. * support math when serializing to HTML.
  18. */
  19. export function mathHtml(options) {
  20. return {
  21. enter: {
  22. mathFlow() {
  23. this.lineEndingIfNeeded();
  24. this.tag('<div class="math math-display">');
  25. },
  26. mathFlowFenceMeta() {
  27. this.buffer();
  28. },
  29. mathText() {
  30. // Double?
  31. this.tag('<span class="math math-inline">');
  32. this.buffer();
  33. }
  34. },
  35. exit: {
  36. mathFlow() {
  37. const value = this.resume();
  38. this.tag(math(value.replace(/(?:\r?\n|\r)$/, ''), true));
  39. this.tag('</div>');
  40. this.setData('mathFlowOpen');
  41. this.setData('slurpOneLineEnding');
  42. },
  43. mathFlowFence() {
  44. // After the first fence.
  45. if (!this.getData('mathFlowOpen')) {
  46. this.setData('mathFlowOpen', true);
  47. this.setData('slurpOneLineEnding', true);
  48. this.buffer();
  49. }
  50. },
  51. mathFlowFenceMeta() {
  52. this.resume();
  53. },
  54. mathFlowValue(token) {
  55. this.raw(this.sliceSerialize(token));
  56. },
  57. mathText() {
  58. const value = this.resume();
  59. this.tag(math(value, false));
  60. this.tag('</span>');
  61. },
  62. mathTextData(token) {
  63. this.raw(this.sliceSerialize(token));
  64. }
  65. }
  66. };
  67. /**
  68. * @param {string} value
  69. * Math text.
  70. * @param {boolean} displayMode
  71. * Whether the math is in display mode.
  72. * @returns {string}
  73. * HTML.
  74. */
  75. function math(value, displayMode) {
  76. return renderToString(value, {
  77. ...options,
  78. displayMode
  79. });
  80. }
  81. }