Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tmcw/f247f461eec352400bccc4ace322a1bd to your computer and use it in GitHub Desktop.
Save tmcw/f247f461eec352400bccc4ace322a1bd to your computer and use it in GitHub Desktop.
import React from "react";
import CodeMirror from "codemirror";
// Adapted from CodeMirror runMode, updated to output React components.
export class HighlightCode extends React.Component {
render() {
const {value: string} = this.props;
const nodes = [];
const mode = CodeMirror.getMode(CodeMirror.defaults, "r-javascript");
const tabSize = CodeMirror.defaults.tabSize;
let col = 0;
function callback(text, style) {
if (text == "\n") {
nodes.push(<>{text}</>);
col = 0;
return;
}
let content = "";
// replace tabs
for (let pos = 0; ; ) {
let idx = text.indexOf("\t", pos);
if (idx == -1) {
content += text.slice(pos);
col += text.length - pos;
break;
} else {
col += idx - pos;
content += text.slice(pos, idx);
let size = tabSize - (col % tabSize);
col += size;
for (let i = 0; i < size; ++i) content += " ";
pos = idx + 1;
}
}
if (style) {
nodes.push(
<span className={"cm-" + style.replace(/ +/g, " cm-")}>
{content}
</span>
);
} else {
nodes.push(<>{content}</>);
}
}
const lines = CodeMirror.splitLines(string);
const state = CodeMirror.startState(mode);
for (let i = 0, e = lines.length; i < e; ++i) {
if (i) callback("\n");
const stream = new CodeMirror.StringStream(lines[i]);
if (!stream.string && mode.blankLine) mode.blankLine(state);
while (!stream.eol()) {
let style = mode.token(stream, state);
callback(stream.current(), style, i, stream.start, state);
stream.start = stream.pos;
}
}
let key = 0;
return (
<code>
<pre>
{nodes.map(node =>
React.cloneElement(node, {
key: ++key
})
)}
</pre>
</code>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment