class Syntax::Ruby
def scan_delimited_region( delim_group, inner_group, starter, exprs,
:flush (meaning the delimiter must be flushed left), or
* +heredoc+ is either +false+, meaning the region is not a heredoc, or
the next character will be treated as the delimiter.
* +delim+ is the text to use as the delimiter of the region. If +nil+,
interpolated string or not
* +exprs+ is a boolean flag indicating whether the region is an
* +starter+ is the text to use as the starting delimiter
region
* +inner_group+ is the group to use to classify the contents of the
region
* +delim_group+ is the group to use to classify the delimiters of the
and here-documents.
delimited with quotes) as well as the more complex cases of %-strings
Scan a delimited region of text. This handles the simple cases (strings
def scan_delimited_region( delim_group, inner_group, starter, exprs, delim=nil, heredoc=false ) # begin if !delim start_group delim_group, starter delim = scan( /./ ) append delim delim = case delim when '{' then '}' when '(' then ')' when '[' then ']' when '<' then '>' else delim end end start_region inner_group items = "\\\\|".dup if heredoc items << "(^" items << '\s*' if heredoc == :float items << "#{Regexp.escape(delim)}\s*?)#{EOL}" else items << "#{Regexp.escape(delim)}" end items << "|#(\\$|@@?|\\{)" if exprs items = Regexp.new( items ) loop do p = pos match = scan_until( items ) if match.nil? start_group inner_group, scan_until( /\Z/ ) break else text = pre_match[p..-1] start_group inner_group, text if text.length > 0 case matched.strip when "\\" unless exprs case peek(1) when "'" scan(/./) start_group :escape, "\\'" when "\\" scan(/./) start_group :escape, "\\\\" else start_group inner_group, "\\" end else start_group :escape, "\\" c = getch append c case c when 'x' append scan( /[a-fA-F0-9]{1,2}/ ) when /[0-7]/ append scan( /[0-7]{0,2}/ ) end end when delim end_region inner_group start_group delim_group, matched break when /^#/ do_highlight = (option(:expressions) == :highlight) start_region :expr if do_highlight start_group :expr, matched case matched[1] when ?{ depth = 1 content = "".dup while depth > 0 p = pos c = scan_until( /[\{}]/ ) if c.nil? content << scan_until( /\Z/ ) break else depth += ( matched == "{" ? 1 : -1 ) content << pre_match[p..-1] content << matched if depth > 0 end end if do_highlight subtokenize "ruby", content start_group :expr, "}" else append content + "}" end when ?$, ?@ append scan( /\w+/ ) end end_region :expr if do_highlight else raise "unexpected match on #{matched}" end end end end