MD handlers for resolvers
This commit is contained in:
55
lib/tcmd/Resolver.tsx
Normal file
55
lib/tcmd/Resolver.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
import { PublicationAtom } from "@/recoil/atoms/publication";
|
||||
import { useState, useEffect, useCallback, useRef } from "react";
|
||||
import { useRecoilValue } from "recoil";
|
||||
import { TTCQueryResolver } from "../ttcQuery/TTCResolvers";
|
||||
|
||||
export function Resolver({ resolver }: { resolver: string }) {
|
||||
const parser = useRecoilValue(PublicationAtom);
|
||||
const [res] = useState(new TTCQueryResolver(parser));
|
||||
const [content, setContent] = useState("");
|
||||
useEffect(() => {
|
||||
setContent(res.resolve(resolver));
|
||||
}, [resolver, res]);
|
||||
return <span>{content}</span>;
|
||||
}
|
||||
|
||||
export function OnDemandResolver({
|
||||
resolver,
|
||||
template,
|
||||
title,
|
||||
}: {
|
||||
resolver: string;
|
||||
template: string;
|
||||
title?: string;
|
||||
}) {
|
||||
const parser = useRecoilValue(PublicationAtom);
|
||||
const res = useRef(new TTCQueryResolver(parser));
|
||||
const [content, setContent] = useState("");
|
||||
const generateContent = useCallback(() => {
|
||||
let content = template;
|
||||
const stackIdxs = Array.from(new Set(template.match(/\$\d/g)));
|
||||
for (const idx of stackIdxs) {
|
||||
let thing = res.current.getFromStack(idx);
|
||||
debugger;
|
||||
if (Array.isArray(thing)) thing = thing.at(0);
|
||||
if (typeof thing === "function") thing = thing();
|
||||
content = content.replaceAll(idx, thing as string);
|
||||
}
|
||||
setContent(content);
|
||||
}, [res, template]);
|
||||
|
||||
const resolve = useCallback(() => {
|
||||
res.current.resolve(resolver, true);
|
||||
generateContent();
|
||||
}, [res, resolver, generateContent]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<button onMouseDown={() => setContent("")} onClick={resolve}>
|
||||
{title ?? "Resolve"}
|
||||
</button>
|
||||
<br />
|
||||
{!!content && <span>{content}</span>}
|
||||
</>
|
||||
);
|
||||
}
|
@@ -3,6 +3,7 @@ import Link from "next/link";
|
||||
import React, { Fragment } from "react";
|
||||
import { Poppable } from "../poppables/components/poppable";
|
||||
import { Accordion, AccordionContent } from "../accordion";
|
||||
import { OnDemandResolver, Resolver } from "./Resolver";
|
||||
|
||||
export const TokenRenderers = new Map<string, TokenRenderer<any>>();
|
||||
|
||||
@@ -123,7 +124,7 @@ export const buildOnlyDefaultElements = () => {
|
||||
</div>
|
||||
);
|
||||
},
|
||||
/(?<!\/)(?:\[\])+/g,
|
||||
/(?<![\/\?])(?:\[\])+/g,
|
||||
/\/\[\]/g
|
||||
);
|
||||
|
||||
@@ -517,6 +518,7 @@ export const buildOnlyDefaultElements = () => {
|
||||
}
|
||||
);
|
||||
|
||||
// accordion
|
||||
registerIdentifier(
|
||||
"accordion",
|
||||
/\[accordion(\s.*?)?]\n+((?:.|\n)*?)\n+\[\/accordion\]/g,
|
||||
@@ -546,6 +548,7 @@ export const buildOnlyDefaultElements = () => {
|
||||
}
|
||||
);
|
||||
|
||||
// paragraph
|
||||
registerIdentifier(
|
||||
"p",
|
||||
/(?<=\n\n)([\s\S]*?)(?=\n\n)/g,
|
||||
@@ -570,6 +573,7 @@ export const buildOnlyDefaultElements = () => {
|
||||
}
|
||||
);
|
||||
|
||||
// horizontal rule
|
||||
registerIdentifier(
|
||||
"hr",
|
||||
/^-{3,}$/gm,
|
||||
@@ -587,6 +591,7 @@ export const buildOnlyDefaultElements = () => {
|
||||
}
|
||||
);
|
||||
|
||||
// comment
|
||||
registerIdentifier(
|
||||
"comment",
|
||||
/<!--[\s\S]+?-->/g,
|
||||
@@ -604,6 +609,7 @@ export const buildOnlyDefaultElements = () => {
|
||||
}
|
||||
);
|
||||
|
||||
// frontmatter
|
||||
registerIdentifier(
|
||||
"frontmatter",
|
||||
/^---([\s\S]*?)---/g,
|
||||
@@ -622,6 +628,7 @@ export const buildOnlyDefaultElements = () => {
|
||||
}
|
||||
);
|
||||
|
||||
// table
|
||||
registerIdentifier(
|
||||
"table",
|
||||
/(?<=\n|^)\| [\s\S]*? \|(?=(\n|$)(?!\|))/g,
|
||||
@@ -767,6 +774,75 @@ export const buildOnlyDefaultElements = () => {
|
||||
}
|
||||
);
|
||||
|
||||
// resolver
|
||||
registerIdentifier(
|
||||
"resolver",
|
||||
/\?\?<<(.*?)>>/g,
|
||||
(s) => {
|
||||
const inp = s.match(/(?<=<<)(.*?)(?=>>)/)![0];
|
||||
if (inp == undefined)
|
||||
return {
|
||||
content: "Error parsing resolver: " + s,
|
||||
metadata: {},
|
||||
raw: "ERROR",
|
||||
uuid: crypto.randomUUID(),
|
||||
};
|
||||
return {
|
||||
content: inp,
|
||||
metadata: {},
|
||||
raw: s,
|
||||
uuid: crypto.randomUUID(),
|
||||
};
|
||||
},
|
||||
(t) => {
|
||||
if (t.content.startsWith("Error"))
|
||||
return <span className="red-500">{t.content}</span>;
|
||||
return <Resolver resolver={t.content} />;
|
||||
}
|
||||
);
|
||||
|
||||
// on-demand resolver
|
||||
registerIdentifier(
|
||||
"on-demand resolver",
|
||||
/\?\?\[.*?\](\(.*?\))?<<(.*?)>>/g,
|
||||
(s) => {
|
||||
const inp = s.match(/(?<=<<)(.*?)(?=>>)/)![0];
|
||||
const template = s.match(/(?<=\?\?\[)(.*?)(?=\])/)![0];
|
||||
const title = s.match(/(?<=\]\()(.*?)(?=\))/)?.at(0);
|
||||
if (inp == undefined)
|
||||
return {
|
||||
content: "Error parsing resolver: " + s,
|
||||
metadata: {
|
||||
title: "",
|
||||
template: "",
|
||||
},
|
||||
raw: "ERROR",
|
||||
uuid: crypto.randomUUID(),
|
||||
};
|
||||
return {
|
||||
content: inp,
|
||||
metadata: {
|
||||
title,
|
||||
template,
|
||||
},
|
||||
raw: s,
|
||||
uuid: crypto.randomUUID(),
|
||||
};
|
||||
},
|
||||
(t) => {
|
||||
if (t.content.startsWith("Error"))
|
||||
return <span className="red-500">{t.content}</span>;
|
||||
|
||||
return (
|
||||
<OnDemandResolver
|
||||
resolver={t.content}
|
||||
template={t.metadata.template}
|
||||
title={t.metadata.title}
|
||||
/>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
return TokenIdentifiers;
|
||||
};
|
||||
|
||||
@@ -840,7 +916,8 @@ function search(
|
||||
closeRx
|
||||
);
|
||||
|
||||
if (newEnd === null) throw Error("There was an issue finding a closing tag");
|
||||
if (newEnd === null)
|
||||
throw Error("There was an issue finding a closing tag for ");
|
||||
|
||||
end = newEnd + start;
|
||||
|
||||
|
@@ -5,7 +5,6 @@ import { buildOnlyDefaultElements, TokenRenderers } from "./TokenIdentifiers";
|
||||
|
||||
export const createElements = (body: string): Token[] => {
|
||||
const tokens = tokenize(body);
|
||||
console.log(tokens);
|
||||
return buildAbstractSyntaxTree(tokens).map((t) => t.token);
|
||||
};
|
||||
|
||||
|
@@ -147,13 +147,3 @@ export class TTCQueryParser {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Example usage:
|
||||
// const
|
||||
|
||||
// const parser = new TTCQueryParser(data);
|
||||
|
||||
// // Example queries
|
||||
// console.log(parser.search("$weapon_abilities[name=Rapid Fire].body")); // Example output
|
||||
// // console.log(parser.search("^weapon_abilities[name=Rapid Fire]", data)); // Example output
|
||||
// console.log(parser.search("$weapon_abilities[name=Rapid Fire].body", data)); // Example output
|
||||
|
@@ -26,12 +26,14 @@ export class TTCQueryResolver {
|
||||
}
|
||||
const last = this.stack.at(-1);
|
||||
if (typeof last === "function" && !onDemand) return last();
|
||||
|
||||
if (onDemand) debugger;
|
||||
return last;
|
||||
}
|
||||
|
||||
private parseResolver(resolver: string) {
|
||||
if (this.isArithmetic(resolver)) return this.solveArithmetic(resolver);
|
||||
if (this.isQuery(resolver)) this.runQuery(resolver);
|
||||
if (this.isQuery(resolver)) return this.runQuery(resolver);
|
||||
}
|
||||
private isQuery(resolver: string) {
|
||||
return (
|
||||
@@ -56,15 +58,15 @@ export class TTCQueryResolver {
|
||||
|
||||
// if (query.startsWith("?") || query.startsWith("_"))
|
||||
return query.startsWith("_") && this.context
|
||||
? this.parser.search(query.replace("_", ""), this.context)
|
||||
: this.parser.search(query.replace(/^[?_].?/, ""));
|
||||
? this.parser.search(query.replace("_", "^"), this.context).at(0)
|
||||
: this.parser.search(query.replace(/^[?_].?/, "")).at(0);
|
||||
}
|
||||
|
||||
private handleDice(dice: string, query: string) {
|
||||
const d = new Dice(dice);
|
||||
const [method, n] = query.split(":");
|
||||
let num = Number(n);
|
||||
if (n.startsWith("$")) num = this.getFromStack(n);
|
||||
if (n && n.startsWith("$")) num = this.getFromStack(n);
|
||||
switch (method) {
|
||||
case "roll":
|
||||
return () => d.roll();
|
||||
@@ -91,7 +93,6 @@ export class TTCQueryResolver {
|
||||
|
||||
if (n1.startsWith("$")) num1 = this.getFromStack<number>(n1);
|
||||
if (n2.startsWith("$")) num2 = this.getFromStack<number>(n2);
|
||||
console.log(num1, num2);
|
||||
|
||||
switch (op) {
|
||||
case "+":
|
||||
@@ -109,7 +110,7 @@ export class TTCQueryResolver {
|
||||
}
|
||||
}
|
||||
|
||||
private getFromStack<T>(stackIndex: string): T {
|
||||
public getFromStack<T>(stackIndex: string): T {
|
||||
const i = Number(stackIndex.replace("$", ""));
|
||||
const val = this.stack[i] as T;
|
||||
return val;
|
||||
|
Reference in New Issue
Block a user