All files codemirror.jsx

100% Statements 46/46
92.31% Branches 12/13
100% Functions 5/5
100% Lines 45/45

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 832x 2x 2x 2x   2x   2x 2x   2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x     20x   20x 15x   15x   14x       20x     2x 20x 20x 20x         6x   6x     3x     20x 20x   129x 129x 54x             75x       20x 132x 109x 109x 109x   23x     20x   20x    
const CodeMirror = require('codemirror');
const React = require('react');
const Variable = require('@readme/variable');
const modes = require('./modes');
 
const { VARIABLE_REGEXP } = Variable;
 
require('codemirror/addon/runmode/runmode');
require('codemirror/mode/meta.js');
 
require('codemirror/mode/clike/clike');
require('codemirror/mode/dockerfile/dockerfile');
require('codemirror/mode/go/go');
require('codemirror/mode/htmlmixed/htmlmixed');
require('codemirror/mode/javascript/javascript');
require('codemirror/mode/php/php');
require('codemirror/mode/powershell/powershell');
require('codemirror/mode/python/python');
require('codemirror/mode/ruby/ruby');
require('codemirror/mode/shell/shell');
require('codemirror/mode/swift/swift');
 
function getMode(lang) {
  let mode = lang;
 
  if (mode in modes) {
    mode = modes[mode];
    // lang = mode;
    if (Array.isArray(mode)) {
      // lang = mode[0];
      [, mode] = mode;
    }
  }
 
  return mode;
}
 
module.exports = (code, lang, opts = { tokenizeVariables: false }) => {
  const output = [];
  let key = 0;
  const mode = getMode(lang);
 
  function tokenizeVariable(value) {
    // Modifies the regular expression to match anything
    // before or after like quote characters: ' "
    const match = new RegExp(`(.*)${VARIABLE_REGEXP}(.*)`).exec(value);
 
    if (!match) return value;
 
    // eslint-disable-next-line no-plusplus
    return [match[1], <Variable key={++key} variable={match[2]} />, match[3]];
  }
 
  let curStyle = null;
  let accum = '';
  function flush() {
    accum = opts.tokenizeVariables ? tokenizeVariable(accum) : accum;
    if (curStyle) {
      output.push(
        // eslint-disable-next-line no-plusplus
        <span key={++key} className={`${curStyle.replace(/(^|\s+)/g, '$1cm-')}`}>
          {accum}
        </span>
      );
    } else {
      output.push(accum);
    }
  }
 
  CodeMirror.runMode(code, mode, (text, style) => {
    if (style !== curStyle) {
      flush();
      curStyle = style;
      accum = text;
    } else {
      accum += text;
    }
  });
  flush();
 
  return output;
};