ttcMD: made card (regrettably) nestable to allow them in code blocks inside of cards

This commit is contained in:
Emmaline Autumn 2024-03-13 00:30:59 -06:00
parent 23cf8c263d
commit 009e988a38
4 changed files with 90 additions and 56 deletions

View File

@ -14,9 +14,7 @@ export const TTCMD: FC<{ body: Promise<string> }> = ({ body }) => {
const text = use(body); const text = use(body);
const [elements, tabSpacing] = useMemo(() => createElements(text), [text]); const [elements, tabSpacing] = useMemo(() => createElements(text), [text]);
const tada = useMemo( const tada = useMemo(
() => ( () => <>{renderer(elements.map((e) => e.token))}</>,
<>{renderer(elements.filter((e) => !e.parent).map((e) => e.token!))}</>
),
[elements], [elements],
); );
return ( return (

View File

@ -31,12 +31,45 @@ export const TokenIdentifiers = new Map<
// }); // });
const rendersContentOnly = true; const rendersContentOnly = true;
const rendersChildrenOnly = true; const rendersChildrenOnly = true;
TokenIdentifiers.set("grid", {
search(s, start, end) {
const rx = /(?<!\/)(?:\[\])+/g;
const closeRx = /\/\[\]/g;
return search(s, start, end, rx, closeRx);
},
rx: /(?:\[\])+\n+((?:.|\n)*?)\n+\/\[\]/g,
parse(s) {
const rx = /((?:\[\])+)\n+([\s\S]*)\n+\/\[\]/;
const [_, columns, content] = s.match(rx) ||
["", "..", "Unable to parse grid"];
return {
content,
raw: s,
metadata: {
columns: (columns.length / 2).toString(),
},
type: "grid",
uuid: crypto.randomUUID(),
rendersChildrenOnly,
};
},
});
TokenIdentifiers.set("card", { TokenIdentifiers.set("card", {
rx: /\[{2}\n+([\s\S]*?)\n+\]{2}/g, rx: /\[{2}\n+([\s\S]*?)\n+\]{2}/g,
search(s, start, end) {
const rx = /\[\[/g;
const crx = /\]\]/g;
return search(s, start, end, rx, crx);
},
parse(s) { parse(s) {
console.log(s);
const rx = /\[{2}\n+([\s\S]*)\n+\]{2}/;
const [_, content] = s.match(rx) || ["", "Unable to parse card"];
return { return {
content: s.match(new RegExp(this.rx, ""))?.at(1) || content: content.trim(),
"Unable to parse card",
raw: s, raw: s,
metadata: {}, metadata: {},
type: "card", type: "card",
@ -91,52 +124,6 @@ TokenIdentifiers.set("list-item", {
}; };
}, },
}); });
TokenIdentifiers.set("grid", {
search(s, start, end) {
const rx = /(?<!\/)(?:\[\])+/g;
const closeRx = /\/\[\]/g;
const oldEnd = end;
const newEnd = findMatchingClosedParenthesis(
s,
rx,
closeRx,
);
if (newEnd === null) throw Error("BAD BAD BAD BAD");
end = newEnd + start;
return {
start,
end,
text: s.substring(0, newEnd),
lastIndex: oldEnd === end
? end
: start + s.match(new RegExp(rx))![0].length,
};
},
rx: /(?:\[\])+\n+((?:.|\n)*?)\n+\/\[\]/g,
parse(s) {
const rx = /((?:\[\])+)\n+([\s\S]*)\n+\/\[\]/;
console.log(s);
const [_, columns, content] = s.match(rx) ||
["", "..", "Unable to parse grid"];
console.log(columns);
return {
content,
raw: s,
metadata: {
columns: (columns.length / 2).toString(),
},
type: "grid",
uuid: crypto.randomUUID(),
rendersChildrenOnly,
};
},
});
TokenIdentifiers.set("heading", { TokenIdentifiers.set("heading", {
rx: /^#+\s(.*?)$/gm, rx: /^#+\s(.*?)$/gm,
parse(s) { parse(s) {
@ -310,7 +297,6 @@ function findMatchingClosedParenthesis(
let lastOpeningSuccessIndex = 0; let lastOpeningSuccessIndex = 0;
let lastClosingSuccessIndex = 0; let lastClosingSuccessIndex = 0;
debugger;
do { do {
const openingMatch = openRegex.exec(str); const openingMatch = openRegex.exec(str);
const closingMatch = closedRegex.exec(str); const closingMatch = closedRegex.exec(str);
@ -341,3 +327,37 @@ function findMatchingClosedParenthesis(
return closedRegex.lastIndex; return closedRegex.lastIndex;
} }
interface SearchResult {
start: number;
end: number;
text: string;
lastIndex: number;
}
function search(
s: string,
start: number,
end: number,
openRx: RegExp,
closeRx: RegExp,
): SearchResult {
const oldEnd = end;
const newEnd = findMatchingClosedParenthesis(
s,
openRx,
closeRx,
);
if (newEnd === null) throw Error("BAD BAD BAD BAD");
end = newEnd + start;
return {
start,
end,
text: s.substring(0, newEnd),
lastIndex: oldEnd === end ? end : start + s.match(openRx)![0].length,
};
}

View File

@ -78,8 +78,8 @@ function buildAbstractSyntaxTree(markers: TokenMarker[]) {
contentToChildren(marker.token); contentToChildren(marker.token);
} }
// return markers.filter((m) => !m.parent); return markers.filter((m) => !m.parent);
return markers; // return markers;
} }
function establishClosestParent(blocks: TokenMarker[]): void { function establishClosestParent(blocks: TokenMarker[]): void {
@ -159,6 +159,7 @@ const contentToChildren = (token: Token) => {
const splitMarker = "{{^^}}"; const splitMarker = "{{^^}}";
for (const child of token.children || []) { for (const child of token.children || []) {
if (token.type === "card" && child.type === "code") debugger;
content = content.replace(child.raw, splitMarker); content = content.replace(child.raw, splitMarker);
} }
@ -183,6 +184,8 @@ function handleSpecial(token: Token) {
token.children = items.flat(); token.children = items.flat();
return token.children; return token.children;
} }
// case "grid":
// return token.children;
default: default:
return; return;
} }

View File

@ -1,7 +1,7 @@
# TEST
[][][] [][][]
[[
```
[][][] [][][]
This will make three columns, just like how this is laid out right now. This will make three columns, just like how this is laid out right now.
@ -11,17 +11,30 @@ Each element will get its own cell in the grid.
So each of these paragraphs will end up in a separate column. So each of these paragraphs will end up in a separate column.
/[] /[]
```
]]
[[
```
[][] [][]
This will make two columns This will make two columns
[[
Each column can use a different element Each column can use a different element
]]
/[] /[]
```
]]
[[
This card will end up in the third column... This card will end up in the third column...
]]
[[
... but since there isn't enough for this one, it will automatically get moved to the next row. ... but since there isn't enough for this one, it will automatically get moved to the next row.
]]
/[] /[]