Math Node Type

Category: Custom • Detailed implementation guide with view integration notes

Schema Definition

Schema definition for the Math node type:

{
  math: {
    group: 'block',
    attrs: {
      formula: { default: '' },
      display: { default: false }
    },
  }
}

Model Representation

Example model representation:

{
  type: 'math',
  attrs: {
    formula: 'E = mc^2',
    display: true
  }
}

HTML Serialization

Converting model to HTML:

function serializeMath(node) {
  return '<div data-type="math" data-display="' + node.attrs.display + '">' + 
         escapeHtml(node.attrs.formula) + '</div>';
}

HTML Deserialization

Parsing HTML to model:

function parseMath(domNode) {
  return {
    type: 'math',
    attrs: {
      formula: domNode.textContent || '',
      display: domNode.getAttribute('data-display') === 'true'
    }
  };
}

View Integration

View Integration Notes: Pay special attention to contenteditable behavior, selection handling, and event management when implementing this node type in your view layer.

View integration code:

// Rendering math
const math = document.createElement('div');
math.setAttribute('data-type', 'math');
math.setAttribute('data-display', node.attrs.display);
math.textContent = node.attrs.formula;
math.contentEditable = 'false'; // Math is typically rendered, not edited directly

// Render with MathJax or KaTeX
function renderMath(element) {
  if (window.MathJax) {
    MathJax.typesetPromise([element]);
  } else if (window.katex) {
    katex.render(element.textContent, element, { displayMode: element.getAttribute('data-display') === 'true' });
  }
}

Common Issues

Common Pitfalls: These are issues frequently encountered when implementing this node type. Review carefully before implementation.

Common issues and solutions:

// Issue: Math rendering library
// Solution: Use MathJax or KaTeX
function initMathRenderer() {
  if (window.MathJax) {
    MathJax.startup.defaultReady();
  }
}

// Issue: Math formula validation
// Solution: Validate LaTeX syntax
function validateMathFormula(formula) {
  // Basic validation or use a LaTeX parser
  return formula.length > 0;
}

Implementation

Complete implementation example:

class MathNode {
  constructor(attrs) {
    this.type = 'math';
    this.attrs = {
      formula: attrs?.formula || '',
      display: attrs?.display || false
    };
  }
  
  toDOM() {
    const math = document.createElement('div');
    math.setAttribute('data-type', 'math');
    math.setAttribute('data-display', this.attrs.display);
    math.textContent = this.attrs.formula;
    return math;
  }
  
  static fromDOM(domNode) {
    return new MathNode({
      formula: domNode.textContent || '',
      display: domNode.getAttribute('data-display') === 'true'
    });
  }
}