ManaManaFramework/manamana

View on GitHub
src/rdsl/lexer.rl

Summary

Maintainability
Test Coverage
# lib/manamana/rdsl/lexer.rb is autogenerated by
# ragel from src/rdsl/lexer.rl. Please edit the 
# .rl file and not the .rb file.

%%{

  machine lexer;

  newline       = ('\n' | '\r\n');
  tab_or_space  = [\t ];
  string        = [A-Za-z0-9\(\)\[\]\{\}`<\\] print*;
  req_string    = [A-Za-z0-9<] print*;
  underline     = '===' '='*;
  pipe          = '|';

  group_name  = string tab_or_space* newline tab_or_space* underline;
  text        = string tab_or_space* (newline tab_or_space* string)* (newline newline)*;
  requirement = '* ' req_string tab_or_space* (newline tab_or_space* (string|underline))* (newline newline)*;
  table_row   = pipe print* pipe;

  main := |*

    group_name  => { emit_group_name(token_array, data, ts, te)  };
    requirement => { emit_requirement(token_array, data, ts, te) };
    table_row   => { emit_row(data, token_array, ts, te) };
    text        => { emit_text(token_array, data, ts, te) };

    space;

  *|;
}%%

module ManaMana

  module RDSL

    class Lexer

      def initialize
        %% write data;
        # %% this just fixes syntax highlighting in TextMate et al.
      end

      def emit_group_name(token_array, data, ts, te)
        value = data[ts...te].pack("c*").split(/=+/)[0].strip
        token_array << [:GROUP, { value: value, offset: ts }]
      end

      def emit_row(data, target_array, ts, te)
        cells = data[(ts + 1)...( te - 1)].pack("c*")

        # ignore borders
        return if /^\-+/ =~ cells

        target_array << [:ROW, { offset: ts }]
        cells.split('|').each do |cell|
          target_array << [:CELL, { value: cell.strip }]
        end
      end

      def emit_requirement(token_array, data, ts, te)
        # Split the string by code block delimiters. Even elements will be
        # non code blocks. Odd elements will be code blocks
        str_arr = data[ts...te].pack("c*").gsub(/^\* /, '').split('```')
                
        value = ''
        
        reserved_chars = /(\[|\])/
        
        
        # Iterate through blocks and non code blocks, copying code blocks verbatim
        # and stripping non-codeblocks        
        str_arr.each_with_index do |str, i|
          value << (i.odd? ? " ```#{str.rstrip.gsub(reserved_chars){|m| '\\' + m }}``` " : str.split.join(' '))
        end
                  
        value.strip!
                  
        token_array << [:REQUIREMENT, { value: value, offset: ts }]
      end

      def emit_text(token_array, data, ts, te)
          value = data[ts...te].pack("c*").strip.split.join(' ')
        token_array << [:TEXT, { value: value, offset: ts }]
      end

      def tokenize(data)
        data = data.unpack("c*") if(data.is_a?(String))
        eof = data.length
        token_array = []

        %% write init;
        %% write exec;

        token_array
      end

    end

  end
  
end