ul done and dusted
This commit is contained in:
@@ -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) {
|
||||
|
@@ -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));
|
||||
}
|
||||
|
Reference in New Issue
Block a user