diff --git a/hugo/assets/scripts/minilogo/minilogo.tsx b/hugo/assets/scripts/minilogo/minilogo.tsx index c37802a1..016f2d30 100644 --- a/hugo/assets/scripts/minilogo/minilogo.tsx +++ b/hugo/assets/scripts/minilogo/minilogo.tsx @@ -19,6 +19,7 @@ let shouldAnimate = true; interface PreviewProps { commands?: Command[]; diagnostics?: Diagnostic[]; + hidden?: boolean; } interface DrawCanvasProps { @@ -157,11 +158,13 @@ class DrawCanvas extends React.Component { } class Preview extends React.Component { canvasRef: React.RefObject; + hidden: boolean; constructor(props: PreviewProps) { super(props); this.state = { commands: props.commands, diagnostics: props.diagnostics, + hidden: false, }; this.canvasRef = createRef(); this.startPreview = this.startPreview.bind(this); @@ -171,7 +174,24 @@ class Preview extends React.Component { this.setState({ commands, diagnostics }); } + hide() { + this.setState({ hidden: true }); + } + + show() { + this.setState({ hidden: false }); + } + + isHidden(): boolean { + return this.hidden; + } + render() { + if (this.props.hidden) { + return; + } + + // check if code contains an astNode if (!this.state.commands) { // Show the exception @@ -210,12 +230,15 @@ class Preview extends React.Component { interface AppState { currentExample: number; + currentWindow: 'preview' | 'editor'; } class App extends React.Component<{}, AppState> { monacoEditor: React.RefObject; preview: React.RefObject; copyHint: React.RefObject; shareButton: React.RefObject; + + constructor(props) { super(props); @@ -230,6 +253,7 @@ class App extends React.Component<{}, AppState> { this.state = { currentExample: 0, + currentWindow: 'editor' }; } @@ -306,32 +330,56 @@ class App extends React.Component<{}, AppState> {
- Editor + Editor
+
+ {/* Button to switch between preview and editor */} + +
Link was copied!
- +
+ +
+
+
+
-
+
Preview
- +
@@ -357,3 +405,4 @@ userConfig = createUserConfig({ }); const root = createRoot(document.getElementById("root") as HTMLElement); root.render(); + \ No newline at end of file diff --git a/hugo/content/playground/ForceGraph.tsx b/hugo/content/playground/ForceGraph.tsx new file mode 100644 index 00000000..9d8f0637 --- /dev/null +++ b/hugo/content/playground/ForceGraph.tsx @@ -0,0 +1,45 @@ +import { AstNode } from "langium"; +import { convertASTtoGraph } from "langium-ast-helper"; +import React from "react"; +import { ForceGraph3D } from "react-force-graph"; +import { toHex } from "./preprocess"; +import * as ReactDOM from "react-dom/client"; + +export let grammarRoot: ReactDOM.Root; + +export function renderForceGraph(grammar?: AstNode) { + const location = document.getElementById("forcegraph-root")!; + + if (!grammarRoot) { + // create a fresh root, if not already present + grammarRoot = ReactDOM.createRoot(location); + } + + if (grammar) { + // the follow code is taken from https://github.com/TypeFox/language-engineering-visualization/blob/main/packages/visuals/src/index.ts + const graphData = convertASTtoGraph(grammar); + const gData = { + nodes: graphData.nodes.map(node => ({ + id: (node as unknown as { $__dotID: string }).$__dotID, + nodeType: node.$type, + node + })), + links: graphData.edges.map(edge => ({ + source: (edge.from as unknown as { $__dotID: string }).$__dotID, + target: (edge.to as unknown as { $__dotID: string }).$__dotID + })) + }; + + return grammarRoot.render( + toHex((node as any).nodeType)} + nodeLabel={node => (node as any).node.name ? `${(node as any).nodeType} - ${(node as any).node.name}` : (node as any).nodeType} + /> + ); + + } +} \ No newline at end of file diff --git a/hugo/content/playground/Tree.tsx b/hugo/content/playground/Tree.tsx index 2b15c1fd..c17e1024 100644 --- a/hugo/content/playground/Tree.tsx +++ b/hugo/content/playground/Tree.tsx @@ -12,15 +12,19 @@ import { clsx } from "clsx"; import { AstNodeLocator } from "langium/lib/workspace/ast-node-locator"; export let treeRoot: ReactDOM.Root; +export type CurrentTreeWindow = "ast" | "grammar"; export function render(root: AstNode, locator: AstNodeLocator) { const location = document.getElementById("ast-body")!; const data = preprocessAstNodeObject(root, locator); + if (!treeRoot) { // create a fresh root, if not already present treeRoot = ReactDOM.createRoot(location); } - treeRoot.render( + + // generate the interactive tree + return treeRoot.render(
@@ -44,13 +48,13 @@ const TreeContent: FC = ({ root, hidden }) => { case "number": case "string": return ( - - {hidden - ? "..." - : root.kind === "string" + + {hidden + ? "..." + : root.kind === "string" ? '"' + root.value + '"' : root.value.toString()} - + ); case "object": return ( @@ -77,10 +81,10 @@ const TreeContent: FC = ({ root, hidden }) => { ); case "array": - if(root.children.length === 0) { + if (root.children.length === 0) { return {"[]"} } - if(hidden) { + if (hidden) { return {"[...]"} } return ( @@ -108,7 +112,7 @@ const TreeContent: FC = ({ root, hidden }) => { return ( <> {hidden ? {"Reference(...)"} : - Reference('{root.$text}')} + Reference('{root.$text}')} ); } @@ -125,6 +129,7 @@ const TreeNode: FC = ({ root, hidden }) => { function Property({ p, comma }: { p: PropertyNode; comma: boolean }) { const [open, setOpen] = useState(true); + return (
  • diff --git a/hugo/content/playground/_index.html b/hugo/content/playground/_index.html index d005d41b..f4a58aa3 100644 --- a/hugo/content/playground/_index.html +++ b/hugo/content/playground/_index.html @@ -10,11 +10,11 @@ noMain: true playground: true --- - - - + + +