Sha256: 8130c090db5d2a563f553e9850a9942e06dbd4315e62324c9445e0e14b9e4d29

Contents?: true

Size: 1.33 KB

Versions: 1

Compression:

Stored size: 1.33 KB

Contents

module DR
	class SimpleKeywordsParser
		attr_accessor :opts, :keywords

		def initialize(hash, **opts)
			@opts=opts
			@keywords=hash
		end

		def keyword(name, &b)
			@keywords[name]=b
		end

		def parse(msg, **opts)
			opts=@opts.merge(opts)
			sep=opts[:sep] || ','
			# Warning: the delims must take only one char
			delims= opts[:delims] || '()'
			bdelim= delims[0]
			edelim= delims[1] || bdelim
			keywords=@keywords.keys
			keywords_r="(?:"+keywords.map {|k| "(?:"+k+")"}.join("|")+")"
			reg = %r{(?<kw>#{keywords_r})(?<re>#{'\\'+bdelim}(?:(?>[^#{'\\'+bdelim}#{'\\'+edelim}]+)|\g<re>)*#{'\\'+edelim})}
			if (m=reg.match(msg))
				arg=m[:re][1...m[:re].length-1]
				arg=parse(arg, **opts)
				args=arg.split(sep)
				args=args.map {|a| a.strip} unless opts[:space]
				key=keywords.find {|k| /#{k}/ =~ m[:kw]}
				r=@keywords[key].call(*args).to_s
				msg=m.pre_match+r+parse(m.post_match,**opts)
				msg=keywords(msg,@keywords,**opts) if opts[:recursive]
			end
			return msg
		end
		# re = %r{
		#   (?<re>
		#     \(
		#       (?:
		#         (?> [^()]+ )
		#         |
		#         \g<re>
		#       )*
		#     \)
		#   )
		# }x
		#(?<re> name regexp/match
		#\g<re> reuse regexp
		#\k<re> reuse match
		#(?: grouping without capturing
		#(?> atomic grouping
		#x whitespace does not count
		# -> match balanced groups of parentheses

	end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
drain-0.3.0 lib/dr/parse/simple_keywords.rb