class Spirit::Render::Processors::MathProcessor

Pre-processes math markup in latex. Adapted from www.math.union.edu/~dpvc/transfer/mathjax/mathjax-editing.js

Constants

SPLIT

Pattern for delimiters and special symbols; used to search for math in the document.

Attributes

blocks[R]
math[R]

Public Class Methods

new(renderer, document) click to toggle source
# File lib/spirit/render/processors/math_processor.rb, line 23
def initialize(renderer, document)
  reset_counters
  @math   = []
  @blocks = document.gsub(/\r\n?/, "\n").split SPLIT
end

Public Instance Methods

filter(document) click to toggle source

Replace math in document with +@@index@@+. @return [String] document

# File lib/spirit/render/processors/math_processor.rb, line 31
def filter(document)
  blocks.each_with_index do |block, i|
    case
    when '@' == block[0]
      process_pseudo_marker block, i
    when @start
      process_potential_close block, i
    else
      process_potential_start block, i
    end
  end
  process_math if @last
  blocks.join
end
replace(document) click to toggle source
# File lib/spirit/render/processors/math_processor.rb, line 46
def replace(document)
  document.gsub(/@@(\d+)@@/) { math[$1.to_i] }
end

Private Instance Methods

process_math(last = @last) click to toggle source

Collects the math from blocks i through j, replaces &, <, and > by named entities, and resets that math positions.

# File lib/spirit/render/processors/math_processor.rb, line 82
def process_math(last = @last)
  block = blocks[@start..last].join
    .gsub(/&/, '&amp;')
    .gsub(/</, '&lt;')
    .gsub(/>/, '&gt;')
  last.downto(@start+1) { |k| blocks[k] = '' }
  blocks[@start] = "@@#{math.length}@@"
  math << block
  reset_counters
end
process_potential_close(block, i) click to toggle source
# File lib/spirit/render/processors/math_processor.rb, line 68
def process_potential_close(block, i)
  case block
  when @close     # process if braces match
    @braces.zero? ? process_math(i) : @last = i
  when /\n.*\n/   # don't go over double line breaks
    process_math if @last
    reset_counters
  when '{' then @braces += 1 # balance braces
  when '}' then @braces -= 1 if @braces > 0
  end
end
process_potential_start(block, i) click to toggle source
# File lib/spirit/render/processors/math_processor.rb, line 59
def process_potential_start(block, i)
  case block
  when '$', '$$'
    @start, @close, @braces = i, block, 0
  when /\A\\begin\{([a-z]*\*?)\}/
    @start, @close, @braces = i, "\\end{#{$1}}", 0
  end
end
process_pseudo_marker(block, i) click to toggle source
# File lib/spirit/render/processors/math_processor.rb, line 54
def process_pseudo_marker(block, i)
  blocks[i] = "@@#{math.length}@@"
  math << block
end
reset_counters() click to toggle source
# File lib/spirit/render/processors/math_processor.rb, line 93
def reset_counters
  @start = @close = @last = nil
  @braces = 0
end