# Creating a \<span\> over a range while preserving nesting

**URL:** <https://www.ruby-forum.com/t/creating-a-span-over-a-range-while-preserving-nesting/111771>\
**Category:** Ruby\
**Created:** [August 10, 2007, 5:28pm UTC](https://www.ruby-forum.com/t/creating-a-span-over-a-range-while-preserving-nesting/111771 "2007-08-10T17:28:41Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![burke](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/9de0a6/32.png) [@burke](https://www.ruby-forum.com/u/burke)\
**Post date:** [August 10, 2007, 5:28pm UTC](https://www.ruby-forum.com/t/creating-a-span-over-a-range-while-preserving-nesting/111771/1 "2007-08-10T17:28:41Z")

</div>

While this is a rails-related question, it has more to do with ruby in  
general.

The user selects a range by highlighting it. This is detected with  
javascript and fed to ruby. I want to take this range and highlight it.

I’m doing that by adding around the region.  
So that works ok, except that this often causes tag nesting problems.  
What I want to do is intelligently add more tag pairs to preserve  
nesting.

For example, the range:

this is a test **that uses pretty  
bizarre** markup.

Should become:

this is a test  
 **that uses pretty bizarre** markup.

I’m not looking for someone to write the code for me (although if you  
did, I wouldn’t complain); I just need someone to point me in the right  
direction. Should I start from scratch with RegExes, or is there a  
suitable library?

Thanks.

/burke

---

<div class="post-metadata">

**Author:** ![burke](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/9de0a6/32.png) [@burke](https://www.ruby-forum.com/u/burke)\
**Post date:** [August 11, 2007, 1:06am UTC](https://www.ruby-forum.com/t/creating-a-span-over-a-range-while-preserving-nesting/111771/2 "2007-08-11T01:06:46Z")

</div>

On Friday 10 August 2007 08:28:38 am Burke L. wrote:

> I’m not looking for someone to write the code for me (although if you  
> did, I wouldn’t complain); I just need someone to point me in the right  
> direction. Should I start from scratch with RegExes, or is there a  
> suitable library?
> 
> Thanks.
> 
> /burke

You might look into Hpricot by \_why or stdlib REXML.

---

<div class="post-metadata">

**Author:** ![burke](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/9de0a6/32.png) [@burke](https://www.ruby-forum.com/u/burke)\
**Post date:** [August 11, 2007, 7:35am UTC](https://www.ruby-forum.com/t/creating-a-span-over-a-range-while-preserving-nesting/111771/3 "2007-08-11T07:35:06Z")

</div>

The easy way to do this is to annotate _all text runs_ in the selected  
area; don’t try to figure  
out if other tags are partly included or not.

In this example, I’ll use \<A: to mean and :A\> to  
mean a that  
closes an “anno” span. **, , etc, stand for arbitrary  
other tags. All text  
is in lower case.**

So, your example is

this is a:B\> test \<C:that \<D:uses pretty:D\>  
bizarre:C\> markup.

your example of what you wanted then can be written as:

\<A:this is a:A\>:B\>\<A: test \<C:that \<D:uses pretty:D\>  
bizarre:C\> markup.:A\>

This is difficult because it requires some amount of parsing to figure  
out  
what markup is ‘complete’ (both start and end tags present) and what  
isn’t  
complete, then various processing to take that info into account. It’s a  
pain  
Instead, if you can accept markup like this:

\<A:this is a:A\>:B\>\<A: test :A\>\<C:\<A:that :A\>\<D:\<A:uses  
pretty:A\>:D\>\<A:bizarre:A\>:C\>\<A: markup.:A\>

Then the algorithm for marking up the selection is simple; just find all  
pieces of “real” text in selection  
(i.e. not start or end tags), and wrap those pieces in \<A: and :A\>. This  
is very easy to do with regular  
expressions.

A potential problem is that you may end up with ‘gaps’ in your  
highlighting. On the other hand,  
you’re less likely to run into weird CSS problems.

Cheers,  
Ken
