Skip to content

Commit

Permalink
Add syntax highlighting (for S2023) (#2)
Browse files Browse the repository at this point in the history
Used Prism's Lisp highlighter as a starting point.
  • Loading branch information
matthewyu01 committed Jun 29, 2023
1 parent debe7e7 commit cac8087
Show file tree
Hide file tree
Showing 5 changed files with 267 additions and 7 deletions.
25 changes: 25 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
"private": true,
"dependencies": {
"@types/node": "^18.14.6",
"@types/prismjs": "^1.26.0",
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
"prismjs": "^1.29.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
Expand Down
118 changes: 118 additions & 0 deletions src/components/BrewinEditor.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/* PrismJS 1.29.0
modified from https://prismjs.com/download.html#themes=prism&languages=lisp */
code[class*="language-"],
pre[class*="language-"] {
color: #000;
background: 0 0;
text-shadow: 0 1px #fff;
font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace;
font-size: 1em;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
code[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection,
pre[class*="language-"] ::-moz-selection,
pre[class*="language-"]::-moz-selection {
text-shadow: none;
background: #b3d4fc;
}
code[class*="language-"] ::selection,
code[class*="language-"]::selection,
pre[class*="language-"] ::selection,
pre[class*="language-"]::selection {
text-shadow: none;
background: #b3d4fc;
}
@media print {
code[class*="language-"],
pre[class*="language-"] {
text-shadow: none;
}
}
pre[class*="language-"] {
padding: 1em;
margin: 0.5em 0;
overflow: auto;
}
:not(pre) > code[class*="language-"],
pre[class*="language-"] {
background: #f5f2f0;
}
:not(pre) > code[class*="language-"] {
padding: 0.1em;
border-radius: 0.3em;
white-space: normal;
}
.token.comment {
color: #708090;
}
.token.punctuation {
color: #999;
}
.token.boolean,
.token.constant,
.token.number,
.token.property,
.token.symbol {
color: #f07178;
}
.token.attr-name,
.token.builtin,
.token.char,
.token.inserted,
.token.selector,
.token.string {
color: #c3e88d;
}
.token.genericTypeConcatChar {
color: #c3a3d2;
}
.language-css .token.string,
.style .token.string,
.token.entity,
.token.operator {
color: #9a6e3a;
background: hsla(0, 0%, 100%, 0.5);
}
.token.keyword {
color: #82aaff;
}
.token.function {
color: #dd4a68;
}
.token.variable {
color: #e90;
}
.token.bold,
.token.important {
font-weight: 700;
}
.token.classRefs,
.token.class-name,
.token.null {
color: #54a5ab;
}
.token.new {
color: #c0984d;
}
.token.classAttributes {
color: #dd4;
}
.token.primitiveTypes {
color: #ab7dbc;
}
.token.exceptionKeywords {
color: #ffcb6b;
}
20 changes: 13 additions & 7 deletions src/components/BrewinEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
import { useContext, useState } from "react";
import Editor from "react-simple-code-editor";
import { DEFAULT_VERSION, ENDPOINT, getFlavourText } from "../constants";
import { DEFAULT_VERSION, ENDPOINT, getFlavourText, S23_VERSIONS } from "../constants";
import { InterpreterVersion, RunResponse } from "../types";
import { BaristaContext } from "../BaristaContext";
import Prism from "prismjs";
import "./BrewinEditor.css";

import PastBrews from "./PastBrews";
import EditorToolbar from "./EditorToolbar";

function getHighlighter(quarter: string, version: string){
if (quarter === "s23"){
return S23_VERSIONS[parseInt(version) - 1]?.highlighter ?? {};
}
return {};
}

export default function BrewinEditor() {
const baristaMode = useContext(BaristaContext);

Expand Down Expand Up @@ -113,9 +123,7 @@ export default function BrewinEditor() {
className="editor border my-1"
value={program}
onValueChange={(program) => setProgram(program)}
highlight={
(code) => code /* this is an identity -- no highlighting */
}
highlight={(program) => Prism.highlight(program, getHighlighter(quarter, version), "brewin")}
padding={10}
/>

Expand All @@ -124,9 +132,7 @@ export default function BrewinEditor() {
className="editor border my-1"
value={stdin}
onValueChange={(stdin) => setStdin(stdin)}
highlight={
(code) => code /* this is an identity -- no highlighting */
}
highlight={(code) => code}
padding={10}
style={{ minHeight: "1rem" }}
/>
Expand Down
109 changes: 109 additions & 0 deletions src/constants/s23.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,115 @@
const par = "(\\()";
const symbol = /(?!\d)[-+*/~!@$%^=<>{}\w]+/.source;
const space = "(?=\\s)";
const optionalSpace = "\\s*";

function primitive(pattern: string) {
return RegExp(
/([\s([])/.source + "(?:" + pattern + ")" + /(?=[\s)])/.source
);
}

const brewinV1 = {
comment: /#.*/,
string: {
pattern: /"(?:[^"\\]|\\.)*"/,
greedy: true,
inside: {
argument: /[-A-Z]+(?=[.,\s])/,
symbol: RegExp("`" + symbol + "'"),
},
},
keyword: [
{
pattern: RegExp(
par + optionalSpace +
"(?:and|(?:cl-)?if|while|(?:lexical-)?let\\*?|while\
)" +
space
),
lookbehind: true,
},
{
pattern: RegExp(
par + optionalSpace + "(?:begin|set|print|call)" + space
),
lookbehind: true,
},
{
pattern: primitive(/return|inputi|inputs/.source),
lookbehind: true,
}
],
class: {
pattern: primitive(/class/.source),
lookbehind: true,
alias: "class-name",
},
boolean: {
pattern: primitive(/false|true/.source),
lookbehind: true,
},
classRefs: {
pattern: primitive(/me/.source),
lookbehind: true,
},
new: {
pattern: primitive(/new/.source),
lookbehind: true,
},
null: {
pattern: primitive(/null/.source),
lookbehind: true,
},
number: {
pattern: primitive(/[-+]?\d+(?:\.\d*)?/.source),
lookbehind: true,
},
classAttributes: {
pattern: primitive(/method|field/.source),
lookbehind: true,
},
punctuation: [
// open paren, brackets, and close paren
/(?:['`,]?\(|[)\[\]])/, //eslint-disable-line
],
};

const brewinV2 = {
...brewinV1,
primitiveTypes: {
pattern: primitive(/void|int|bool|string/.source),
lookbehind: true,
},
classRefs: {
pattern: primitive(/me|super/.source),
lookbehind: true,
},
};

const brewinV3 = {
...brewinV2,
class: {
pattern: primitive(/t?class/.source),
lookbehind: true,
alias: "class-name",
},
genericTypeConcatChar:{
pattern: RegExp(/@/.source),
lookbehind: true,
},
exceptionKeywords: {
pattern: RegExp(par + "try|throw\\s+"),
lookbehind: true,
},
};

export const S23_VERSIONS = [
{
version: "1",
quarter: "s23",
title: "brewin",
highlighter: brewinV1,
defaultProgram: `(class person
(field name "")
(field age 0)
Expand All @@ -27,6 +134,7 @@ export const S23_VERSIONS = [
version: "2",
quarter: "s23",
title: "brewin++",
highlighter: brewinV2,
defaultProgram: `(class main
(method int value_or_zero ((int q))
(begin
Expand All @@ -48,6 +156,7 @@ export const S23_VERSIONS = [
version: "3",
quarter: "s23",
title: "brewin##",
highlighter: brewinV3,
defaultProgram: `(tclass node (field_type)
(field node@field_type next null)
(field field_type value)
Expand Down

0 comments on commit cac8087

Please sign in to comment.