def gsub!(pattern, replacement=nil, &block)
mark_changes = []
mark_additions = []
text = @text.gsub(pattern) do |s|
index = $~.begin(0)
replacement = block.call(self.class.new(s)) if block_given?
if self.class===replacement
adj_marks = replacement.marks.map{ |(i,c)| [i+index,c] }
mark_additions.concat(adj_marks)
replacement = replacement.text
end
delta = (replacement.size - s.size)
mark_changes << [index, delta]
replacement
end
marks = @marks
mark_changes.each do |(index, delta)|
marks = shift_marks(index, delta, marks)
end
marks.concat(mark_additions)
@text = text
@marks = marks
self
end