A quick guide to extracting and displaying icon fonts like Font Awesome

80-shades-of-white-icons-psd

Today, I will share with you a method of extracting and displaying icons from an icon font such as FontAwesome. The solution depends entirely on Javascript’s Regex engine, so I will be doing a quick refresher on the subject first.

What are Regular Expressions?

Regular expressions or regex in short, are programming objects that allow you to search for complex patterns in textual content using only a sequence of characters. These characters can be meta characters with special meaning, or regular characters with literal meaning.

If for example you wanted to search for the two spellings of the word color in the text “color and colour mean the same thing”, then you would write your regex as follows:

colo[u]*r

The above regex will find occurrences of the words color and colour. But how does it work?

  • colo will match the string colo. This part is made up of literal characters.
  • [u] will match u. The brackets are meta characters and will match any of the contained characters.
  • * is also a meta character. It matches the preceding pattern zero or more times.
  • so colo[u]*r will match any spelling of color with zero or more u’s in the position specified.

Regex in Javascript

Javascript offers two methods to declare a Regex object. The first method uses a constructor, while the second one uses a literal notation.


// Using a constructor. The "g" flag is passed as an argument.
var myRegex = new RegExp("col[u]*r", "g");

// Using a literal defined by slashes. The "g" flag is passed at the end.
var myRegex = /col[u]*r/g;

The “g” in both methods is a regex flag. The “g” tells the regex engine to do a global search. When using the constructor method, flags are passed as arguments. In the second method, flags are appended at the end of the expression.

Regex in our solution

So what part does regex play in extracting icons? Well, just look at the following entries for a few icons in font awesome’s CSS file.


.fa-bookmark:before {
  content: "\f02e";
}
.fa-print:before {
  content: "\f02f";
}
.fa-camera:before {
  content: "\f030";
}

From what you can see, each icon is defined in the same exact way. This means that extracting the entire collection of icons is as simple as reading the CSS file and finding classes that follow the above pattern. And that’s where regex come in. We need to craft an expression that only matches icon classes, then use it to search for icons.

Turning our pattern to Regex

Now, it must be said that there are usually more than 1 way to cook a Regular Expression. You may have come up with a different, possibly even shorter regex, but this straight forward version got me positive matches:


\.([\w-]+):before\s*{\s*content:\s*(["']\\\w+["']);*\s*}

The brackets in the highlighted parts will tell the regex engine to group our matches. The first group captures the class name, will the other one captures the icon code. These groups will be stored in different positions in the returned array. Thus the entire match will be at match[0], the class name as match[1] and so on. The regex further explained:

  • \. matches a period which we have to escape.
  • [\w-]+ matches any word or hyphen character, that is the class name at least once.
  • :before\s*{ matches :before plus an optional white space that is followed by {
  • \s*content:\s* matches content and any optional white spaces surrounding it
  • [“‘] matches single or double quotes
  • \\\w+ matches any word that starts with an escaped \ at least once.
  • ;*\s*} matches optional semi colon and white spaces followed by }

Testing our pattern

There are many regex testing tools online. My favorite is www.regexpal.com. The main interface on regexpal only has two boxes. Simply paste your regex in the top text box, then a few test icon classes in the bottom box. Any positive matches will be highlighted and you can adjust your regex accordingly.

Once you are satisfied with the results, then you can move on to actually write the code that will put your regex to use.

Writing our functions

At the very least we will need the following functions:

  1. A function that uses AJAX to load a CSS file from a given path.
  2. A function that adds the CSS file as stylesheet
  3. A function that reads the CSS file, extracts the icon classes, then spits out markup to display them

All these functions of course will be running inside a web page you have already setup and styled. If you are too lazy to do this, I have setup a demo at codepen you can build upon. Okay, now on to the functions:

// Declare our regex object. "m" flag enables a multi line search
var regex = /\.([\w-]+):before\s*{\s*content:\s*(["']\\\w+["']);*\s*}/gm;

// Main function
function loadIcons(path) {
  $.ajax({
    url: path,
    dataType: "text",
    success: function(data) {
      loadSheet(path);
      parseCss(data);
    },
    error: function(error) {
      console.log(error.statusText);
    }
  });
}

// CSS parser
function parseCss(text) {
  var listMarkup = "<ul>";
  var match;
  
  while (match = regex.exec(text)) {
    var name = match[1];  // class name is at index 1
    var code = match[2]; // code at index 2
    listMarkup += "<li><i class='" + name + "'></i></li>";           
  }
  
  listMarkup += "</ul>";
  
  return listMarkup;
}

// Stylesheet loader
function loadSheet(path) {
  var similar = 0;
  $("link").each(function(e) {
    if($(this).attr("href") == path) similar++;
  });
  
  if(similar == 0) {
    $('<link>').attr('rel','stylesheet')
    .attr('type','text/css')
    .attr('href',path)
    .appendTo('head');
  }
}

Complete demo

The above functions are really all you need. However, you will still need other things like a means of accepting file inputs, error handling, styles for your page etc. If you do not have time for all of this, then you can check out a complete demo I put upon my codepen page.

See the Pen Extracting icon fonts using Regex by Arnique Studio (@Arnique) on CodePen.