Sha256: 1eb357fd415ba6c236975b5d077c57740e1f43875d5b9994d7b3f2c5e7ca733a
Contents?: true
Size: 1.73 KB
Versions: 4
Compression:
Stored size: 1.73 KB
Contents
require 'strscan' class Sapluuna class Parser CODE_OPEN = '<%\s*' CODE_CLOSE = '\s*%>' TEMPLATE_OPEN = '[\t ]*{{{[\t ]*' TEMPLATE_CLOSE = '[\t ]*}}}[\t ]*\n?' NEW_LINE = "\n" class ParserError < Error; end class UnterminatedBlock < ParserError; end def initialize @sc = StringScanner.new '' end def parse input level = 0 cfg = [] @sc.string = input loop do if @sc.scan_until Regexp.new(TEMPLATE_OPEN) cfg << [:template, get_labels, get_template(level)] else break end end @sc.string = '' # no need to keep it in memory cfg end private def get_labels labels = @sc.scan_until Regexp.new(NEW_LINE) labels.strip.split(/\s+/) end def re_combine *args re = args.map do |arg| '(?:%s)' % arg end.join('|') Regexp.new re end def clean_scan scan endstr = -(@sc.matched.size+1) scan[0..endstr] end def get_template level cfg = [] loop do scan = @sc.scan_until re_combine(CODE_OPEN, TEMPLATE_OPEN, TEMPLATE_CLOSE) raise UnterminatedBlock, "template at #{level}, #{@sc.pos} runs forever" unless scan cfg << [:cfg, clean_scan(scan)] case @sc.matched when Regexp.new(CODE_OPEN) scan = @sc.scan_until Regexp.new(CODE_CLOSE) raise UnterminatedBlock, "code at #{level}, #{@sc.pos} runs forever" unless scan cfg << [:code, clean_scan(scan)] when Regexp.new(TEMPLATE_OPEN) cfg << [:template, get_labels, get_template(level+1)] when Regexp.new(TEMPLATE_CLOSE) return cfg end end end end end
Version data entries
4 entries across 4 versions & 1 rubygems
Version | Path |
---|---|
sapluuna-0.2.0 | lib/sapluuna/parser.rb |
sapluuna-0.1.7 | lib/sapluuna/parser.rb |
sapluuna-0.1.6 | lib/sapluuna/parser.rb |
sapluuna-0.1.5 | lib/sapluuna/parser.rb |