Browse Source

fix parsing structure

master
limina1 6 months ago
parent
commit
c552f606ae
  1. 249
      src/lib/utils/publication_tree_processor.ts

249
src/lib/utils/publication_tree_processor.ts

@ -522,6 +522,7 @@ function buildLevel2Structure( @@ -522,6 +522,7 @@ function buildLevel2Structure(
/**
* Build hierarchical structure for Level 3+: Mix of 30040 and 30041 events
* NKBIP-01: Sections with children become BOTH 30040 indices AND 30041 content events
*/
function buildHierarchicalStructure(
segments: ContentSegment[],
@ -540,64 +541,27 @@ function buildHierarchicalStructure( @@ -540,64 +541,27 @@ function buildHierarchicalStructure(
const eventStructure: EventStructureNode[] = [];
// Add root index to structure
eventStructure.push({
const rootNode: EventStructureNode = {
title,
level: 1,
eventType: "index",
eventKind: 30040,
dTag: generateDTag(title),
children: [],
});
// Build hierarchical structure
const hierarchy = buildSegmentHierarchy(segments);
for (const level2Section of hierarchy) {
if (level2Section.hasChildren) {
// Create 30040 for level 2 section with children
const level2Index = createIndexEventForSection(level2Section, ndk);
contentEvents.push(level2Index);
const level2Node: EventStructureNode = {
title: level2Section.title,
level: level2Section.level,
eventType: "index",
eventKind: 30040,
dTag: generateDTag(level2Section.title),
children: [],
};
eventStructure.push(rootNode);
// Add children as 30041 content events
for (const child of level2Section.children) {
const childEvent = createContentEvent(child, ndk);
contentEvents.push(childEvent);
level2Node.children.push({
title: child.title,
level: child.level,
eventType: "content",
eventKind: 30041,
dTag: generateDTag(child.title),
children: [],
});
}
eventStructure[0].children.push(level2Node);
} else {
// Create 30041 for level 2 section without children
const contentEvent = createContentEvent(level2Section, ndk);
contentEvents.push(contentEvent);
// Build hierarchical segment groups based on parse level
const hierarchicalGroups = buildHierarchicalGroups(segments, parseLevel);
eventStructure[0].children.push({
title: level2Section.title,
level: level2Section.level,
eventType: "content",
eventKind: 30041,
dTag: generateDTag(level2Section.title),
children: [],
});
}
}
// Process each group recursively
processHierarchicalGroup(
hierarchicalGroups,
rootNode,
contentEvents,
ndk,
parseLevel
);
return { tree, indexEvent, contentEvents, eventStructure };
}
@ -845,6 +809,193 @@ function groupSegmentsByLevel2(segments: ContentSegment[]): ContentSegment[] { @@ -845,6 +809,193 @@ function groupSegmentsByLevel2(segments: ContentSegment[]): ContentSegment[] {
return level2Groups;
}
/**
* Build hierarchical groups for proper event generation
* This creates a tree structure that reflects which sections should become indices vs content
*/
function buildHierarchicalGroups(
segments: ContentSegment[],
parseLevel: number
): HierarchicalNode[] {
const groups: HierarchicalNode[] = [];
// Group segments by their parent-child relationships
const segmentsByLevel: Map<number, ContentSegment[]> = new Map();
for (let level = 2; level <= parseLevel; level++) {
segmentsByLevel.set(level, segments.filter(s => s.level === level));
}
// Build the hierarchy from level 2 down to parseLevel
for (const segment of segmentsByLevel.get(2) || []) {
const node = buildNodeHierarchy(segment, segments, parseLevel);
groups.push(node);
}
return groups;
}
/**
* Build a hierarchical node for a segment and its descendants
*/
function buildNodeHierarchy(
segment: ContentSegment,
allSegments: ContentSegment[],
parseLevel: number
): HierarchicalNode {
// Find direct children (one level deeper)
const directChildren = allSegments.filter(s => {
if (s.level !== segment.level + 1) return false;
if (s.startLine <= segment.startLine) return false;
// Check if this segment is within our section's bounds
const nextSibling = allSegments.find(
next => next.level <= segment.level && next.startLine > segment.startLine
);
const endLine = nextSibling?.startLine || Infinity;
return s.startLine < endLine;
});
// Recursively build child nodes
const childNodes: HierarchicalNode[] = [];
for (const child of directChildren) {
if (child.level < parseLevel) {
// This child might have its own children
childNodes.push(buildNodeHierarchy(child, allSegments, parseLevel));
} else {
// This is a leaf node at parse level
childNodes.push({
segment: child,
children: [],
hasChildren: false
});
}
}
return {
segment,
children: childNodes,
hasChildren: childNodes.length > 0
};
}
interface HierarchicalNode {
segment: ContentSegment;
children: HierarchicalNode[];
hasChildren: boolean;
}
/**
* Process hierarchical groups to generate events
*/
function processHierarchicalGroup(
nodes: HierarchicalNode[],
parentStructureNode: EventStructureNode,
contentEvents: NDKEvent[],
ndk: NDK,
parseLevel: number
): void {
for (const node of nodes) {
if (node.hasChildren && node.segment.level < parseLevel) {
// This section has children and is not at parse level
// Create BOTH an index event AND a content event
// 1. Create the index event (30040)
const indexEvent = createIndexEventForHierarchicalNode(node, ndk);
contentEvents.push(indexEvent);
// 2. Create the content event (30041) for the section's own content
const contentEvent = createContentEvent(node.segment, ndk);
contentEvents.push(contentEvent);
// 3. Add index node to structure
const indexNode: EventStructureNode = {
title: node.segment.title,
level: node.segment.level,
eventType: "index",
eventKind: 30040,
dTag: generateDTag(node.segment.title),
children: [],
};
parentStructureNode.children.push(indexNode);
// 4. Add content node as first child of index
indexNode.children.push({
title: node.segment.title,
level: node.segment.level,
eventType: "content",
eventKind: 30041,
dTag: generateDTag(node.segment.title),
children: [],
});
// 5. Process children recursively
processHierarchicalGroup(
node.children,
indexNode,
contentEvents,
ndk,
parseLevel
);
} else {
// This is either a leaf node or at parse level - just create content event
const contentEvent = createContentEvent(node.segment, ndk);
contentEvents.push(contentEvent);
parentStructureNode.children.push({
title: node.segment.title,
level: node.segment.level,
eventType: "content",
eventKind: 30041,
dTag: generateDTag(node.segment.title),
children: [],
});
}
}
}
/**
* Create a 30040 index event for a hierarchical node
*/
function createIndexEventForHierarchicalNode(
node: HierarchicalNode,
ndk: NDK
): NDKEvent {
const event = new NDKEvent(ndk);
event.kind = 30040;
event.created_at = Math.floor(Date.now() / 1000);
event.pubkey = ndk.activeUser?.pubkey || "preview-placeholder-pubkey";
const dTag = generateDTag(node.segment.title);
const [mTag, MTag] = getMimeTags(30040);
const tags: string[][] = [["d", dTag], mTag, MTag, ["title", node.segment.title]];
// Add section attributes as tags
addSectionAttributesToTags(tags, node.segment.attributes);
// Add a-tags for the section's own content event
tags.push(["a", `30041:${event.pubkey}:${dTag}`]);
// Add a-tags for each child section
for (const child of node.children) {
const childDTag = generateDTag(child.segment.title);
if (child.hasChildren && child.segment.level < node.segment.level + 1) {
// Child will be an index
tags.push(["a", `30040:${event.pubkey}:${childDTag}`]);
} else {
// Child will be content
tags.push(["a", `30041:${event.pubkey}:${childDTag}`]);
}
}
event.tags = tags;
event.content = ""; // NKBIP-01: Index events must have empty content
return event;
}
/**
* Build hierarchical segment structure for Level 3+ parsing
*/

Loading…
Cancel
Save