math.ts 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. import { getEnvironmentName } from './environments'
  2. import { EditorState } from '@codemirror/state'
  3. import { SyntaxNode, SyntaxNodeRef } from '@lezer/common'
  4. import { ancestorNodeOfType } from './ancestors'
  5. export type MathContainer = {
  6. content: string
  7. displayMode: boolean
  8. passToMathJax: boolean
  9. pos: number
  10. }
  11. export const mathAncestorNode = (state: EditorState, pos: number) =>
  12. ancestorNodeOfType(state, pos, '$MathContainer') ||
  13. ancestorNodeOfType(state, pos, 'EquationEnvironment') ||
  14. // NOTE: EquationArrayEnvironment can be nested inside EquationEnvironment
  15. ancestorNodeOfType(state, pos, 'EquationArrayEnvironment')
  16. export const parseMathContainer = (
  17. state: EditorState,
  18. nodeRef: SyntaxNodeRef,
  19. ancestorNode: SyntaxNode
  20. ): MathContainer | null => {
  21. // the content of the Math element, without braces
  22. const innerContent = state.doc.sliceString(nodeRef.from, nodeRef.to).trim()
  23. if (!innerContent.length) {
  24. return null
  25. }
  26. let content = innerContent
  27. let displayMode = false
  28. let passToMathJax = true
  29. let pos = nodeRef.from
  30. if (ancestorNode.type.is('$Environment')) {
  31. const environmentName = getEnvironmentName(ancestorNode, state)
  32. if (environmentName) {
  33. // use the outer content of environments that MathJax supports
  34. // https://docs.mathjax.org/en/latest/input/tex/macros/index.html#environments
  35. if (environmentName === 'tikzcd') {
  36. passToMathJax = false
  37. }
  38. if (environmentName !== 'math' && environmentName !== 'displaymath') {
  39. content = state.doc
  40. .sliceString(ancestorNode.from, ancestorNode.to)
  41. .trim()
  42. pos = ancestorNode.from
  43. }
  44. if (environmentName !== 'math') {
  45. displayMode = true
  46. }
  47. }
  48. } else {
  49. if (
  50. ancestorNode.type.is('BracketMath') ||
  51. Boolean(ancestorNode.getChild('DisplayMath'))
  52. ) {
  53. displayMode = true
  54. }
  55. }
  56. return { content, displayMode, passToMathJax, pos }
  57. }