# renderer/canvas/symbols/MathSymbolCanvasRenderer.js

    import { rendererLogger as logger } from '../../../configuration/LoggerConfig'
    import { drawStroke } from './StrokeSymbolCanvasRenderer'
    import * as InkModel from '../../../model/InkModel'

    /**
     * @type {{inputCharacter: String, char: String, string: String, textLine: String}}
     */
    export const MathSymbols = {
      nonTerminalNode: 'nonTerminalNode',
      terminalNode: 'terminalNode',
      rule: 'rule'
    }

    function drawTerminalNode (context, terminalNode, model, stroker) {
      terminalNode.inkRanges.forEach((inkRange) => {
        InkModel.extractStrokesFromInkRange(model, inkRange.component, inkRange.component, inkRange.firstItem, inkRange.lastItem)
          .forEach(stroke => drawStroke(context, stroke, stroker))
      })
    }

    /**
     * Draw a math symbol
     * @param {Object} context Current rendering context
     * @param {Object} symbol Symbol to draw
     * @param {Model} model Current model
     * @param {Stroker} stroker Stroker to use to render a stroke
     */
    export function drawMathSymbol (context, symbol, model, stroker) {
      logger.debug(`draw ${symbol.type} text input`)
      const contextReference = context
      contextReference.save()
      try {
        contextReference.lineWidth = symbol.width
        contextReference.strokeStyle = symbol.color

        switch (symbol.type) {
          case MathSymbols.nonTerminalNode:
            drawMathSymbol(contextReference, symbol.candidates[symbol.selectedCandidate], model, stroker)
            break
          case MathSymbols.terminalNode:
            drawTerminalNode(contextReference, symbol, model, stroker)
            break
          case MathSymbols.rule:
            symbol.children.forEach(child => drawMathSymbol(contextReference, child, model, stroker))
            break
          default:
            logger.error(`${symbol.type} not implemented`)
        }
      } finally {
        contextReference.restore()
      }
    }