JavaScript Keyword Highlighting

L

Leif902

After much searching of google, the closest I can find is highlighting
search terms... however, this is not what I wanted to do.

Does anyone know how to parse through a specific element (lets say the
innerHTML of a div) and add tags to change the styles of several
keywords?

For instance, I might want the words "and", "or" and "xor" to be bold
and the words "c_white", "c_red" and "c_orange" to appear as maroon...
(it's for a syntax highlighting script).

It would need to be able to take multiple lists, and if it could load
those lists from an external file that would be great, but an array is
just fine... they keywords lists I am using are quite long.

Thank you
-Leif902
 
E

es_

Leif902 said:
After much searching of google, the closest I can find is highlighting
search terms... however, this is not what I wanted to do.

Does anyone know how to parse through a specific element (lets say the
innerHTML of a div) and add tags to change the styles of several
keywords?

For instance, I might want the words "and", "or" and "xor" to be bold
and the words "c_white", "c_red" and "c_orange" to appear as maroon...
(it's for a syntax highlighting script).

It would need to be able to take multiple lists, and if it could load
those lists from an external file that would be great, but an array is
just fine... they keywords lists I am using are quite long.

Thank you
-Leif902

// http://www.nsftools.com/misc/SearchAndHighlight.htm
// shorter version by TW

function doHighlight(bodyText, searchTerm)
{

highlightStartTag = "<span class='hili' style='
background-color:yellow;'>";
highlightEndTag = "</span>";

var newText = "";
var i = -1;
var lcSearchTerm = searchTerm.toLowerCase();
var lcBodyText = bodyText.toLowerCase();

while (bodyText.length > 0) {
i = lcBodyText.indexOf(lcSearchTerm, i+1);
if (i < 0) {
newText += bodyText;
bodyText = "";
} else {
if (bodyText.lastIndexOf(">", i) >= bodyText.lastIndexOf("<", i)) {
if (lcBodyText.lastIndexOf("/script>", i) >=
lcBodyText.lastIndexOf("<script", i)) {
newText += bodyText.substring(0, i) + highlightStartTag +
bodyText.substr(i, searchTerm.length) + highlightEndTag;
bodyText = bodyText.substr(i + searchTerm.length);
lcBodyText = bodyText.toLowerCase();
i = -1;
}
}
}
}

return newText;
}


function hST(searchText, treatAsPhrase)
{

if (treatAsPhrase) {
searchArray = [searchText];
} else {
searchArray = searchText.split(" ");
}

var bodyText = document.body.innerHTML;
for (var i = 0; i < searchArray.length; i++) {
bodyText = doHighlight(bodyText, searchArray);
}

document.body.innerHTML = bodyText;
return true;
}


// hST("search");
 
R

RobG

A basic script is simple, however it becomes complex very quickly:
what do you do with words that are already wrapped in emphasis or
highlighting elements?

e.g.:

<!-- Define highligh classes -->
<style type="text/css">
.animal {color: red;}
.thing {color: blue;}
</style>


<script type="text/javascript">

// Keywords
var keywordObj = {
cat : 'animal',
dog : 'animal',
mat : 'thing',
door : 'thing'
}

function highlightKeywords(el) {
var a = el.innerHTML.split(/\b/);
var w;

for (var i=0, len=a.length; i<len; i++){
w = a

// If word is a keywords, wrap in highlight span
if (w in keywordObj) {
a = '<span class="' + keywordObj[w] + '">'
+ w + '<\/span>';
}
}

// Update the element's innerHTML
el.innerHTML = a.join('');
}

</script>

<button onclick="highlightKeywords(document.getElementById('p01'),
'cat');">Higlight some words</button>

<p id="p01"onclick="alert(this.innerHTML);">The cat and the
dog went through the door to sit on their mat. The cat on
the cat:mat, the dog on the dog:mat.</p>


If you press the button multiple times, you'll see that the words are
wrapped multiple times. If you want to match cat, cats, Cat, Cats,
you have to add each one to the keywords object.

There is also an interesting post from Yann-Erwan Perio:

<URL:
http://groups.google.com.au/group/c...highlight+words&rnum=1&hl=en#fba8f6630c533340
An array is less functional (how do you allocate different higlighting
for different words?) and searching an array is likely much slower
than using a object with the in operator.


[...]
function doHighlight(bodyText, searchTerm)
{
[...]

That seems long-winded. Consider:


function highlightWord1(el, word, c){
var c = c || '#ff0000';
var re = new RegExp('\\b' + word + '\\b','i');

var s = el.innerHTML;
var newS = '';
while (re(s)) {
newS += RegExp.leftContext + '<span style="color:'+c+';">'
+ RegExp.lastMatch + '<\/span>';
s = RegExp.rightContext;
}
el.innerHTML = newS + RegExp.rightContext;
}
 
L

Leif902

Thank you both, this looks like it will work fine for my purposes
(with a little modification that is)!
-Leif902
 
L

Leif902

<!-- Define highligh classes -->
<style type="text/css">
.animal {color: red;}
.thing {color: blue;}
</style>

<script type="text/javascript">

// Keywords
var keywordObj = {
cat : 'animal',
dog : 'animal',
mat : 'thing',
door : 'thing'
}

function highlightKeywords(el) {
var a = el.innerHTML.split(/\b/);
[...]


Rob, I ended up using your method (thanks again)...

Now I have another question though, if anyone can answer it... How
might I, in the same script preferably, format a single line (for
instance a line after //) or multiple lines between two sets of
characters (/**/ c style)? I'm very new to javascript incase you can't
tell :) I'm more of a C++/GML kind of person... but I'm attempting to
learn
-Leif
 
L

Leif902

Edit: Sorry for the multiple posts, but I forgot... also, is it
possible to load a file on the server and read values from it? I don't
know how to load a file, otherwise I would build the list of keywords
dynamically from a list (c_red,c_white or maybe using a linebreak...
whatever, the parsing's not hard, just the file stream :) )

Thanks again
-Leif
 
R

RobG

Edit: Sorry for the multiple posts, but I forgot... also, is it
possible to load a file on the server and read values from it? I don't
know how to load a file, otherwise I would build the list of keywords
dynamically from a list (c_red,c_white or maybe using a linebreak...
whatever, the parsing's not hard, just the file stream :) )

Sure, search the archives, there are a number of methods. The
simplest is to load a script file that contains an object with the
required data, you could also use XMLHttpRequest.
 
L

Leif902

Sure, search the archives, there are a number of methods. The
simplest is to load a script file that contains an object with the
required data, you could also use XMLHttpRequest.

Okay, thank you, i'll look into that
- Leif
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,217
Latest member
topweb3twitterchannels

Latest Threads

Top