class MathML::LaTeX::Parser
Constants
- BUILTIN_MACRO
Attributes
macro[R]
symbol_table[R]
unsecure_entity[RW]
Public Class Methods
new(opt={})
click to toggle source
Calls superclass method
MathML::LaTeX::BuiltinCommands::new
# File lib/math_ml/latex.rb 365 def initialize(opt={}) 366 @unsecure_entity = false 367 @entities = Hash.new 368 @commands = Hash.new 369 @symbols = Hash.new 370 @delimiters = Array.new 371 @group_begins = Hash.new 372 @group_ends = Hash.new 373 @macro = Macro.new 374 @macro.parse(BUILTIN_MACRO) 375 @expanded_command = Array.new 376 @expanded_environment = Array.new 377 @symbol_table = opt[:symbol] || MathML::Symbol::Default 378 @symbol_table = MathML::Symbol::MAP[@symbol_table] if @symbol_table.is_a?(::Symbol) 379 380 super() 381 end
Public Instance Methods
add_commands(*a)
click to toggle source
# File lib/math_ml/latex.rb 414 def add_commands(*a) 415 if a.size==1 && Hash===a[0] 416 @commands.merge!(a[0]) 417 else 418 a.each{|i| @commands[i] = false} 419 end 420 end
add_delimiter(list)
click to toggle source
# File lib/math_ml/latex.rb 430 def add_delimiter(list) 431 @delimiters.concat(list) 432 end
add_entity(list)
click to toggle source
# File lib/math_ml/latex.rb 383 def add_entity(list) 384 list.each do |i| 385 @entities[i] = true 386 end 387 end
add_group(begin_name, end_name, method=nil)
click to toggle source
# File lib/math_ml/latex.rb 434 def add_group(begin_name, end_name, method=nil) 435 @group_begins[begin_name] = method 436 @group_ends[end_name] = begin_name 437 end
add_multi_command(m, *a)
click to toggle source
# File lib/math_ml/latex.rb 422 def add_multi_command(m, *a) 423 a.each{|i| @commands[i] = m} 424 end
add_plugin(plugin)
click to toggle source
# File lib/math_ml/latex.rb 410 def add_plugin(plugin) 411 self.extend(plugin) 412 end
add_sym_cmd(hash)
click to toggle source
# File lib/math_ml/latex.rb 426 def add_sym_cmd(hash) 427 @symbols.merge!(hash) 428 end
parse(src, displaystyle=false)
click to toggle source
# File lib/math_ml/latex.rb 389 def parse(src, displaystyle=false) 390 @ds = displaystyle 391 begin 392 parse_into(src, Math.new(@ds), Font::NORMAL) 393 rescue ParseError => e 394 e.done = src[0...(src.size - e.rest.size)] 395 raise 396 end 397 end
push_container(container, scanner=@scanner, font=@font) { |container| ... }
click to toggle source
# File lib/math_ml/latex.rb 399 def push_container(container, scanner=@scanner, font=@font) 400 data = [@container, @scanner, @font] 401 @container, @scanner, @font = [container, scanner, font] 402 begin 403 yield container 404 container 405 ensure 406 @container, @scanner, @font = data 407 end 408 end
Private Instance Methods
entitize(str)
click to toggle source
# File lib/math_ml/latex.rb 590 def entitize(str) 591 MathML.pcstring(str.sub(/^(.*)$/){"&#{$1};"}, true) 592 end
parse_any(message = "Syntax error.")
click to toggle source
# File lib/math_ml/latex.rb 466 def parse_any(message = "Syntax error.") 467 raise ParseError.new(message) unless @scanner.scan_any 468 s = @scanner 469 @scanner = Scanner.new(@scanner.matched) 470 begin 471 parse_to_element 472 ensure 473 @scanner = s 474 end 475 end
parse_block()
click to toggle source
# File lib/math_ml/latex.rb 536 def parse_block 537 os = @scanner 538 @scanner = Scanner.new(@scanner[1]) 539 begin 540 push_container(Row.new) do |r| 541 r << parse_to_element(true) until @scanner.eos? 542 end 543 rescue ParseError => e 544 e.rest << '}' 545 raise 546 ensure 547 @scanner = os 548 end 549 end
parse_char()
click to toggle source
# File lib/math_ml/latex.rb 511 def parse_char 512 c = @scanner.matched 513 i = Identifier.new 514 case @font 515 when Font::ROMAN 516 i.extend(Variant).variant = Variant::NORMAL 517 when Font::BOLD 518 i.extend(Variant).variant = Variant::BOLD 519 when Font::BOLD_ITALIC 520 i.extend(Variant).variant = Variant::BOLD_ITALIC 521 when Font::BLACKBOLD 522 c = symbol_table.convert("#{c}opf") 523 when Font::SCRIPT 524 c = symbol_table.convert("#{c}scr") 525 when Font::FRAKTUR 526 c = symbol_table.convert("#{c}fr") 527 end 528 i << c 529 end
parse_command()
click to toggle source
# File lib/math_ml/latex.rb 639 def parse_command 640 com = @scanner[1] 641 matched = @scanner.matched 642 pos = @scanner.pos-matched.size 643 macro = @macro.commands(com) 644 if macro 645 begin 646 flg = @expanded_command.include?(com) 647 @expanded_command.push(com) 648 raise CircularReferenceCommand if flg 649 option = (macro.option && @scanner.scan_option) ? @scanner[1] : nil 650 params = Array.new 651 (1..macro.num).each do 652 params << (@scanner.scan_block ? @scanner[1] : @scanner.scan_any) 653 raise ParseError.new("Need more parameter.") unless params.last 654 end 655 r = parse_into(@macro.expand_command(com, params, option), Array.new) 656 return r 657 rescue CircularReferenceCommand 658 if @expanded_command.size>1 659 raise 660 else 661 @scanner.pos = pos 662 raise ParseError.new("Circular reference.") 663 end 664 rescue ParseError => e 665 if @expanded_command.size>1 666 raise 667 else 668 @scanner.pos = pos 669 raise ParseError.new(%[Error in macro(#{e.message} "#{e.rest.strip}").]) 670 end 671 ensure 672 @expanded_command.pop 673 end 674 elsif @commands.key?(com) 675 m = @commands[com] 676 m = com unless m 677 return __send__("cmd_#{m.to_s}") 678 end 679 parse_symbol_command(com) 680 end
parse_group()
click to toggle source
# File lib/math_ml/latex.rb 692 def parse_group 693 font = @font 694 begin 695 g = @group_begins[@scanner[1]] 696 g = @scanner[1] unless g 697 __send__("grp_#{g.to_s}") 698 ensure 699 @font = font 700 end 701 end
parse_into(src, parent, font=nil)
click to toggle source
# File lib/math_ml/latex.rb 440 def parse_into(src, parent, font=nil) 441 orig = [@scanner, @container, @font, @ds] 442 @scanner = Scanner.new(src) 443 @container = parent 444 @font = font if font 445 begin 446 until @scanner.eos? 447 @container << parse_to_element(true) 448 end 449 @container 450 rescue BlockNotClosed => e 451 raise ParseError.new("Block not closed.", @scanner.rest) 452 rescue NotEnvironment => e 453 raise ParseError.new("Not environment.", @scanner.rest) 454 rescue EnvironmentNotEnd => e 455 raise ParseError.new("Environment not end.", @scanner.rest) 456 rescue OptionNotClosed => e 457 raise ParseError.new("Option not closed.", @scanner.rest) 458 rescue ParseError => e 459 e.rest = e.rest + @scanner.rest.to_s 460 raise 461 ensure 462 @scanner, @container, @font, @ds = orig 463 end 464 end
parse_mathfont(font)
click to toggle source
# File lib/math_ml/latex.rb 682 def parse_mathfont(font) 683 f = @font 684 @font = font 685 begin 686 push_container(Row.new){|r| r << parse_any} 687 ensure 688 @font = f 689 end 690 end
parse_num()
click to toggle source
# File lib/math_ml/latex.rb 505 def parse_num 506 n = Number.new 507 n.extend(Variant).variant = Variant::BOLD if @font==Font::BOLD 508 n << @scanner.matched 509 end
parse_operator()
click to toggle source
# File lib/math_ml/latex.rb 531 def parse_operator 532 o = @scanner.matched 533 Operator.new.tap{|op| op[:stretchy]="false"} << o 534 end
parse_sub()
click to toggle source
# File lib/math_ml/latex.rb 551 def parse_sub 552 e = @container.pop 553 e = None.new unless e 554 e = SubSup.new(@ds && e.display_style, e) unless e.is_a?(SubSup) 555 raise ParseError.new("Double subscript.", "_") if e.sub 556 e.sub = parse_any("Subscript not exist.") 557 e 558 end
parse_sup()
click to toggle source
# File lib/math_ml/latex.rb 560 def parse_sup 561 e = @container.pop 562 e = None.new unless e 563 e = SubSup.new(@ds && e.display_style, e) unless e.is_a?(SubSup) 564 raise ParseError.new("Double superscript.", @scanner[0]) if e.sup 565 if /'+/=~@scanner[0] 566 prime = Operator.new 567 @scanner[0].size.times do 568 prime << symbol_table.convert("prime") 569 end 570 unless @scanner.scan(/\^/) 571 e.sup = prime 572 return e 573 end 574 end 575 sup = parse_any("Superscript not exist.") 576 577 if prime 578 unless sup.is_a?(Row) 579 r = Row.new 580 r << sup 581 sup = r 582 end 583 sup.contents.insert(0, prime) 584 end 585 586 e.sup = sup 587 e 588 end
parse_symbol_command(com, plain=false)
click to toggle source
# File lib/math_ml/latex.rb 594 def parse_symbol_command(com, plain=false) 595 unless @symbols.include?(com) 596 @scanner.pos = @scanner.pos-(com.size+1) 597 raise ParseError.new("Undefined command.") 598 end 599 data = @symbols[com] 600 return nil unless data 601 602 data, s = data 603 su = data[0] 604 el = data[1] 605 el = :o unless el 606 s = com.dup.untaint.to_sym unless s 607 s = com if s.is_a?(String) && s.length==0 608 609 case el 610 when :I 611 el = Identifier.new 612 when :i 613 el = Identifier.new 614 el.extend(Variant).variant = Variant::NORMAL unless s.is_a?(String)&&s.length>1 615 when :o 616 el = Operator.new 617 el[:stretchy] = "false" 618 when :n 619 el = Number.new 620 else 621 raise ParseError.new("Inner data broken.") 622 end 623 624 case s 625 when Fixnum 626 s = MathML.pcstring("&\#x#{s.to_s(16)};", true) 627 when ::Symbol 628 s = symbol_table.convert(s) 629 else 630 MathML.pcstring(s, true) 631 end 632 633 return s if plain 634 el << s 635 el.as_display_style if su==:u 636 el 637 end
parse_to_element(whole_group = false)
click to toggle source
# File lib/math_ml/latex.rb 477 def parse_to_element(whole_group = false) 478 if whole_group && @group_begins.has_key?(@scanner.peek_command) 479 @scanner.scan_command 480 parse_group 481 else 482 case 483 when @scanner.scan(RE::NUMERICS) 484 parse_num 485 when @scanner.scan(RE::ALPHABETS) 486 parse_char 487 when @scanner.scan(RE::OPERATORS) 488 parse_operator 489 when @scanner.scan_block 490 parse_block 491 when @scanner.scan(/_/) 492 parse_sub 493 when @scanner.scan(/'+|\^/) 494 parse_sup 495 when @scanner.scan(/~/) 496 Space.new("1em") 497 when @scanner.scan_command 498 parse_command 499 else 500 raise ParseError.new('Syntax error.') 501 end 502 end 503 end