JavaScript Snippet – Simple CSV Parser

As I mentioned in yesterday’s post, I was recently working on a quick way to parse CSVs into an array of arrays and alternatively into an array of dictionaries keyed on the values in the first row. I ended up landing on the following definition:

As you can see the function is annotated for anyone that may be interested in using. Let’s see example of how it could be used. Here is an example string that can be parsed:

ID,First Name,Last Name,Address,Last Purchase Date,Purchase Amount,Comment,Return Customer
1,Don,Knots,"123 Main St.,
Duggietown, ET 12342",10/23/2013,23.43,"""Doesn't like cheese"" according to his mom.",Y
2,Cher,Vega,"92 Victor Ln.
Rutrow, DA 39252",01/12/2013,588.1,,N
3,Tina,Ray,"1111 Yomdip Circle
Bribloop, EV 92341",02/03/2013,234.2,,Y
4,Charlie,Bucket,"745 Caca Pl.
Hastiville, JS 92293",05/06/2013,345.4,,N

Below is an example of processing the above CSV first as an array of arrays, then as an array of dictionaries (objects), and lastly as an array of dictionaries with typed values:

As you can see from the jPaq Proof above, this parser works well with the majority of the CSVs that you would need to process. Still, in the case that you need a fully-fledged CSV parser, Papa Parse seems to be a pretty good solution. Have fun! 8-)

Regular Expressions – Extra Ending Match

A few days ago I was working on a very primitive version of a CSV reader for a quick JS project and while testing my regex out, I noticed that I was getting an extra match at the end. Here is the JavaScript function that I had:

function parseCSV(str) {
  var row = [], rows = [row];
  str.replace(/([^",\r\n]*|"((?:[^"]+|"")*)")(,|\r|\r?\n|$)/g, function(match, cell, quoted, delimiter) {
    row.push(quoted ? quoted.replace(/""/g, '"') : cell);
    if (delimiter && delimiter != ',') {
      rows.push(row = []);
    }
  });
  return rows;
}

Interestingly, if you pass "Name,DOB" into parseCSV() an extra cell will be added:

> parseCSV('Name,DOB')
[["Name", "DOB", ""]]

Without diving into the function too much to see why it should work with a good regex, you will notice that finding all of the matches for my CSV parsing regex produces an interesting result:

> 'Name,DOB'.match(/([^",\r\n]*|"((?:[^"]+|"")*)")(,|\r|\r?\n|$)/g)
["Name", "DOB", ""]

After thoroughly analyzing my regex, I started to think there was something wrong with the JS implementation of the regular expression engine. I also thought there might be something wrong with my regular expression so I made a simpler one and saw the following:

> 'hello,world'.match(/[^,]*(?:,|$)/g)
["hello", "world", ""]

That seems pretty strange, right? I continued investigating and asked around the office to see if others thought it was weird and they agreed. Therefore I decided to try it out in Python to see if there was just a peculiarity in the JS engine:

>>> import re
>>> re.findall('[^,]*(?:,|$)', 'hello,world')
['hello', 'world', '']

Finally, I started thinking about how I would create a regular expression engine that would look for all instances of the empty string and still not result in an infinite loop. The reason I did this was because I knew that running the following doesn’t result in an infinite loop in Python:

>>> import re
>>> re.findall('', 'Yo')
['', '', '']

I tried the same thing in JS:

> 'Yo'.match(/(?:)/g)
["", "", ""]

It seems that if the matched substring has a length of zero, the next search will start one character past the match’s starting/ending index. On the other hand, if the match contains at least one character, the next search will start at the index after the last character matched. Therefore, let’s consider my simplified regular expression again:

> 'hello,world'.match(/[^,]*(?:,|$)/g)
["hello", "world", ""]
  1. The first time the regex engine tries to find a match it uses a greedy search to find zero or more word characters right before a comma or the end of the string.
  2. It finds hello, and the end index is 6.
  3. Now since the last match was not the empty string the regex engine doesn’t try to advance the starting position of the next search and simply evaluates against "world".
  4. It finds world and the end index is 11 (5 plus the offset of 6).
  5. Again since the last match was not the empty string the regex engine doesn’t try to advance the starting position of the next search simply evaluates against the empty string.
  6. Since the empty string matches the regular expression, the third string found is the empty string and the ending index remains 11.
  7. Finally the regex engine looks to see if the previous match was the empty string and since it was, it tries to advance the starting index by one but realizes that is outside the bounds of the string and therefore there is no need to continue.

The steps listed above are simply used to validate the reasoning behind why regex engines would find three matches for matching /[^,]*(,|$)/g against "hello,world". In the event that I would want to use a similar regex which doesn’t allow the empty string at the end, I could use /(?!$)[^,]*(?:,|$)/g. In conclusion, even though I thought I knew all of the strange edge cases for regexes in JS, I found that I still have more to learn! 8-)

Chrome Apps – File System Helpers

Here are a few helper functions that can help you get on the right track to building a simple chrome app that can read and modify the user’s file system:

Get Full Path

In order to get the full path for a DirectoryEntry or a FileEntry you can use the following function:

Reading From A Directory

In order to get the contents of a folder you can use the following function:

Recursively Reading From A Directory

In order to get the contents of a folder and all of it subfolders recursively you can use the following function:

Reading File Contents As Text

In order to get the contents of a file as text you can use the following function:

Writing File Contents AS Text

In order to set the contents of a file as text you can use the following function:

Final Notes

As you may have noticed, all of these functions use callback functions in order to indicate when the action is finished. In the case of writing a file, the callback is optional and is used to indicate that the file has been written. In the end this post is mostly for my benefit, but maybe it will help you out as well! 8-)

JavaScript – Global Eval Using Data URIs

WARNING:
This post is intended solely to educate and is not to by any means encourage that anyone use this method to globally evaluate JavaScript code. Most JavaScripters avoid eval(), especially globalEval() (like what is provided in libraries such as jQuery), as if it were the plague. Its use can be substantiated in some cases but it is of the utmost importance to consider the risks involved with the two functions.
SCRIPTER’S DISCRETION IS ADVISED. :lol:

Since many modern browsers now offer the ability to use Data URIs for more than just images, we could actually use them to essentially run a string of JS code on a page in the global namespace. How so? Here is the code for a simple globalEval() function that can be used in modern browsers such as Chrome and FireFox:

Conceivable Uses

As the jQuery docs mention, one good reason that this type of function exists is to provide a way to execute external scripts in the global namespace. It is important to reiterate that you must use this type of function sparingly, analyzing the reasons why you are using it in the first place.

Another conceivable use would be if you are developing a browser extension that really needs to execute a JavaScript snippet on certain pages. At this point though, if you decide that you want to publish your extension through Google or whichever other channel, that authority may deny your request in the interest to safeguard users from malicious intent. On the other hand, if you are simply creating something like a Chrome extension for private use, I believe you should be able to use this type of approach to execute additional code within pages visited by the user.

Final Words

Much more could be said of the uses of globalEval() and reasons not to use globalEval(), but I like to keep my posts short. If you do find yourself thinking you want to use globalEval(), be sure to calculate the risks (such as possibly running malicious code if it is coming from an external source). Also, this implementation, although very simple, will not work in older browsers such as IE7 (and hasn’t been tested in IE8 or IE9). If you really need a version that has been tested for almost all browsers, I suggest using jQuery’s implementation or perhaps this one. Be careful! :cool:

JavaScript – Creating A Downloadable File in the Browser

Let’s say that you have an array of arrays that is dynamically generated and you would like to provide a download link/button to download it as a CSV. How would you go about doing it? Ordinarily you would go about sending the data to the server which would then be able to make a downloadable version of the data. Believe it or not, there is also a way to do it in modern browsers without ever needing to make additional requests to a server. The following JSBin proves this by providing a large textarea that can be modified and a download link which when clicked (in modern browsers) will download a file with the specified contents:
JS Bin

How does it work? We basically just rely on data URIs. For instance, clicking here should result in downloading a file with text saying Hello World!!!. This an simply an anchor element (<a>) with an href of data:text/plain;charset=utf-8,Hello%20world!!!. In addition, some newer browsers (Chrome and FireFox) support the download attribute being set to specify the default file name when downloaded.

How do you get it to be dynamic? You can simply modify the href attribute when the link is clicked, by binding the necessary code to the click event of the link. Here is a simple version of the JSBin shown:

<!DOCTYPE html>
<html>
  <head>
    <style type="text/css">...</style>
    <script type="text/JavaScript">
    window.onload = function() {
      var txt = document.getElementById('txt');
      txt.value = window.onload + '';
      document.getElementById('link').onclick = function(code) {
        this.href = 'data:text/plain;charset=utf-8,'
          + encodeURIComponent(txt.value);
      };
    };

    main();
    </script>
  </head>
  <body>
    <div id="txtWrap">
      <textarea id="txt"></textarea>
    </div>
    <a href="" id="link" download="code.txt">Download Above Code</a>
  </body>
</html>

Ignoring the omitted CSS rules, you will notice that the concept is quite simple. The one thing you want to remember is that in order to make sure that all characters are downloaded correctly you will want to use encodeURIComponent(). I have seen implementations that use escape(), but that function is deprecated and doesn’t always encode the characters correctly.

Have fun making your quick custom download buttons :cool:

POW Answer – Circle, Square, Circle

Last week’s problem involved using your geometry/trigonometry skills to find areas of shapes. We start off with a large (black) circle which has a (black) square inscribed in it which in turn has a (red) circle inscribed in it:
Circle Inscribed In A Square Inscribed In Another Circle

  1. Let’s start off with the equation for the area of a circle: A = π × r2 (where r is the radius)
  2. Now let’s think about the equation for area of a square: A = s2 (where s is the length of one of the sides)
  3. Next we can say that the radius of the inner circle is r1.
  4. After that let’s find the area of the red inner circle relative to r1: A1 = π × r12
  5. Now let’s find the length of the diagonal of the square (d) in which the red circle is inscribed relative to r1. This will also be the diameter of the outer circle
    1. s = r1 + r1 = 2 × r1
    2. The above is true because the red circle is inscribed in the square.
    3. d2 = s2 + s2
    4. d2 = 2 × s2
    5. d = (2 × s2)1/2
    6. d = s × 21/2
    7. d = 2 × r1 × 21/2
  6. Next we should find the area of the black circle (A2), in which the black square is inscribed, relative to r1.
    1. We will use r2 to represent the radius of the outer circle:
      1. r2 = d / 2
      2. r2 = (2 × r1 × 21/2) / 2
      3. r2 = r1 × 21/2
    2. A2 = π × r22
    3. A2 = π × (r1 × 21/2)2
    4. A2 = π × r12 × 2
  7. Lastly we should find the area of the black outer circle while excluding the area covered by the red inner circle:
    1. Let’s make the area of the black doughnut shape be represented by A3.
    2. A3 = A2 - A1
    3. A3 = (π × r12 × 2) - (π × r12)
    4. A3 = (π × r12) + (π × r12) - (π × r12)
    5. A3 = π × r12

So after doing all of the math by using a little geometry and a little algebra we end up with the A1 (red area) being equal to A3 (black area).
Filled Circles

Even though the image makes it look like there is more red than black, there really isn’t. Interesting stuff, huh? :cool:

POW – Circle, Square, Circle

Recently a friend asked why I haven’t put up any new POWs (Problems of the Week). Part of the reason is because I got lazy but the other part is because the show Numb3rs is what inspired me before and I haven’t been watching any reruns lately :razz:. Yesterday I started watching a new show called Scorpion which has a little math in it and the second episode got me thinking about inscribed shapes. Take the following three shapes for example:
Circle Inscribed In A Square Inscribed In Another Circle

Above is a picture of a circle inscribed in a square which itself is inscribed in another circle. Now if I make the inner circle red and the remaining area black the image ends up looking as follows:
Filled Circles

Using the information given, is the red area bigger or the black area? If you remember a few things from trigonometry/geometry I’m sure this math problem will be a breeze :cool:. As usual the answer to this problem of the week became available a week after the POW was published and can be found here.

Embedding Stylesheets in JavaScript

One of the cool things about JS is that you can do almost anything with it! The only thing is that you need to have the tools to get that “anything” job done. Recently, I had the desire to embed HTML, CSS, and JS all in one file that would be loaded when a specific browser event fired. The common solution is to use a library such as jQuery to load an HTML snippet but I wanted a different solution. I was thinking it would be great to be able to do something like this:

css({
    'div.special-1, span.special-2': {
        fontFamily: 'Trebuchet MS',
        a: {
            textDecoration: null,
            '&:link, &:visited': { color: '#08F' },
            '&:hover, &:active': { color: 'red' }
        }
    }
});

Having this resulting in a stylesheet added to the HEAD with the following CSS:

div.special-1, span.special-2 {
    font-family: Trebuchet MS;
}
div.special-1 a, span.special-2 a {
    text-decoration: none;
}

div.special-1 a:link, span.special-2 a:link,
div.special-1 a:visited, span.special-2 a:visited {
    color: #08F;
}

div.special-1 a:hover, span.special-2 a:hover,
div.special-1 a:active, span.special-2 a:active {
    color: red;
}

After a bit of work to make a few Sass-like features work, I came up with the following JavaScript function:

Brief css(objStyles, opt_ancestors) Documentation

This function takes an object representing CSS rules and adds a stylesheet with those rules to the document.

Parameters

  1. objStyles
    An object representing the CSS rules to be inserted into the document.

    • Property names will be used as media queries if they start with "@media ".
    • Property names will be used as rule selectors if the value is an object.
    • If a property name is to be used as a selector, if any selectors don’t contain &, "& " will be prepended to it.
    • For all selectors, & will be replaced recursively with the selectors found in the parent.
    • CSS property names will be uncamelcased by inserting dashes before each uppercased character and lower casing all characters.
    • If a value is null or undefined, it will be turned into "none".
    • If a value is a number other than 0, "px" will be appended to it.
    • If a value is an array all of the items will be concatenated together, using "," to delimit the values.
    • If a value ends with ! it will be replaced with "!important".
  2. opt_ancestors
    Optional. This can be an element or an array of elements which will get another class added to target all rules to it and its children. This can alternatively be a CSS path (selector) specifying the root on which all CSS rules created should be based.

Returns

The stylesheet that is created and appended to the document is returned.

Future Development

I feel like this function turned out pretty well so I plan on incorporating it into YourJS (whenever I finish up with that :-D ). In the meantime, if I update the code, you will be able to see the updates here or in GitHub. One thing I would like to incorporate is the ability to have variables. Another nice-to-have thing would be the ability to supply more options such as where the stylesheet should be inserted (if it will be inserted at all), pretty-print, and helper functions (eg. darken). Feel free to leave a comment saying what other things may be nice to have. 8-)

JavaScript Snippet – Get Function Comments

Last year I wrote about having heredoc like strings available in JavaScript. Today I figured i’d briefly bring the topic back, providing a solution for returning an array of all comments found in a function:

Why is this useful? As you may know, writing multiline strings in JavaScript isn’t always the prettiest especially when you have to use \n or \r\n. On the other hand, let’s imagine that we have some multiline strings stored inside of a function as comments:

As you can see in the above jPaq Proof, by using the getComments function on a function which contains comments you can pull the comments out as if they were HEREDOC strings. Have fun! 8-)

NOTE: It is important to remember that if you are minifying your code, these comments will most-likely be stripped out. In this case you will want to find a different solution such as using the string escape characters (\r\n or \n).

Watch Anime & Cartoons Online for Free

Recently I have had the desire to provide more multimedia on my site. Due to the server requirements and the time it would take to keep everything up-to-date I decided to take the easy way out and simply link to the media providers such as Apple and WatchCartoonOnline. If you check out my home page at GoToChrisWest.com you will notice I have three new content sections with one of them for displaying anime/cartoon content. How did I get it to work? The following is the JSBin version of the content:
WatchCartoonOnline Links

As is the case with all JSBin content, you will be able to look through all of the HTML, CSS and JS code yourself, but it is important to note that with just a few tweaks here and there you could modify this code to work on your own site. I’d like to note that besides using the RSS feed provided by WatchCartoonOnline I am also using two different services provided by Google:

  1. Google Feed API (https://ajax.googleapis.com/ajax/services/feed/load?…):
    Used to convert the feed into JSON-P.
  2. Google Image Search API (https://ajax.googleapis.com/ajax/services/search/images?…):
    Used to search for a thumbnail to display next to each episode name. If you want to actually use this on your site it is suggested that you use the non-deprecated Custom Search API :-)

I’d also like to mention that the scripts added to handle the JSON-P calls are created by the function outlined here.

One way you could improve this code would be to avoid making a new JSON-P call for an image for a show that was already search for. There are most-likely other ways to improve this code as well, but I feel it’s a pretty good starting point for anyone that would like to provide similar links to WatchCartoonOnline content on their site. 8-)

JavaScript, Math, and much more.