From 173dbc6e5d2951d7665afbbfa7945e17156d7a6d Mon Sep 17 00:00:00 2001 From: Jonathon Herbert Date: Tue, 29 Oct 2024 17:14:17 +0000 Subject: [PATCH] Add AST visualisation --- .../src/cqlInput/editor/debug.ts | 130 ++++++++++++++++-- .../src/cqlInput/editor/plugin.ts | 7 + prosemirror-client/src/style.css | 117 ++++++++++++++++ 3 files changed, 240 insertions(+), 14 deletions(-) diff --git a/prosemirror-client/src/cqlInput/editor/debug.ts b/prosemirror-client/src/cqlInput/editor/debug.ts index 8fb9f2d..72fc327 100644 --- a/prosemirror-client/src/cqlInput/editor/debug.ts +++ b/prosemirror-client/src/cqlInput/editor/debug.ts @@ -83,20 +83,20 @@ export const getDebugTokenHTML = (tokens: Token[]) => { }; export const getOriginalQueryHTML = (query: string) => ` -
-
- ${query - .split("") - .map( - (char, index) => ` -
-
${index}
-
${char}
-
` - ) - .join("")} -
-
`; +
+
+ ${query + .split("") + .map( + (char, index) => ` +
+
${index}
+
${char}
+
` + ) + .join("")} +
+
`; export const getDebugMappingHTML = ( query: string, @@ -186,3 +186,105 @@ export const getDebugMappingHTML = ( // return `
${queryDiagram}${nodeDiagram}
`; }; + +export const getDebugASTHTML = (query: QueryList) => { + return `
+ +
`; +}; + +const getContentHTML = (query: QueryContent) => { + const html = (() => { + switch (query.content.type) { + case "QueryBinary": + return getBinaryHTML(query.content); + case "QueryField": + return getFieldHTML(query.content); + case "QueryGroup": + return getGroupHTML(query.content); + case "QueryStr": + return getStrHTML(query.content); + } + })(); + + return ` + `; +}; + +const getBinaryHTML = (query: QueryBinary): string => { + return ` + + `; +}; + +const getFieldHTML = (field: QueryField) => { + return ` + + `; +}; + +const getTokenHTML = (token: Token) => { + return ` + ${token.tokenType} + ${token.literal} + ${token.start}‑${token.end} + + `; +}; + +const getGroupHTML = (group: QueryGroup) => { + return ` + + `; +}; + +const getStrHTML = (str: QueryStr) => { + return ` + + `; +}; + +const getNodeHTML = (node: { type: string }) => + `${node.type}`; diff --git a/prosemirror-client/src/cqlInput/editor/plugin.ts b/prosemirror-client/src/cqlInput/editor/plugin.ts index 4446ab1..dfe88ff 100644 --- a/prosemirror-client/src/cqlInput/editor/plugin.ts +++ b/prosemirror-client/src/cqlInput/editor/plugin.ts @@ -27,6 +27,7 @@ import { ErrorPopover } from "../ErrorPopover"; import { MappedTypeaheadSuggestion } from "../../lang/types"; import { CqlConfig } from "../CqlInput"; import { + getDebugASTHTML, getDebugMappingHTML, getDebugTokenHTML, getOriginalQueryHTML, @@ -342,6 +343,12 @@ export const createCqlPlugin = ({ ${getOriginalQueryHTML(query)}

Tokenises to:

${getDebugTokenHTML(result.tokens)} + ${ + result.ast + ? `

AST:

+ ${getDebugASTHTML(result.ast)}` + : "" + }

Maps to nodes:

${getDebugMappingHTML(query, mapping, newDoc)} `; diff --git a/prosemirror-client/src/style.css b/prosemirror-client/src/style.css index 5dda166..80ed611 100644 --- a/prosemirror-client/src/style.css +++ b/prosemirror-client/src/style.css @@ -213,3 +213,120 @@ input { background: none; color: rgba(255, 255, 255, 0.87); } + + +.tree--container { + display: flex; + align-items: center; + flex-direction: column; + width: 100%; +} + +.tree { + display: block; + max-width: 100%; + margin-top: 5px; + overflow-y: scroll; +} + + + + /*https://www.cssscript.com/clean-tree-diagram/*/ + .tree, + .tree ul, + .tree li { + font-family: monospace; + list-style: none; + margin: 0; + padding: 0; + position: relative; + } + + .tree { + margin: 0 0 1em; + text-align: center; + white-space: initial; + } + + .tree, + .tree ul { + display: table; + } + + .tree ul { + width: 100%; + } + + .tree li { + display: table-cell; + padding: .5rem 0; + vertical-align: top; + } + + .tree li:before { + outline: solid 0.5px #666; + content: ""; + left: 0; + position: absolute; + right: 0; + top: -1px; + } + + .tree li:first-child:before { + left: 50%; + } + + .tree li:last-child:before { + right: 50%; + } + + .tree code, + .tree li > span { + background-color: #4b6978; + border-radius: .2em; + display: inline-block; + margin: 0 .2em .5em; + padding: .2em .5em; + position: relative; + } + + .node-content { + background-color: rgb(71, 75, 86); + margin-left: 5px; + padding: 1px 5px; + } + + .node-pos { + line-break:normal; + padding: 0 4px; + } + + .tree ul:before, + .tree code:before, + .tree li > span:before { + outline: solid 0.5px #666; + content: ""; + height: .5em; + left: 50%; + position: absolute; + } + + .tree ul:before { + top: -.5em; + } + + .tree code:before, + .tree li > span:before { + top: -.55em; + } + + .tree>li { + margin-top: 0; + } + + .tree>li:before, + .tree>li:after, + .tree>li>code:before, + .tree>li>.span:before { + outline: none; + } \ No newline at end of file