| Class | MathML::LaTeX::Macro |
| In: |
lib/math_ml/latex.rb
|
| Parent: | Object |
# File lib/math_ml/latex.rb, line 185
185: def initialize
186: @commands = Hash.new
187: @environments = Hash.new
188: end
# File lib/math_ml/latex.rb, line 228
228: def check_parameter_numbers(src, opt, whole)
229: s = Scanner.new(src)
230: until s.eos?
231: case
232: when s.scan(/#{MBEC}*?\#(\d+|.)/)
233: raise parse_error("Need positive number.") unless s[1]=~/\d+/
234: raise parse_error("Parameter \# too large.", s[1]+s.rest, whole) if s[1].to_i>opt
235: else
236: return nil
237: end
238: end
239: end
# File lib/math_ml/latex.rb, line 304
304: def expand_command(com, params, opt=nil)
305: return nil unless @commands.has_key?(com)
306: c = @commands[com]
307: opt = c.option if c.option && !opt
308: params.unshift(opt) if c.option
309: raise ParseError.new("Need more parameter.") if params.size < c.num
310:
311: c.body.gsub(/(#{MBEC}*?)\#(\d+)/) do
312: $1.to_s << params[$2.to_i-1]
313: end
314: end
# File lib/math_ml/latex.rb, line 320
320: def expand_environment(env, body, params, opt=nil)
321: return nil unless @environments.has_key?(env)
322: e = @environments[env]
323: opt = e.option if e.option && !opt
324: params.unshift(opt) if e.option
325: raise ParseError.new("Need more parameter.") if params.size < e.num
326:
327: bg = e.beginning.gsub(/(#{MBEC}*?)\#(\d+)/) do
328: $1.to_s << params[$2.to_i-1]
329: end
330:
331: en = e.ending.gsub(/(#{MBEC}*?)\#(\d+)/) do
332: $1.to_s << params[$2.to_i-1]
333: end
334:
335: " #{bg} #{body} #{en} "
336: end
# File lib/math_ml/latex.rb, line 197
197: def parse(src)
198: @scanner = Scanner.new(src)
199: until @scanner.eos?
200: unless @scanner.scan_command
201: @scanner.scan_space
202: raise parse_error("Syntax error.")
203: end
204: case @scanner[1]
205: when "newcommand"
206: parse_newcommand
207: when "newenvironment"
208: parse_newenvironment
209: else
210: raise parse_error("Syntax error.", @scanner.matched)
211: end
212: end
213: rescue BlockNotClosed => e
214: raise parse_error("Block not closed.")
215: rescue OptionNotClosed => e
216: raise parse_error("Option not closed.")
217: end
# File lib/math_ml/latex.rb, line 190
190: def parse_error(message, rest="", whole=nil)
191: rest = whole[/\A.*?(#{Regexp.escape(rest)}.*\z)/, 1] if whole
192: rest << @scanner.rest
193: done = @scanner.string[0, @scanner.string.size-rest.size]
194: ParseError.new(message, rest, done)
195: end
# File lib/math_ml/latex.rb, line 241
241: def parse_newcommand
242: case
243: when @scanner.scan_block
244: s = Scanner.new(@scanner[1])
245: raise parse_error("Need newcommand.", s.rest+"}") unless s.scan_command
246: com = s[1]
247: raise parse_error("Syntax error." ,s.rest+"}") unless s.eos?
248: when @scanner.scan_command
249: s = Scanner.new(@scanner[1])
250: com = s.scan_command
251: else
252: raise parse_error("Need newcommand.")
253: end
254:
255: optnum = scan_num_of_parameter
256: opt = @scanner.scan_option ? @scanner[1] : nil
257:
258: case
259: when @scanner.scan_block
260: body = @scanner[1]
261: when @scanner.scan_command
262: body = @scanner.matched
263: else
264: body = @scanner.scan(/./)
265: end
266:
267: raise parse_error("Need parameter.") unless body
268:
269: check_parameter_numbers(body, optnum, @scanner.matched)
270:
271: optnum-=1 if opt
272: @commands[com] = Command.new(optnum, body, opt)
273: end
# File lib/math_ml/latex.rb, line 275
275: def parse_newenvironment
276: case
277: when @scanner.scan_block
278: env = @scanner[1]
279: when @scanner.scan_command
280: raise ParseError.new
281: when @scanner.scan(/./)
282: env = @scanner.matched
283: end
284: raise parse_error("Syntax error.", env[/\A.*?(\\.*\z)/, 1], @scanner.matched) if env=~/\\/
285:
286: optnum = scan_num_of_parameter
287: opt = @scanner.scan_option ? @scanner[1] : nil
288:
289: b = @scanner.scan_block ? @scanner[1] : @scanner.scan_any
290: raise parse_error("Need begin block.") unless b
291: check_parameter_numbers(b, optnum, @scanner.matched)
292: e = @scanner.scan_block ? @scanner[1] : @scanner.scan_any
293: raise parse_error("Need end block.") unless e
294: check_parameter_numbers(e, optnum, @scanner.matched)
295:
296: optnum -= 1 if opt
297: @environments[env] = Environment.new(optnum, b, e, opt)
298: end