Skip to content

Commit

Permalink
Add AST visualisation
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathonherbert committed Oct 29, 2024
1 parent f164387 commit 173dbc6
Show file tree
Hide file tree
Showing 3 changed files with 240 additions and 14 deletions.
130 changes: 116 additions & 14 deletions prosemirror-client/src/cqlInput/editor/debug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,20 +83,20 @@ export const getDebugTokenHTML = (tokens: Token[]) => {
};

export const getOriginalQueryHTML = (query: string) => `
<div class="CqlDebug__queryDiagram">
<div class="CqlDebug__queryDiagramContent">
${query
.split("")
.map(
(char, index) => `
<div class="CqlDebug__queryBox">
<div class="CqlDebug__queryIndex">${index}</div>
<div class="CqlDebug__queryChar">${char}</div>
</div>`
)
.join("")}
</div>
</div>`;
<div class="CqlDebug__queryDiagram">
<div class="CqlDebug__queryDiagramContent">
${query
.split("")
.map(
(char, index) => `
<div class="CqlDebug__queryBox">
<div class="CqlDebug__queryIndex">${index}</div>
<div class="CqlDebug__queryChar">${char}</div>
</div>`
)
.join("")}
</div>
</div>`;

export const getDebugMappingHTML = (
query: string,
Expand Down Expand Up @@ -186,3 +186,105 @@ export const getDebugMappingHTML = (

// return `<div class="CqlDebug__mapping">${queryDiagram}${nodeDiagram}</div>`;
};

export const getDebugASTHTML = (query: QueryList) => {
return `<div class="tree--container">
<ul class="tree">
<li>
${getNodeHTML(query)}
<ul>
${query.content
.map((binary) => `<li>${getBinaryHTML(binary)}</li>`)
.join("")}
</ul>
<li>
</ul>
</div>`;
};

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 `
<ul>
<li>
<span>${getNodeHTML(query)}</span>
${html}
</li>
</ul>`;
};

const getBinaryHTML = (query: QueryBinary): string => {
return `
<ul>
<li>
<span>${getNodeHTML(query)}</span>
<ul>
<li>${getContentHTML(query.left)}</li>
${query.right?.[1] ? `<li>${getBinaryHTML(query.right[1])}</li>` : ""}
</ul>
</li>
</ul>
`;
};

const getFieldHTML = (field: QueryField) => {
return `
<ul>
<li>
<span>${getNodeHTML(field)}</span>
<ul>
<li>${getTokenHTML(field.key)}</li>
${field.value ? `<li>${getTokenHTML(field.value)}</li>` : ""}
</ul>
</ul>
`;
};

const getTokenHTML = (token: Token) => {
return `
<span>${token.tokenType}
<span class="node-content">${token.literal}</span>
<span class="node-pos">${token.start}${token.end}</span>
</span>
`;
};

const getGroupHTML = (group: QueryGroup) => {
return `
<ul>
<li>
${getNodeHTML(group)}
${getBinaryHTML(group.content)}
</li>
</ul>
`;
};

const getStrHTML = (str: QueryStr) => {
return `
<ul>
<li>
<span>
${getNodeHTML(str)}
<span class="node-content">${str.searchExpr}</span>
<span class="node-pos">${str.token.start}${str.token.end}</span>
</span>
</li>
</ul>
`;
};

const getNodeHTML = (node: { type: string }) =>
`<span class="node-description">${node.type}</span>`;
7 changes: 7 additions & 0 deletions prosemirror-client/src/cqlInput/editor/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { ErrorPopover } from "../ErrorPopover";
import { MappedTypeaheadSuggestion } from "../../lang/types";
import { CqlConfig } from "../CqlInput";
import {
getDebugASTHTML,
getDebugMappingHTML,
getDebugTokenHTML,
getOriginalQueryHTML,
Expand Down Expand Up @@ -342,6 +343,12 @@ export const createCqlPlugin = ({
${getOriginalQueryHTML(query)}
<p>Tokenises to:</p>
${getDebugTokenHTML(result.tokens)}
${
result.ast
? `<p>AST: </p>
${getDebugASTHTML(result.ast)}`
: ""
}
<p>Maps to nodes: </p>
${getDebugMappingHTML(query, mapping, newDoc)}
`;
Expand Down
117 changes: 117 additions & 0 deletions prosemirror-client/src/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

0 comments on commit 173dbc6

Please sign in to comment.