Browse Source

fix: editor correctly identifying and highlighting index events

master
limina1 6 months ago
parent
commit
27382f4b86
  1. 101
      src/lib/components/ZettelEditor.svelte

101
src/lib/components/ZettelEditor.svelte

@ -57,11 +57,11 @@ import Asciidoctor from "asciidoctor";
// Note: updateEditorContent() is only called manually when needed // Note: updateEditorContent() is only called manually when needed
// The automatic effect was causing feedback loops with user typing // The automatic effect was causing feedback loops with user typing
// Effect to update syntax highlighting when parsedSections change // Effect to update syntax highlighting when parsing results change
$effect(() => { $effect(() => {
if (editorView && parsedSections) { if (editorView && (parsedSections || publicationResult?.metadata?.eventStructure)) {
editorView.dispatch({ editorView.dispatch({
effects: updateHighlighting.of(parsedSections) effects: updateHighlighting.of(parsedSections || [])
}); });
} }
}); });
@ -317,16 +317,37 @@ import Asciidoctor from "asciidoctor";
// Analyze document structure for ambiguity detection // Analyze document structure for ambiguity detection
const documentStructure = analyzeDocumentStructure(lines); const documentStructure = analyzeDocumentStructure(lines);
// Create a map of header text to section info for fast lookup // Create a map of header text to section info for fast lookup from actual event structure
const sectionMap = new Map(); const sectionMap = new Map();
if (sections) { if (publicationResult?.metadata?.eventStructure) {
sections.forEach(section => { // Flatten the event structure to get all nodes with their actual event types
if (section.title) { const flattenEventStructure = (nodes: any[], result: any[] = []): any[] => {
sectionMap.set(section.title.toLowerCase().trim(), { for (const node of nodes) {
level: section.level, result.push(node);
if (node.children && node.children.length > 0) {
flattenEventStructure(node.children, result);
}
}
return result;
};
const allEventNodes = flattenEventStructure(publicationResult.metadata.eventStructure);
// Debug: log the event structure
console.log('Event structure nodes for highlighting:', allEventNodes.map(n => ({
title: n.title,
level: n.level,
eventType: n.eventType,
eventKind: n.eventKind
})));
allEventNodes.forEach(node => {
if (node.title) {
sectionMap.set(node.title.toLowerCase().trim(), {
level: node.level,
isEventTitle: true, isEventTitle: true,
eventType: section.eventType, eventType: node.eventType,
eventKind: section.eventKind eventKind: node.eventKind
}); });
} }
}); });
@ -347,24 +368,28 @@ import Asciidoctor from "asciidoctor";
const sectionInfo = sectionMap.get(headerText); const sectionInfo = sectionMap.get(headerText);
let className: string; let className: string;
if (sectionInfo && sectionInfo.isEventTitle) { // Determine highlighting based on structural analysis first
// Event title - different colors based on event type if (level === 1) {
if (sectionInfo.eventKind === 30040) { // Document title is always an index event (blue)
className = 'cm-header-index-event'; className = 'cm-header-index-event';
} else if (sectionInfo.eventKind === 30041) { } else if (level === parseLevel) {
className = 'cm-header-content-event'; // Headers at parse level are content events (green)
className = 'cm-header-content-event';
} else if (level < parseLevel) {
// Headers above parse level that could have children are index events (blue)
// Check if this header has children by looking ahead in the document
const hasChildren = headerHasChildren(lines, i, level);
if (hasChildren) {
className = 'cm-header-index-event'; // Blue for sections with children
} else { } else {
className = 'cm-header-event-title'; className = 'cm-header-content-event'; // Green for sections without children
} }
} else if (isAmbiguousHeader(level, headerText, documentStructure, parseLevel)) {
className = 'cm-header-potential-event'; // Amber for ambiguous
} else if (level > parseLevel) {
className = 'cm-header-subcontent'; // Gray for subheaders below parse level
} else { } else {
// Check for ambiguous syntax patterns className = 'cm-header-potential-event'; // Amber for unclear cases
if (isAmbiguousHeader(level, headerText, documentStructure, parseLevel)) {
className = 'cm-header-potential-event'; // Amber for ambiguous
} else if (level <= parseLevel) {
className = 'cm-header-potential-event'; // Amber for at parse level but not extracted
} else {
className = 'cm-header-subcontent'; // Gray for subheaders
}
} }
ranges.push({ ranges.push({
@ -412,6 +437,30 @@ import Asciidoctor from "asciidoctor";
}; };
} }
// Check if a header has children by looking ahead in the document
function headerHasChildren(lines: string[], headerIndex: number, headerLevel: number): boolean {
// Look ahead to see if there are any headers at a deeper level
for (let i = headerIndex + 1; i < lines.length; i++) {
const line = lines[i];
const headerMatch = line.match(/^(=+)\s+(.+)$/);
if (headerMatch) {
const nextLevel = headerMatch[1].length;
if (nextLevel > headerLevel) {
// Found a deeper header - this header has children
return true;
} else if (nextLevel <= headerLevel) {
// Found a header at the same or higher level - no children
return false;
}
}
}
// Reached end of document with no headers found - no children
return false;
}
// Check if a header represents ambiguous syntax // Check if a header represents ambiguous syntax
function isAmbiguousHeader( function isAmbiguousHeader(
level: number, level: number,

Loading…
Cancel
Save