title: Client Side JavaScript Code Analyser
body: <p>Is there a JavaScript Code analyser which can be used on the client side to analyze code patterns? 
  I've found the following but it seems that this is just for regular text and gives you the <code>=</code> sign etc. I need some code analysis which can run on the client side (JS code), is there any which can be used? </p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>function parseData() {
    var rawData = document.getElementById('data').value.trim(),  
        result,
        output = $('#output'),
        table = $('table').remove(),
        header,
        row,
        cell,
        ul,
        slice,
        wpm = [],        
        wpmAvg = [];
  
    output.empty();
    table.find('thead, tbody').empty();
  
    if ($('[name="format"]:checked').val() === 'text') {
      // Simple text        
      result = analyzeText(rawData);
      output.append('Word count: ' + result.count + '&lt;br&gt;&lt;br&gt;Frequent words:&lt;br&gt;');
      ul = $('&lt;ul&gt;');
      _.forEach(result.frequentWords, function(value, key) {
        ul.append('&lt;li&gt;' + value.word + ': ' + value.count + '&lt;/li&gt;');
      });
      output.append(ul);       
    }
    else {
      // JSON
      try {
        data = JSON.parse(rawData);
      }
      catch(e) {
        console.log('Error parsing JSON', e);
      }
      header = table.find('thead');
      body = table.find('tbody');
      row = $('&lt;tr&gt;');
      body.append(row);
      // Loop over slices
      _.forEach(data, function(value, key) {
        slice = '';
        // Loop over statements
        _.forEach(value, function(value, key) {
          slice += value.words + ' ';
        });
  
        result = analyzeText(slice);
  
        addCell(slice, key);
  
      });
      $.plot('#wpm', [wpm], {
        xaxes: [{
          axisLabel: 'Time index (1-minute increments)',
        }],
        yaxes: [{
          position: 'left',
          axisLabel: 'Words per minute',
        }]
      });
      output.append(table);
    }
  
    function addCell(data, index) {
      var cell1, cell2, ul1, ul2, result;
      cell1 = $('&lt;td&gt;');
      cell2 = $('&lt;td&gt;');
      ul1 = $('&lt;ul&gt;');
      ul2 = $('&lt;ul&gt;');
      cell1.append(ul1);
      cell2.append(ul2);
      row.append(cell1, cell2);
      result = analyzeText(data);
      header.append('&lt;th&gt;' + index + '&lt;/th&gt;&lt;th class="subText"&gt;(' + result.count + ')&lt;/th&gt;');
      wpm.push([index, result.count]);
      _.forEach(result.frequentWords, function(value, key) {
        ul1.append('&lt;li&gt;' + value.word + '&lt;/li&gt;');
        ul2.append('&lt;li&gt;' + value.count + '&lt;/li&gt;');
      });
    }
  }
  
  function analyzeText(rawData) {
    var result = {
      count: 0,
      frequentWords: []
    },
        data = rawData.split(/[\s.,]+/g)
    counts = {},
      countsArray = [],
      commonWords = [ 
      0,1,2,3,4,5,6,7,8,9,            
      '-',
      'a',
      'about',
      'function',
      'object'
    ];
  
    if (!data[data.length]) {
      data.splice(-1, 1);
    }
  
    // Word count
    result.count = data.length;
  
    // Word frequency (filtered for common words, sorted descending by count)
    for (var i = 0; i &lt; data.length; i++) {
      if (!counts.hasOwnProperty(data[i].toLowerCase())) {
        counts[data[i].toLowerCase()] = 1;
      }
      else {
        counts[data[i].toLowerCase()] += 1;
      }
    }    
    _.forEach(counts, function(value, key) {
      if (commonWords.indexOf(key.toLowerCase()) === -1) {
        countsArray.push({
          word: key.toLowerCase(),
          count: value
        });
      }
    });
    countsArray = _.sortBy(countsArray, 'count').reverse();    
    _.forEach(countsArray, function(value, index) {
      if (value.count &gt; 1) {
        result.frequentWords.push(value);            
      }
    });
  
    return result;
  }</code></pre>
  <pre class="snippet-code-css lang-css prettyprint-override"><code>body {
    font-family: arial;
  }
  table, tr, td, th {
    border-collapse: collapse;
    border: solid 1px #ddd;
  }
  th, td {
    padding: 4px 8px;    
  }
  .subText {
    color:#999;
    font-style: italic;
  }
  #wpm {
    width:600px;
    height: 400px;
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"&gt;&lt;/script&gt;
  &lt;script src="https://code.jquery.com/jquery-2.1.4.min.js"&gt;&lt;/script&gt;
  &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/flot/0.8.3/jquery.flot.js"&gt;&lt;/script&gt;
  
  &lt;textarea id="data" cols="80" rows="20" placeholder="Paste text or JSON here"&gt;&lt;/textarea&gt;&lt;br /&gt;
  &lt;label for="text"&gt;&lt;input type="radio" name="format" checked value="text" id="text"&gt; Simple text&lt;/label&gt;
  &lt;button type="button" onclick="parseData()"&gt;Analyze text&lt;/button&gt;
  &lt;br&gt;&lt;br&gt;
  &lt;div id="output"&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;
  &lt;div id="wpm"&gt;&lt;/div&gt;
  &lt;table&gt;
    &lt;thead&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p><a href="https://jsfiddle.net/fxn5q8y0/6/" rel="nofollow">https://jsfiddle.net/fxn5q8y0/6/</a></p>