load-mathjax.ts 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import getMeta from '../../utils/meta'
  2. let mathJaxPromise: Promise<typeof window.MathJax>
  3. export const loadMathJax = async (options?: {
  4. enableMenu?: boolean
  5. numbering?: string
  6. singleDollar?: boolean
  7. useLabelIds?: boolean
  8. }) => {
  9. if (!mathJaxPromise) {
  10. mathJaxPromise = new Promise((resolve, reject) => {
  11. options = {
  12. enableMenu: false,
  13. singleDollar: true,
  14. useLabelIds: false,
  15. ...options,
  16. }
  17. const inlineMath = [['\\(', '\\)']]
  18. if (options.singleDollar) {
  19. inlineMath.push(['$', '$'])
  20. }
  21. // https://docs.mathjax.org/en/v3.2-latest/upgrading/v2.html
  22. window.MathJax = {
  23. // https://docs.mathjax.org/en/latest/options/input/tex.html#the-configuration-block
  24. tex: {
  25. macros: {
  26. // Implements support for the \bm command from the bm package. It bolds the argument in math mode.
  27. // https://github.com/mathjax/MathJax/issues/1219#issuecomment-341059843
  28. bm: ['\\boldsymbol{#1}', 1],
  29. },
  30. inlineMath,
  31. displayMath: [
  32. ['\\[', '\\]'],
  33. ['$$', '$$'],
  34. ],
  35. packages: {
  36. '[-]': [
  37. 'html', // avoid creating HTML elements/attributes
  38. 'require', // prevent loading disabled packages
  39. ],
  40. },
  41. processEscapes: true,
  42. processEnvironments: true,
  43. useLabelIds: options.useLabelIds,
  44. tags: options.numbering,
  45. },
  46. loader: {
  47. load: [
  48. 'ui/safe', // https://docs.mathjax.org/en/latest/options/safe.html
  49. ],
  50. },
  51. options: {
  52. enableMenu: options.enableMenu, // https://docs.mathjax.org/en/latest/options/menu.html
  53. },
  54. startup: {
  55. typeset: false,
  56. pageReady() {
  57. // disable the "Math Renderer" option in the context menu,
  58. // as only SVG is available
  59. window.MathJax.startup.document.menu.menu
  60. .findID('Renderer')
  61. .disable()
  62. },
  63. },
  64. }
  65. const script = document.createElement('script')
  66. const path = getMeta('ol-mathJaxPath')
  67. if (!path) {
  68. reject(new Error('No MathJax path found'))
  69. return
  70. }
  71. script.src = path
  72. script.addEventListener('load', async () => {
  73. await window.MathJax.startup.promise
  74. document.head.appendChild(window.MathJax.svgStylesheet())
  75. resolve(window.MathJax)
  76. })
  77. script.addEventListener('error', reject)
  78. document.head.append(script)
  79. })
  80. }
  81. return mathJaxPromise
  82. }