Skip to content

Commit

Permalink
chore: roll up lines into commands
Browse files Browse the repository at this point in the history
  • Loading branch information
jerelmiller committed Oct 15, 2020
1 parent 1fa4ff4 commit c5241bb
Showing 1 changed file with 55 additions and 8 deletions.
63 changes: 55 additions & 8 deletions src/components/Terminal/SyntaxHighlighter.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ import Highlight from 'prism-react-renderer';
import Prism from 'prismjs';
import Prompt from './Prompt';

const WHITESPACE = /^\s*$/;
const MULTILINE_COMMAND = /\\\s*$/;
const OUTPUT_TAG = /^\[output\]\s/;
const OUTPUT_COLOR_TOKENS = /{([a-z]+)}(.*?(?={|$))/g;

const SyntaxHighlighter = ({ code }) => (
<Highlight Prism={Prism} code={code} language="shell">
{({ tokens, getLineProps, getTokenProps }) => {
console.log(tokens);
const commands = rollupIntoCommands(tokens, code);

return tokens.map((line, idx) => {
const previousLine = collapse(tokens[idx - 1] || [])
.map((token) => token.content)
.join(' ');
const previousLine = collapse(tokens[idx - 1] || []);
const isMultiline = MULTILINE_COMMAND.test(previousLine);

return (
Expand Down Expand Up @@ -49,10 +49,57 @@ const SyntaxHighlighter = ({ code }) => (
);

const collapse = (line) => {
return line.filter(
(token) =>
!WHITESPACE.test(token.content) && !token.types.includes('comment')
return line
.filter((token) => !token.types.includes('comment'))
.map((token) => token.content)
.join('');
};

const rollupIntoCommands = (lines, code) => {
const rawLines = code.split('\n');

const { commands } = lines.reduce(
({ commands, terminated }, line, idx) => {
const command = collapse(line);
const updateIdx = terminated ? commands.length : commands.length - 1;
const data = commands[updateIdx] || { lines: [], output: [] };
const nextCommand = collapse(lines[idx + 1] || []);
const continues =
OUTPUT_TAG.test(nextCommand) || MULTILINE_COMMAND.test(command);

if (OUTPUT_TAG.test(command)) {
commands[updateIdx] = {
...data,
output: [...data.output, tokenizeOutputLine(rawLines[idx])],
};
} else {
commands[updateIdx] = { ...data, lines: [...data.lines, line] };
}

return { commands, terminated: !continues };
},
{ commands: [{ lines: [], output: [] }], terminated: false }
);

return commands;
};

const tokenizeOutputLine = (line) => {
const text = line.replace(OUTPUT_TAG, '');
const tokens = Array.from(text.matchAll(OUTPUT_COLOR_TOKENS));

if (tokens.length === 0) {
return [{ color: 'plain', text }];
}

const startOfColorIdx = text.indexOf('{');
const coloredTokens = tokens.map(([, color, text]) => ({ color, text }));

return startOfColorIdx === 0
? coloredTokens
: [{ color: 'plain', text: text.slice(0, startOfColorIdx) }].concat(
coloredTokens
);
};

SyntaxHighlighter.propTypes = {
Expand Down

0 comments on commit c5241bb

Please sign in to comment.