Class: MathML::Util::SimpleLaTeX

Inherits:
Object
  • Object
show all
Includes:
MathML::Util
Defined in:
lib/math_ml/util.rb

Constant Summary collapse

DEFAULT =
{
  delimiter: "\001",
  math_env_list: [
    /\$((?:\\.|[^\\$])#{MathML::LaTeX::MBEC}*?)\$/m,
    /\\\((#{MathML::LaTeX::MBEC}*?)\\\)/m
  ],
  dmath_env_list: [
    /\$\$(#{MathML::LaTeX::MBEC}*?)\$\$/m,
    /\\\[(#{MathML::LaTeX::MBEC}*?)\\\]/m
  ],
  escape_list: [
    /\\(.)/m
  ],
  through_list: [],
  escape_any: false,
  without_parse: false
}
@@default_latex =
nil

Constants included from MathML::Util

EQNARRAY_RE, ESCAPES, INVALID_RE, SINGLE_COMMAND_RE

Class Method Summary collapse

Instance Method Summary collapse

Methods included from MathML::Util

collect_regexp, #collect_regexp, #escapeXML, escapeXML

Constructor Details

#initialize(options = {}) ⇒ SimpleLaTeX

Returns a new instance of SimpleLaTeX.



94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/math_ml/util.rb', line 94

def initialize(options = {})
  @params = DEFAULT.merge(options)
  @params[:parser] = MathML::LaTeX::Parser.new unless @params[:parser] || @params[:without_parse]

  @params[:math_envs] = collect_regexp(@params[:math_env_list])
  @params[:dmath_envs] = collect_regexp(@params[:dmath_env_list])
  @params[:escapes] = collect_regexp(@params[:escape_list])
  @params[:throughs] = collect_regexp(@params[:through_list])
  reset_encode_proc
  reset_rescue_proc
  reset_decode_proc
  reset_unencode_proc
end

Class Method Details

.decode(src, data) ⇒ Object



332
333
334
# File 'lib/math_ml/util.rb', line 332

def self.decode(src, data)
  @@default_latex.decode(src, data)
end

.encode(src) ⇒ Object



327
328
329
330
# File 'lib/math_ml/util.rb', line 327

def self.encode(src)
  @@default_latex ||= new
  @@default_latex.encode(src)
end

Instance Method Details

#decode(encoded, data, without_parsed = false, &proc) ⇒ Object



239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
# File 'lib/math_ml/util.rb', line 239

def decode(encoded, data, without_parsed = false, &proc)
  return nil if encoded.nil?

  proc ||= @decode_proc
  encoded.gsub(/#{Regexp.escape(@params[:delimiter])}([demu])(\d+)#{Regexp.escape(@params[:delimiter])}/) do
    i = $2.to_i
    t, d, s =
      case $1
      when 'd'
        [:dmath, without_parsed ? escapeXML(data.dsrc_list[i], true) : data.dmath_list[i], data.dsrc_list[i]]
      when 'e'
        [:escape, data.escape_list[i], data.esrc_list[i]]
      when 'm'
        [:math, without_parsed ? escapeXML(data.msrc_list[i], true) : data.math_list[i], data.msrc_list[i]]
      when 'u'
        [:user, data.user_list[i], data.usrc_list[i]]
      end
    if proc
      proc.call(d, type: t, index: i, src: s) || d
    else
      d
    end
  end
end

#decode_partial(type, encoded, data, &proc) ⇒ Object



264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
# File 'lib/math_ml/util.rb', line 264

def decode_partial(type, encoded, data, &proc)
  return nil if encoded.nil?

  head =
    case type
    when :math
      'm'
    when :dmath
      'd'
    when :escape
      'e'
    when :user
      'u'
    else
      return
    end
  encoded.gsub(/#{Regexp.escape(@params[:delimiter])}#{head}(\d+)#{Regexp.escape(@params[:delimiter])}/) do
    i = $1.to_i
    t, d, s =
      case head
      when 'd'
        [:dmath, data.dmath_list[i], data.dsrc_list[i]]
      when 'e'
        [:escape, data.escape_list[i], data.esrc_list[i]]
      when 'm'
        [:math, data.math_list[i], data.msrc_list[i]]
      when 'u'
        [:user, data.user_list[i], data.usrc_list[i]]
      end
    if proc
      proc.call(d, type: t, index: i, src: s) || "#{@params[:delimiter]}#{head}#{i}#{@params[:delimiter]}"
    else
      d
    end
  end
end

#encode(src, *proc_re, &proc) ⇒ Object



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/math_ml/util.rb', line 142

def encode(src, *proc_re, &proc)
  data = if proc_re.size > 0 && proc_re[0].is_a?(MathData)
           proc_re.shift
         else
           MathData.new
         end

  proc_re = proc_re.size == 0 ? @encode_proc_re : collect_regexp(proc_re)
  proc ||= @encode_proc

  s = StringScanner.new(src)
  encoded = ''

  until s.eos?
    if s.scan(/
      (.*?)
      (((((#{@params[:throughs]})|
      #{@params[:dmath_envs]})|
      #{@params[:math_envs]})|
      #{proc_re})|
      #{@params[:escapes]})
    /mx)
      encoded << s[1]
      if s[6]
        encoded << s[6]
      elsif s[5] || s[4]
        env_src = s[5] || s[4]
        if @params[:dmath_envs] =~ env_src
          encoded << "#{@params[:delimiter]}d#{data.dsrc_list.size}#{@params[:delimiter]}"
          data.dsrc_list << env_src
        else
          encoded << "#{@params[:delimiter]}m#{data.msrc_list.size}#{@params[:delimiter]}"
          data.msrc_list << env_src
        end
      elsif s[3]
        size = s[3].size
        s.pos = left = s.pos - size
        if r = proc.call(s)
          right = s.pos
          encoded << "#{@params[:delimiter]}u#{data.user_list.size}#{@params[:delimiter]}"
          data.user_list << r
          data.usrc_list << s.string[left...right]
        else
          encoded << s.peek(size)
          s.pos = s.pos + size
        end
      elsif s[2]
        encoded << "#{@params[:delimiter]}e#{data.escape_list.size}#{@params[:delimiter]}"
        @params[:escapes] =~ s[2]
        data.esrc_list << s[2]
        data.escape_list << escapeXML($+, true)
      end
    else
      encoded << s.rest
      s.terminate
    end
  end

  parse(data, @params[:parser]) unless @params[:without_parse]

  [encoded, data]
end

#error_to_html(e) ⇒ Object



205
206
207
208
# File 'lib/math_ml/util.rb', line 205

def error_to_html(e)
  "<br />\n#{escapeXML(e.message)}<br />\n<code>#{escapeXML(e.done).gsub(/\n/, "<br />\n")}" \
    "<strong>#{escapeXML(e.rest).gsub(/\n/, "<br />\n")}</strong></code><br />"
end

#latex_parserObject



210
211
212
213
# File 'lib/math_ml/util.rb', line 210

def latex_parser
  @params[:parser] = MathML::LaTeX::Parser.new unless @params[:parser]
  @params[:parser]
end

#parse(data, parser = nil) ⇒ Object



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/math_ml/util.rb', line 215

def parse(data, parser = nil)
  parser ||= latex_parser
  (data.math_list.size...data.msrc_list.size).each do |i|
    @params[:math_envs] =~ data.msrc_list[i]
    data.math_list[i] = parser.parse($+)
  rescue MathML::LaTeX::ParseError => e
    data.math_list[i] = if @rescue_proc
                          @rescue_proc.call(e)
                        else
                          error_to_html(e)
                        end
  end
  (data.dmath_list.size...data.dsrc_list.size).each do |i|
    @params[:dmath_envs] =~ data.dsrc_list[i]
    data.dmath_list[i] = parser.parse($+, true)
  rescue MathML::LaTeX::ParseError => e
    data.dmath_list[i] = if @rescue_proc
                           @rescue_proc.call(e)
                         else
                           error_to_html(e)
                         end
  end
end

#parse_eqnarray(src, parser = nil) ⇒ Object



336
337
338
339
340
341
342
343
344
345
346
347
348
349
# File 'lib/math_ml/util.rb', line 336

def parse_eqnarray(src, parser = nil)
  src = "\\begin{array}{ccc}#{src}\\end{array}"
  parser ||= latex_parser
  begin
    parser.parse(src, true)
  rescue MathML::LaTeX::ParseError => e
    e = MathML::LaTeX::ParseError.new(
      e.message,
      e.rest.sub(/\\end\{array\}\z/, '\end{eqnarray}'),
      e.done.sub(/\A\\begin\{array\}\{ccc\}/, '\begin{eqnarray}')
    )
    @rescue_proc ? @rescue_proc.call(e) : error_to_html(e)
  end
end

#parse_single_command(src, parser = nil) ⇒ Object



351
352
353
354
355
356
357
358
359
# File 'lib/math_ml/util.rb', line 351

def parse_single_command(src, parser = nil)
  s = src[SINGLE_COMMAND_RE, 1]
  parser ||= latex_parser
  begin
    parser.parse(s)
  rescue MathML::LaTeX::ParseError => e
    src[SINGLE_COMMAND_RE, 2]
  end
end

#reset_decode_procObject



126
127
128
# File 'lib/math_ml/util.rb', line 126

def reset_decode_proc
  @decode_proc = nil
end

#reset_encode_procObject



108
109
110
111
# File 'lib/math_ml/util.rb', line 108

def reset_encode_proc
  @encode_proc_re = INVALID_RE
  @encode_proc = nil
end

#reset_rescue_procObject



118
119
120
# File 'lib/math_ml/util.rb', line 118

def reset_rescue_proc
  @rescue_proc = nil
end

#reset_unencode_procObject



138
139
140
# File 'lib/math_ml/util.rb', line 138

def reset_unencode_proc
  @unencode_proc = nil
end

#set_decode_proc(&proc) ⇒ Object



130
131
132
# File 'lib/math_ml/util.rb', line 130

def set_decode_proc(&proc)
  @decode_proc = proc
end

#set_encode_proc(*re, &proc) ⇒ Object



113
114
115
116
# File 'lib/math_ml/util.rb', line 113

def set_encode_proc(*re, &proc)
  @encode_proc_re = collect_regexp(re)
  @encode_proc = proc
end

#set_rescue_proc(&proc) ⇒ Object



122
123
124
# File 'lib/math_ml/util.rb', line 122

def set_rescue_proc(&proc)
  @rescue_proc = proc
end

#set_unencode_proc(&proc) ⇒ Object



134
135
136
# File 'lib/math_ml/util.rb', line 134

def set_unencode_proc(&proc)
  @unencode_proc = proc
end

#unencode(encoded, data, without_escape = false, &proc) ⇒ Object



301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
# File 'lib/math_ml/util.rb', line 301

def unencode(encoded, data, without_escape = false, &proc)
  return nil if encoded.nil?

  proc ||= @unencode_proc
  encoded.gsub(/#{Regexp.escape(@params[:delimiter])}([demu])(\d+)#{Regexp.escape(@params[:delimiter])}/) do
    i = $2.to_i
    t, s =
      case $1
      when 'd'
        [:dmath, data.dsrc_list[i]]
      when 'e'
        [:escape, data.esrc_list[i]]
      when 'm'
        [:math, data.msrc_list[i]]
      when 'u'
        [:user, data.usrc_list[i]]
      end
    s = escapeXML(s, true) unless without_escape
    if proc
      proc.call(s, type: t, index: i) || s
    else
      s
    end
  end
end