ul done and dusted

This commit is contained in:
2024-03-12 19:21:01 -06:00
parent 42a671d49d
commit d04e374231
4 changed files with 237 additions and 249 deletions

View File

@@ -21,7 +21,7 @@ export const TokenIdentifiers = new Map<string, {
const rendersContentOnly = true;
const rendersChildrenOnly = true;
TokenIdentifiers.set("card", {
rx: /\[{2}\n+(\n|.*?)\n+\]{2}/g,
rx: /\[{2}\n+([\s\S]*?)\n+\]{2}/g,
parse(s) {
return {
content: s.match(new RegExp(this.rx, ""))?.at(1) ||
@@ -47,6 +47,39 @@ TokenIdentifiers.set("code", {
};
},
});
TokenIdentifiers.set("list", {
rx: /^\s*-\s([\s\S]*?)\n\n/gm,
parse(s) {
return {
content: s.match(new RegExp(this.rx, ""))?.at(1) ||
"Unable to parse list",
raw: s,
metadata: {
initialDepth: s.replace("\n", "").split("-").at(0)?.length.toString() ||
"1",
},
type: "list",
uuid: crypto.randomUUID(),
rendersChildrenOnly,
};
},
});
TokenIdentifiers.set("list-item", {
rx: /^\s*-\s(.*?)$/gm,
parse(s) {
return {
content: s.match(new RegExp(this.rx, ""))?.at(1) ||
"Unable to parse list-item",
raw: s,
metadata: {
initialDepth: s.replace("\n", "").split("-").at(0)?.length.toString() ||
"1",
},
type: "list-item",
uuid: crypto.randomUUID(),
};
},
});
TokenIdentifiers.set("grid", {
rx: /(?:\[\])+\n+((?:.|\n)*?)\n+\/\[\]/g,
parse(s) {

View File

@@ -65,10 +65,38 @@ function buildAbstractSyntaxTree(markers: TokenMarker[]) {
contentToChildren(marker.token);
}
return markers.filter((m) => !m.parent);
// return markers;
// return markers.filter((m) => !m.parent);
return markers;
}
// function establishClosestParent(blocks: TokenMarker[]): void {
// blocks.sort((a, b) => a.start - b.start); // Sort blocks by start position
// for (let i = 0; i < blocks.length; i++) {
// const block = blocks[i];
// if (block.parent) continue; // Skip blocks that already have a parent
// let closestParent: TokenMarker | undefined = undefined;
// let minDistance = Number.MAX_SAFE_INTEGER;
// // Find the closest parent block for each block
// for (let j = 0; j < i; j++) {
// const otherBlock = blocks[j];
// if (otherBlock.end >= block.start && otherBlock.start <= block.start) {
// const distance = block.start - otherBlock.start;
// if (distance < minDistance) {
// minDistance = distance;
// closestParent = otherBlock;
// }
// }
// }
// if (closestParent) {
// block.parent = closestParent; // Assign the closest parent block
// }
// }
// }
function establishClosestParent(blocks: TokenMarker[]): void {
blocks.sort((a, b) => a.start - b.start); // Sort blocks by start position
@@ -84,7 +112,10 @@ function establishClosestParent(blocks: TokenMarker[]): void {
const otherBlock = blocks[j];
if (otherBlock.end >= block.start && otherBlock.start <= block.start) {
const distance = block.start - otherBlock.start;
if (distance < minDistance) {
if (
distance < minDistance &&
isAcceptableChild(otherBlock.type, block.type)
) {
minDistance = distance;
closestParent = otherBlock;
}
@@ -97,6 +128,20 @@ function establishClosestParent(blocks: TokenMarker[]): void {
}
}
type ParentChildMap = {
[parentType: string]: string[]; // Map parent types to an array of acceptable child types
};
const parentChildMap: ParentChildMap = {
"list": ["list-item"],
// Add more mappings as needed...
};
function isAcceptableChild(parentType: string, childType: string): boolean {
const acceptableChildren = parentChildMap[parentType];
return acceptableChildren ? acceptableChildren.includes(childType) : true;
}
function filterOverlappingPBlocks(blocks: TokenMarker[]): TokenMarker[] {
return blocks.filter((block) => {
if (block.type !== "p") {
@@ -122,6 +167,10 @@ function filterOverlappingPBlocks(blocks: TokenMarker[]): TokenMarker[] {
const contentToChildren = (token: Token) => {
let content = token.content;
const wasSpecialCase = handleSpecial(token);
if (wasSpecialCase) return;
const splitMarker = "{{^^}}";
for (const child of token.children || []) {
content = content.replace(child.raw, splitMarker);
@@ -139,3 +188,79 @@ const contentToChildren = (token: Token) => {
token.children || [],
).filter((c) => c.children?.length || (c.rendersContentOnly && c.content));
};
function handleSpecial(token: Token) {
switch (token.type) {
case "list": {
const chunks = splitByDepth(token.children!);
const items = processChunks(chunks);
token.children = items.flat();
return token.children;
}
default:
return;
}
}
function splitByDepth(items: Token[]) {
const chunks: Token[][] = [];
let currentDepth = -1;
let chunk: Token[] = [];
if (!items) return chunks;
for (const item of items) {
const depth = Number(item.metadata.initialDepth);
if (depth === currentDepth) {
chunk.push(item);
} else {
if (chunk.length > 0) {
chunks.push(chunk);
}
chunk = [item];
currentDepth = depth;
}
}
if (chunk.length > 0) {
chunks.push(chunk);
}
return chunks;
}
function processChunks(chunks: Token[][]) {
const mergedChunks: Token[][] = [];
for (let i = 1; i < chunks.length; i++) {
const currentChunk = chunks[i];
let j = i - 1;
// Find the first chunk with a lower depth
while (j >= 0) {
const prevChunk = chunks[j];
const prevDepth = Number(prevChunk[0].metadata.initialDepth);
if (prevDepth < Number(currentChunk[0].metadata.initialDepth)) {
// Append the current chunk to the children of the found chunk
const lastPrev = prevChunk[prevChunk.length - 1];
lastPrev.children = lastPrev.children || [];
lastPrev.children.push({
type: "list",
content: "",
raw: "",
metadata: { initialDepth: currentChunk[0].metadata.initialDepth },
uuid: crypto.randomUUID(),
children: currentChunk,
});
mergedChunks.push(currentChunk);
break;
}
j--;
}
}
// console.log(chunks);
// Filter out chunks that were merged into others
return chunks.filter((c) => !mergedChunks.find((c2) => c === c2));
}