docs: function highlight(text, lang, options){
  
      function makeSafe(str){
        return str
          .replace(/\r\n|\n\r|\r/g, '\n')
          .replace(/&/g, '&amp;')
          .replace(/</g, '&lt;');
      }
  
      function normalize(text){
        text = text
          // cut first empty lines
          .replace(/^(?:\s*[\n]+)+?([ \t]*)/, '$1')
          .trimRight();
  
        // fix empty strings
        text = text.replace(/\n[ \t]+\n/g, '\n\n');
  
        // normalize text offset
        var minOffset = 1000;
        var lines = text.split(/\n+/);
        var startLine = Number(text.match(/^function/) != null); // fix for function.toString()
  
        for (var i = startLine; i < lines.length; i++)
        {
          var m = lines[i].match(/^\s*/);
          if (m[0].length < minOffset)
            minOffset = m[0].length;
          if (minOffset == 0)
            break;
        }
  
        if (minOffset > 0)
          text = text.replace(new RegExp('(^|\\n) {' + minOffset + '}', 'g'), '$1');
  
        return text;
      }
  
      function defaultWrapper(line, idx){
        return (
          '<div class="line ' + (idx % 2 ? 'odd' : 'even') + lineClass + '">' +
            '<span class="lineContent">' +
              (!options.noLineNumber
                ? '<input class="lineNumber" value="' + lead(idx + 1, numberWidth) + '" type="none" unselectable="on" readonly="readonly" tabindex="-1" />' +
                  '<span class="over"></span>'
                : ''
              ) +
              line + '\r\n' +
            '</span>' +
          '</div>'
        );
      }
  
      //  MAIN PART
  
      if (!options)
        options = {};
  
      // prepare text
      var rangeStart = -1;
      var rangeEnd = -1;
      var rangeName = '';
  
      if (options.range)
      {
        var left = makeSafe(text.substr(0, options.range[0]));
        var range = makeSafe(text.substring(options.range[0], options.range[1]));
        var right = makeSafe(text.substr(options.range[1]));
  
        rangeStart = left.length;
        rangeEnd = rangeStart + range.length;
        rangeName = options.range[2] || 'range';
  
        text = left + range + right;
      }
      else
      {
        text = makeSafe(text);
      }
  
      if (!options.keepFormat)
        text = normalize(text || '');
  
      var parser = LANG_PARSER[lang] || LANG_PARSER.text;
      var html = parser(text, rangeStart, rangeEnd, rangeName);
  
      var lines = html.split('\n');
      var numberWidth = String(lines.length).length;
      var lineClass = (options.noLineNumber ? '' : ' hasLineNumber');
      var offsetRx = new RegExp('^(<span class="' + rangeName + '">)?([ \\t]+)');
  
      lines = lines
        .map(function(line){
          return line.replace(offsetRx, function(m, rangeSpan, spaces){
            return (rangeSpan || '') + repeat('\xA0', spaces.replace(/\t/g, '  ').length);
          });
        })
        .map(options.wrapper || defaultWrapper);
  
      return options.lines ? lines : lines.join('');
    }