class Glaemscribe::API::Glaeml::Parser

Public Instance Methods

add_text_node(lnum, text) click to toggle source
# File lib/api/glaeml.rb, line 114
def add_text_node(lnum, text)
  n             = Node.new(lnum, Node::Type::Text, "root")
  n.args        << text
  n.parent_node = @current_parent_node     
  @current_parent_node.children << n   
end
parse(raw_data) click to toggle source
# File lib/api/glaeml.rb, line 121
def parse(raw_data)
  raw_data.gsub!(/\\\*\*(.*?)\*\*\\/m) { |found|
    "\n" * found.count("\n")
  }

  lnum = 0   

  @document             = Document.new
  @document.root_node   = Node.new(lnum, Node::Type::ElementBlock, nil)

  @current_parent_node  = @document.root_node
   
  raw_data.lines.each{ |l|
    lnum  += 1
   
    l     = l.strip
    add_text_node(lnum, l) and next if l.empty?
          
    if(l[0..0] == "\\")
      if(l.length == 1)
        @document.errors << Error.new(lnum, "Incomplete node.")
      else
        if(l[1..1] == "\\") # First backslash is escaped
        
          add_text_node(lnum, l[1..-1])              
        
        elsif l =~ /^(\\beg\s+)/
        
          rest    = $'.strip
          args    = []
          name    = "???"
          if(! (rest =~ /^([a-z_]+)/) )
            @document.errors << Error.new(lnum, "Bad element name #{rest}.")
          else
            name = $1
            begin
              args = Shellwords.new.parse $'                
            rescue Shellwords::Error => e
              @document.errors << Error.new(lnum, "Failed to parse args : #{e}")
              args = []
            end
          end
        
          n             = Node.new(lnum, Node::Type::ElementBlock, name)
          n.args        += args
          n.parent_node = @current_parent_node
      
          @current_parent_node.children << n
          @current_parent_node           = n                
                      
        elsif l =~ /^(\\end(\s|$))/              
        
          if !@current_parent_node.parent_node
            @document.errors << Error.new(lnum, "Element 'end' unexpected.")
          elsif $'.strip != ""
            @document.errors << Error.new(lnum, "Element 'end' should not have arguments.")
          else
            @current_parent_node = @current_parent_node.parent_node
          end
      
        else
        
          # Read the name of the node
          l             = l[1..-1]         
          l             =~ /^([a-z_]+)/
          name          = $1
          
          begin
            args = Shellwords.new.parse $'                
          rescue Shellwords::Error => e
            @document.errors << Error.new(lnum, "Failed to parse args : #{e}")
            args = []
          end
        
          n             = Node.new(lnum, Node::Type::ElementInline, name)
          n.args        += args
          n.parent_node = @current_parent_node
        
          @current_parent_node.children << n     
                   
        end
      end
    else
      add_text_node(lnum, l)
    end
  }

  if @current_parent_node != @document.root_node
    @document.errors << Error.new(lnum, "Missing 'end' element.")
  end

  return @document

end