JSFiddle - React, Tailwind, and code Playground

by mathheadinclouds

HTML

<head>
  <script src="https://mathheadinclouds.github.io/thirdparty/esprima.js"></script>
  <script src="https://mathheadinclouds.github.io/thirdparty/estraverse.browser.js"></script>
  <script src="https://mathheadinclouds.github.io/thirdparty/escope.browser.js"></script>
</head>

<body>
    <div>
        <h3>what's in scope</h3>
        paste your code here<br>
        <textarea cols="99" rows="25" id="theTextArea"></textarea><br>
        <button id="button">go</button>
        <pre>
            put your mouse over the code. Variables in scope will be highlighted
            shadowed variables will have red border
            if the mouse is over a variable, the corresponding declaration will have black border
        </pre>
        <pre id="codeContainer"></pre>
        <div id="swatchesParent"></div><br>
        <pre id="CONSOLE"></pre><br>
    </div>
</body>

CSS

div.swatch {
	width: 45px;
	float: left;
	text-align: center;
}
pre { tab-size: 4 }

JavaScript

var generateColor = (function(){
    // alpha, beta, gamma must all be between 0 and 1,
    // they must be irrational, and their respective ratios must be irrational also.
    // further, when written as a continued fraction, the integer coefficients of that
    // should be small, such as, all ones and twos. Then, with below method, you get
    // a stream of colors which are "as different as possible to each other", loosely speaking.
      var gamma = (Math.sqrt(5)-1)/2;
      var alpha = Math.sqrt(3)-1;
      var beta  = Math.sqrt(2)-1;
      var brightnessFactor = 4; // positive floating point number; the larger the brighter; for dark colors, make it less than 1
      function _generateColor(index){
          var n = 1 + index;
          var nAlpha = n * alpha;
          var nBeta  = n * beta;
          var nGamma = n * gamma;
          var _r = nAlpha - Math.floor(nAlpha);
          var _g = nBeta  - Math.floor(nBeta);
          var _b = nGamma - Math.floor(nGamma);
          var expo = 1/brightnessFactor;
          var _R = Math.pow(_r, expo);
          var _G = Math.pow(_g, expo);
          var _B = Math.pow(_b, expo);
          var r = Math.floor(255.999999 * _R);
          var g = Math.floor(255.999999 * _G);
          var b = Math.floor(255.999999 * _B);
          return 'rgb(' + [r,g,b].join(', ') + ')';
      }
      return _generateColor;
  })();
    
  var theTextArea, ast, codeContainer, analysis, colors, codeSpans, activeSpan, swatchesParent, CONSOLE, tokens, button;
  colors = [];
  
      function findPathAtPosition(pos){
          var result = [];
          function process(node){
              result.push(node);
              function isSubNode(key){
                  // caution/todo: I strongly suspect that there are one or more fringe cases
                  // I haven't considered, and this function is buggy. But it works most of the time ...
                  var child = node[key];
                  if (child===null) return false;
       ...