7

What I am trying to do: As stated in the title, I want to set the CSS of a word if it is a reserved word.


HTML
<html>
    <body>
        <code id="java">
            public static void main(String[] args)<br>
            {
                <pre>    System.out.println("Hello World!");</pre>
            }
        </code>
    </body>
</html>


jQuery
$(document).ready(function()
{
    // Get the text inside the code tags
    var code  = $("#java").text();

    // Split up each word
    var split = code.split(' ');

    // Array of reserved words
    var array = ["abstract","assert","boolean","break","byte","case",
                 "catch","char","class","const","continue","default",
                 "do","double","else","else if","enum","extends","final",
                 "finally","float","for","goto","if","import","implements",
                 "instanceof","int","interface","long","native","new","null",
                 "package","private","protected","public","return","short",
                 "static","strictfp","super","switch","synchronized","this",
                 "throw","throws","transient","void","volatile","while"];

    // Added when text contains a reserved word
    var css = {'font-weight':'bold','color':'#2400D9'}

    array = jQuery.map(array, function(n,i)
    {
        for (int j=0; j<array.length; j++)
        {
            if (split[i].contains(array[j]))
                split[i].css(css);
        }
    });
});


Problem: I have referred to the documentation for several methods (in the references section below), but I'm not too sure where the problem(s) lies. To narrow the issue down, my question(s) would be...
  1. Is .split() even a method in jQuery?
  2. Should I use a for loop to run through all the words in the array (to see if the code contains a reserved word) or is there a better approach (such as .each())?
  3. If I should use .each(), could someone please give me a simple example? I don't understand the examples in the documentation.


References
Community
  • 1
  • 1
Rob
  • 435
  • 1
  • 5
  • 25
  • jQuery is JavaScript and uses JavaScript methods all the time. Check this post, it may help a lot - http://stackoverflow.com/questions/784012/javascript-equivalent-of-phps-in-array – Jay Blanchard Mar 16 '12 at 21:19
  • [`.split()`](http://www.w3schools.com/jsref/jsref_split.asp) is a string method in JavaScript. So it's also a string method in jQuery ;). – Zeta Mar 16 '12 at 21:19
  • 1
    btw, $.each() performs a bit slower than native JS for loop (http://jsperf.com/jquery-vs-lowdash-loops/4), but it's much more convenient to use. When there are not a lot of elements I prefer .each(). With more elements performance difference starts showing and then I usually use a usual for loop. – Arman Bimatov Nov 16 '13 at 03:55
  • @ArmanBimatov Not if I'm running Firefox 24.0... ;) – Rob Nov 19 '13 at 02:47

2 Answers2

4

If I understood correctly, you can achieve what you want using $.inArray and wrapping the reserved word with a span tag. See my DEMO

Edit: Below is from jQuery $.inArray documentation.

$.inArray( value, array [, fromIndex] ) -

valueThe value to search for.

arrayAn array through which to search.

fromIndexThe index of the array at which to begin the search. The default is 0, which will search the whole array.

..read more..

CSS

.code {
    font-weight: bold;
    color: #2400D9;
}

JS

$(document).ready(function() {
    // Get the text inside the code tags
    var code = $("#java").html();

    // Split up each word
    var split = code.split(' ');

    // Array of reserved words
    var array = ["abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "default", "do", "double", "else", "else if", "enum", "extends", "final", "finally", "float", "for", "goto", "if", "import", "implements", "instanceof", "int", "interface", "long", "native", "new", "null", "package", "private", "protected", "public", "return", "short", "static", "strictfp", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "void", "volatile", "while"];

    for (var j = 0; j < split.length; j++) {
        if ($.inArray(split[j], array) > 0) {
            split[j] = '<span class="code">' + split[j] + '</span>';
        }
    }

    $("#java").html(split.join(' '));
});
Selvakumar Arumugam
  • 79,297
  • 15
  • 120
  • 134
  • Cool! Could you please explain the `$.inArray(split[j], array)`? Mainly the `$.inArray` part. – Rob Mar 16 '12 at 21:36
  • @MikeDtrick See my edits. You can read more about it clearly in jQuery documentation. – Selvakumar Arumugam Mar 16 '12 at 21:41
  • I don't think it would be wise to start up a new question, but I was wondering... if I wanted to run through another `for` loop to check and see if any digits were in the code, should I follow what you wrote for the `for` loop (with exception to the `span class=...` and `array`) or do something else? – Rob Mar 17 '12 at 17:25
  • 1
    @MikeDtrick Check my [DEMO for digit highlighting](http://jsfiddle.net/zLZ83/1/) . – Selvakumar Arumugam Mar 18 '12 at 04:40
2

I asked myself this question a few months ago, after a lot of searching I found this:

http://forum.jquery.com/topic/wrapping-specific-words-inside-span-elements#14737000001028912

which I addapted into the following jQuery plugin:

$.fn.applyKeyword = function(opt, selector) {
    var numOfKeys = opt.keys.length;

    if (typeof selector == 'undefined') {
        selector = ":visible:not(:input):not(label):not(select)";
    }

    for (var i = 0; i < numOfKeys; i++) {
        if (opt.keys[i].partials) {
            var re = new RegExp("(" + opt.keys[i].keyword + ")", 'ig');
        } else {
            var re = new RegExp("(\\b" + opt.keys[i].keyword + "\\b)", 'ig');
        }
        $(selector, this).contents().filter(function() {
            return this.nodeType != 1;
        }).each(function() {
            var output = $(this).text().replace(re, opt.keys[i].prefix + "$1" + opt.keys[i].suffix);
            if (output != $(this).text()) {
                $(this).wrap("<p></p>").parent('p').html(output).contents().unwrap();
            }
        })
    }
}

It doesn't have a way to 'undo' the keyword wrapping but it suited my needs.

If you need an example how to implement this I'd be happy to make one if you provide some text I can test it on....

sg3s
  • 9,411
  • 3
  • 36
  • 52
  • Can also capture partial matches of strings through the use of regexes; if you expect a lot of keywords / text this might be a bit heavy. It uses the element you use it with as a scope as to limiting in which elements to check. – sg3s Mar 16 '12 at 21:38
  • I've gotta admit this is quite complex (I started using jQuery about a month ago). I'm glad you mentioned the plugin because I've followed several tutorials on how to set one up, but I have no idea how to "compile" one (if that makes any sense). Do you save your plugin as a `.js` file and call it in an `id` or `class` of a tag? – Rob Mar 16 '12 at 21:41
  • A plugin is basically just a 'property' you add to the jQuery object; it just so happens to be a function so it can be called using braces ()... This is just basic JS; but for more information on how to write a plugin check [this link to an official tutorial](http://docs.jquery.com/Plugins/Authoring) – sg3s Mar 16 '12 at 21:44
  • 1
    If it helps you anything [here is the plugin](http://jsfiddle.net/RFJMy/217/) I wrote to teach myself how to do it; it isn't great at what it does but it does use the plugin style as suggested in the tutorial I linked and is semantic / documented enough to be able to read through it without a headache – sg3s Mar 16 '12 at 21:48
  • I referred to that tutorial about a week ago and couldn't follow it very well. Thank you for the link to your plugin! I'll be sure to look it over. – Rob Mar 16 '12 at 21:51
  • About compiling; you don't really need to compile anything; just include it in line in closures with the rest of your code; if by compiling you mean minifying your code you can find more on that [here](http://developer.yahoo.com/yui/compressor/), yui compressor is the most popular one I think; – sg3s Mar 16 '12 at 21:53
  • I kind of figured that, compiling wasn't the proper word to use (sorry for any confusion). Once again, thanks for the links! :) – Rob Mar 16 '12 at 21:57