Add Shakespeare esolang
This commit is contained in:
24
languages/shakespeare/renderer/character-row.tsx
Normal file
24
languages/shakespeare/renderer/character-row.tsx
Normal file
@ -0,0 +1,24 @@
|
||||
import { CharacterValue } from "../common";
|
||||
import { SimpleTag } from "./utils";
|
||||
|
||||
type Props = {
|
||||
name: string;
|
||||
value: CharacterValue;
|
||||
};
|
||||
|
||||
export const CharacterRow = (props: Props) => {
|
||||
const { name, value } = props;
|
||||
|
||||
return (
|
||||
<div style={{ margin: "20px 10px" }}>
|
||||
<div>
|
||||
<b style={{ marginRight: 5 }}>{name}:</b>{" "}
|
||||
<pre style={{ display: "inline" }}>{value.value}</pre>
|
||||
{value.stack.map((v, i) => (
|
||||
<SimpleTag key={i}>{v}</SimpleTag>
|
||||
))}
|
||||
</div>
|
||||
<div></div>
|
||||
</div>
|
||||
);
|
||||
};
|
63
languages/shakespeare/renderer/index.tsx
Normal file
63
languages/shakespeare/renderer/index.tsx
Normal file
@ -0,0 +1,63 @@
|
||||
import { Colors } from "@blueprintjs/core";
|
||||
import { RendererProps } from "../../types";
|
||||
import { RS } from "../common";
|
||||
import { CharacterRow } from "./character-row";
|
||||
import { TopBar } from "./topbar";
|
||||
|
||||
/** Common border color for dark and light, using transparency */
|
||||
export const BorderColor = Colors.GRAY3 + "55";
|
||||
|
||||
const styles = {
|
||||
placeholderDiv: {
|
||||
height: "100%",
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
fontSize: "1.2em",
|
||||
},
|
||||
rootContainer: {
|
||||
height: "100%",
|
||||
display: "flex",
|
||||
flexDirection: "column" as "column",
|
||||
},
|
||||
topBarContainer: {
|
||||
borderBottom: "1px solid " + BorderColor,
|
||||
padding: 10,
|
||||
},
|
||||
mainContainer: {
|
||||
flex: 1,
|
||||
minHeight: 0,
|
||||
overflowY: "auto" as "auto",
|
||||
},
|
||||
};
|
||||
|
||||
export const Renderer = ({ state }: RendererProps<RS>) => {
|
||||
if (state == null)
|
||||
return (
|
||||
<div style={styles.placeholderDiv}>Run some code to see the stage!</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<div style={styles.rootContainer}>
|
||||
<div style={styles.topBarContainer}>
|
||||
<TopBar
|
||||
charactersOnStage={state.charactersOnStage}
|
||||
currSpeaker={state.currentSpeaker}
|
||||
questionState={state.questionState}
|
||||
/>
|
||||
</div>
|
||||
<div style={styles.mainContainer}>
|
||||
{Object.keys(state.characterBag).map((name) => (
|
||||
<CharacterRow
|
||||
key={name}
|
||||
name={name}
|
||||
value={state.characterBag[name]}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
return null;
|
||||
};
|
56
languages/shakespeare/renderer/topbar.tsx
Normal file
56
languages/shakespeare/renderer/topbar.tsx
Normal file
@ -0,0 +1,56 @@
|
||||
import { Tag, Text } from "@blueprintjs/core";
|
||||
import { SimpleTag } from "./utils";
|
||||
|
||||
const styles = {
|
||||
charChip: {
|
||||
margin: "0 5px",
|
||||
},
|
||||
questionText: {
|
||||
marginLeft: 30,
|
||||
marginRight: 10,
|
||||
},
|
||||
};
|
||||
|
||||
type Props = {
|
||||
charactersOnStage: string[];
|
||||
currSpeaker: string | null;
|
||||
questionState: boolean | null;
|
||||
};
|
||||
|
||||
export const TopBar = (props: Props) => {
|
||||
const { charactersOnStage, currSpeaker, questionState } = props;
|
||||
|
||||
const characterChips =
|
||||
charactersOnStage.length === 0 ? (
|
||||
<Tag large minimal>
|
||||
The stage is empty
|
||||
</Tag>
|
||||
) : (
|
||||
charactersOnStage.map((character) => {
|
||||
return (
|
||||
<SimpleTag
|
||||
key={character}
|
||||
intent={character === currSpeaker ? "active" : undefined}
|
||||
>
|
||||
{character}
|
||||
</SimpleTag>
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
return (
|
||||
<div>
|
||||
{characterChips}
|
||||
{questionState != null && (
|
||||
<>
|
||||
<Text tagName="span" style={styles.questionText}>
|
||||
Answer to question:
|
||||
</Text>
|
||||
<SimpleTag intent={questionState ? "success" : "danger"}>
|
||||
{questionState ? "yes" : "no"}
|
||||
</SimpleTag>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
60
languages/shakespeare/renderer/utils.tsx
Normal file
60
languages/shakespeare/renderer/utils.tsx
Normal file
@ -0,0 +1,60 @@
|
||||
import { Colors } from "@blueprintjs/core";
|
||||
import { useDarkMode } from "../../../ui/providers/dark-mode-provider";
|
||||
|
||||
const backgroundColorsLight = {
|
||||
success: Colors.GREEN3,
|
||||
danger: Colors.RED3,
|
||||
plain: Colors.GRAY3,
|
||||
active: Colors.DARK_GRAY1,
|
||||
};
|
||||
|
||||
const backgroundColorsDark = {
|
||||
success: Colors.GREEN3,
|
||||
danger: Colors.RED3,
|
||||
plain: Colors.GRAY3,
|
||||
active: Colors.LIGHT_GRAY5,
|
||||
};
|
||||
|
||||
const foregroundColorsLight = {
|
||||
success: Colors.GREEN2,
|
||||
danger: Colors.RED2,
|
||||
plain: Colors.DARK_GRAY1,
|
||||
active: Colors.LIGHT_GRAY5,
|
||||
};
|
||||
|
||||
const foregroundColorsDark = {
|
||||
success: Colors.GREEN5,
|
||||
danger: Colors.RED5,
|
||||
plain: Colors.LIGHT_GRAY5,
|
||||
active: Colors.DARK_GRAY1,
|
||||
};
|
||||
|
||||
/**
|
||||
* Utility component that renders a tag similar to BlueprintJS tags, but underneath
|
||||
* is just a single span tag with no frills and high performance.
|
||||
*/
|
||||
export const SimpleTag = (props: {
|
||||
children: React.ReactNode;
|
||||
intent?: "success" | "danger" | "active";
|
||||
}) => {
|
||||
const { isDark } = useDarkMode();
|
||||
const intent = props.intent == null ? "plain" : props.intent;
|
||||
const backgroundMap = isDark ? backgroundColorsDark : backgroundColorsLight;
|
||||
const foregroundMap = isDark ? foregroundColorsDark : foregroundColorsLight;
|
||||
|
||||
return (
|
||||
<span
|
||||
style={{
|
||||
display: "inline-flex",
|
||||
margin: 5,
|
||||
padding: "5px 10px",
|
||||
borderRadius: 3,
|
||||
backgroundColor:
|
||||
backgroundMap[intent] + (intent === "active" ? "aa" : "55"),
|
||||
color: foregroundMap[intent],
|
||||
}}
|
||||
>
|
||||
{props.children}
|
||||
</span>
|
||||
);
|
||||
};
|
Reference in New Issue
Block a user