class MathML::LaTeX::Macro

Public Class Methods

new() click to toggle source
# File lib/math_ml/latex.rb, line 185
def initialize
        @commands = Hash.new
        @environments = Hash.new
end

Public Instance Methods

check_parameter_numbers(src, opt, whole) click to toggle source
# File lib/math_ml/latex.rb, line 228
def check_parameter_numbers(src, opt, whole)
        s = Scanner.new(src)
        until s.eos?
                case
                when s.scan(/#{MBEC}*?\#(\d+|.)/)
                        raise parse_error("Need positive number.") unless s[1]=~/\d+/
                        raise parse_error("Parameter \# too large.", s[1]+s.rest, whole) if s[1].to_i>opt
                else
                        return nil
                end
        end
end
commands(com) click to toggle source
# File lib/math_ml/latex.rb, line 300
def commands(com)
        @commands[com]
end
environments(env) click to toggle source
# File lib/math_ml/latex.rb, line 316
def environments(env)
        @environments[env]
end
expand_command(com, params, opt=nil) click to toggle source
# File lib/math_ml/latex.rb, line 304
def expand_command(com, params, opt=nil)
        return nil unless @commands.has_key?(com)
        c = @commands[com]
        opt = c.option if c.option && !opt
        params.unshift(opt) if c.option
        raise ParseError.new("Need more parameter.") if params.size < c.num

        c.body.gsub(/(#{MBEC}*?)\#(\d+)/) do
                $1.to_s << params[$2.to_i-1]
        end
end
expand_environment(env, body, params, opt=nil) click to toggle source
# File lib/math_ml/latex.rb, line 320
def expand_environment(env, body, params, opt=nil)
        return nil unless @environments.has_key?(env)
        e = @environments[env]
        opt = e.option if e.option && !opt
        params.unshift(opt) if e.option
        raise ParseError.new("Need more parameter.") if params.size < e.num

        bg = e.beginning.gsub(/(#{MBEC}*?)\#(\d+)/) do
                $1.to_s << params[$2.to_i-1]
        end

        en = e.ending.gsub(/(#{MBEC}*?)\#(\d+)/) do
                $1.to_s << params[$2.to_i-1]
        end

        " #{bg} #{body} #{en} "
end
parse(src) click to toggle source
# File lib/math_ml/latex.rb, line 197
def parse(src)
        @scanner = Scanner.new(src)
        until @scanner.eos?
                unless @scanner.scan_command
                        @scanner.scan_space
                        raise parse_error("Syntax error.")
                end
                case @scanner[1]
                when "newcommand"
                        parse_newcommand
                when "newenvironment"
                        parse_newenvironment
                else
                        raise parse_error("Syntax error.", @scanner.matched)
                end
        end
rescue BlockNotClosed => e
        raise parse_error("Block not closed.")
rescue OptionNotClosed => e
        raise parse_error("Option not closed.")
end
parse_error(message, rest="", whole=nil) click to toggle source
# File lib/math_ml/latex.rb, line 190
def parse_error(message, rest="", whole=nil)
        rest = whole[/\A.*?(#{Regexp.escape(rest)}.*\z)/, 1] if whole
        rest << @scanner.rest
        done = @scanner.string[0, @scanner.string.size-rest.size]
        ParseError.new(message, rest, done)
end
parse_newcommand() click to toggle source
# File lib/math_ml/latex.rb, line 241
def parse_newcommand
        case
        when @scanner.scan_block
                s = Scanner.new(@scanner[1])
                raise parse_error("Need newcommand.", s.rest+"}") unless s.scan_command
                com = s[1]
                raise parse_error("Syntax error." ,s.rest+"}") unless s.eos?
        when @scanner.scan_command
                s = Scanner.new(@scanner[1])
                com = s.scan_command
        else
                raise parse_error("Need newcommand.")
        end

        optnum = scan_num_of_parameter
        opt = @scanner.scan_option ? @scanner[1] : nil

        case
        when @scanner.scan_block
                body = @scanner[1]
        when @scanner.scan_command
                body = @scanner.matched
        else
                body = @scanner.scan(/./)
        end

        raise parse_error("Need parameter.") unless body

        check_parameter_numbers(body, optnum, @scanner.matched)

        optnum-=1 if opt
        @commands[com] = Command.new(optnum, body, opt)
end
parse_newenvironment() click to toggle source
# File lib/math_ml/latex.rb, line 275
def parse_newenvironment
        case
        when @scanner.scan_block
                env = @scanner[1]
        when @scanner.scan_command
                raise ParseError.new
        when @scanner.scan(/./)
                env = @scanner.matched
        end
        raise parse_error("Syntax error.", env[/\A.*?(\\.*\z)/, 1], @scanner.matched) if env=~/\\/

        optnum = scan_num_of_parameter
        opt = @scanner.scan_option ? @scanner[1] : nil

        b = @scanner.scan_block ? @scanner[1] : @scanner.scan_any
        raise parse_error("Need begin block.") unless b
        check_parameter_numbers(b, optnum, @scanner.matched)
        e = @scanner.scan_block ? @scanner[1] : @scanner.scan_any
        raise parse_error("Need end block.") unless e
        check_parameter_numbers(e, optnum, @scanner.matched)

        optnum -= 1 if opt
        @environments[env] = Environment.new(optnum, b, e, opt)
end
scan_num_of_parameter() click to toggle source
# File lib/math_ml/latex.rb, line 219
def scan_num_of_parameter
        if @scanner.scan_option
                raise parse_error("Need positive number.", @scanner[1]+"]") unless @scanner[1]=~/\A#{RE::SPACE}*\d+#{RE::SPACE}*\z/
                @scanner[1].to_i
        else
                0
        end
end