diff --git a/src/lib/components/ZettelEditor.svelte b/src/lib/components/ZettelEditor.svelte index 717f47b..684865c 100644 --- a/src/lib/components/ZettelEditor.svelte +++ b/src/lib/components/ZettelEditor.svelte @@ -1,6 +1,10 @@
-
+

Unified AsciiDoc Publisher

-
+
- -
- +
Content Type: - - {contentType === 'article' ? 'Article' : contentType === 'scattered-notes' ? 'Notes' : 'None'} + + {contentType === "article" + ? "Article" + : contentType === "scattered-notes" + ? "Notes" + : "None"}
- + {#if generatedEvents}
Events: - {generatedEvents.contentEvents.length + (generatedEvents.indexEvent ? 1 : 0)} + {generatedEvents.contentEvents.length + + (generatedEvents.indexEvent ? 1 : 0)}
{/if}
-
- + {#if publicationResult?.metadata?.eventStructure && generatedEvents}
-
+
- {#if generatedEvents && contentType !== 'none'} - + {#if generatedEvents && contentType !== "none"} + {:else}
Add content to enable publishing @@ -717,23 +883,40 @@ import Asciidoctor from "asciidoctor"; {/if}
-
+
-
-
+
+
-
+
{#if showPreview} -
-
-
+
+
+

AsciiDoc Preview

@@ -741,23 +924,34 @@ import Asciidoctor from "asciidoctor";
{#if !content.trim()} -
+
Start typing to see the preview...
{:else} - {#if contentType === 'article' && publicationResult?.metadata.title} -
-

+ {#if contentType === "article" && publicationResult?.metadata.title} +
+

{publicationResult.metadata.title}

{#if publicationResult.metadata.attributes.tags} - {@const tagsList = publicationResult.metadata.attributes.tags.split(',').map((t: string) => t.trim())} + {@const tagsList = + publicationResult.metadata.attributes.tags + .split(",") + .map((t: string) => t.trim())} {#if tagsList.length > 0}
{#each tagsList as tag} - + #{tag} {/each} @@ -766,30 +960,42 @@ import Asciidoctor from "asciidoctor"; {/if}
{/if} - +
- {#if contentType === 'article' && publicationResult?.metadata.title} + {#if contentType === "article" && publicationResult?.metadata.title} {@const documentHeader = content.split(/\n==\s+/)[0]} -
+
{@html asciidoctor.convert(documentHeader, { standalone: false, attributes: { showtitle: true, sectids: false, - } + }, })}
{#if publicationResult.metadata.attributes.tags} - {@const tagsList = publicationResult.metadata.attributes.tags.split(',').map((t: string) => t.trim())} + {@const tagsList = + publicationResult.metadata.attributes.tags + .split(",") + .map((t: string) => t.trim())} {#if tagsList.length > 0} -
+
- Document tags: + Document tags: {#each tagsList as tag} -
+
# {tag}
@@ -800,70 +1006,91 @@ import Asciidoctor from "asciidoctor"; {/if}
{/if} - + {#each parsedSections as section, index} -
+
{#if section.isIndex} -
+
Index Event (30040)
-

+

{section.title}

{:else}
-
+
Content Event (30041)
- + -
- {@html asciidoctor.convert(`${'='.repeat(section.level)} ${section.title}`, { - standalone: false, - attributes: { - showtitle: false, - sectids: false, - } - })} +
+ {@html asciidoctor.convert( + `${"=".repeat(section.level)} ${section.title}`, + { + standalone: false, + attributes: { + showtitle: false, + sectids: false, + }, + }, + )}
- + {#if section.tags && section.tags.length > 0}
{#each section.tags as tag} - + #{tag[1]} {/each}
{/if} - + {#if section.content} -
+
{@html asciidoctor.convert(section.content, { standalone: false, attributes: { showtitle: false, sectids: false, - } + }, })}
{/if}
{/if} - + {#if index < parsedSections.length - 1}
-
+
- + Event Boundary
@@ -878,12 +1105,24 @@ import Asciidoctor from "asciidoctor"; > Event Count: {#if generatedEvents} - {@const indexEvents = generatedEvents.contentEvents.filter((e: any) => e.kind === 30040)} - {@const contentOnlyEvents = generatedEvents.contentEvents.filter((e: any) => e.kind === 30041)} - {@const totalIndexEvents = indexEvents.length + (generatedEvents.indexEvent ? 1 : 0)} - {@const totalEvents = totalIndexEvents + contentOnlyEvents.length} + {@const indexEvents = generatedEvents.contentEvents.filter( + (e: any) => e.kind === 30040, + )} + {@const contentOnlyEvents = + generatedEvents.contentEvents.filter( + (e: any) => e.kind === 30041, + )} + {@const totalIndexEvents = + indexEvents.length + (generatedEvents.indexEvent ? 1 : 0)} + {@const totalEvents = + totalIndexEvents + contentOnlyEvents.length} {totalEvents} event{totalEvents !== 1 ? "s" : ""} - ({totalIndexEvents} index{totalIndexEvents !== 1 ? " events" : ""} + {contentOnlyEvents.length} content{contentOnlyEvents.length !== 1 ? " events" : ""}) + ({totalIndexEvents} index{totalIndexEvents !== 1 + ? " events" + : ""} + {contentOnlyEvents.length} content{contentOnlyEvents.length !== + 1 + ? " events" + : ""}) {:else} 0 events {/if} @@ -896,48 +1135,88 @@ import Asciidoctor from "asciidoctor"; {#if showTutorial} -
-
-
+
+
+

AsciiDoc Guide

- -
+ +
-

Header Highlighting

+

+ Header Highlighting +

-
- Blue: Index Events (30040) +
+ Blue: Index Events (30040)
-
- Green: Content Events (30041) +
+ Green: Content Events + (30041)
-
- Amber: Potential Events (at parse level) +
+ Amber: Potential Events + (at parse level)
-
- Gray: Subheaders (within content) +
+ Gray: Subheaders (within + content)
- +
-

Publishing Levels

+

+ Publishing Levels +

    {#each generateParseLevelOptions(MIN_PARSE_LEVEL, MAX_PARSE_LEVEL) as option}
  • - Level {option.level}: + Level {option.level}: {#if option.level === 2} - Only {'='.repeat(option.level)} sections become events (containing {'='.repeat(option.level + 1)} and deeper) + Only {"=".repeat(option.level)} sections become events (containing + {"=".repeat(option.level + 1)} and deeper) {:else} - {'='.repeat(option.level - 1)} sections become indices, {'='.repeat(option.level)} sections become events + {"=".repeat(option.level - 1)} sections become indices, {"=".repeat( + option.level, + )} sections become events {/if}
  • {/each} @@ -945,8 +1224,11 @@ import Asciidoctor from "asciidoctor";
-

Example Structure

-
{`= Understanding Knowledge
+              

+ Example Structure +

+
{`= Understanding Knowledge
 :image: https://i.nostr.build/example.jpg
 :published: 2025-04-21
 :tags: knowledge, philosophy, education
@@ -974,33 +1256,56 @@ Understanding the nature of knowledge...
             
-

Attributes

-

Use :key: value format to add metadata that becomes event tags.

+

+ Attributes +

+

+ Use :key: value format to add metadata that becomes + event tags. +

-

Content Types

+

+ Content Types +

    -
  • Article: Starts with = title, creates index + content events
  • -
  • Notes: Just == sections, creates individual content events
  • +
  • + Article: Starts with = title, creates index + + content events +
  • +
  • + Notes: Just == sections, creates individual content + events +
{/if} - + {#if showStructurePreview} -
-
-
+
+
+

Event Structure

- -
+ +
{#if publicationResult?.metadata?.eventStructure && publicationResult.metadata.eventStructure.length > 0}
@@ -1008,21 +1313,37 @@ Understanding the nature of knowledge...
📁
-
Index Events
+
+ Index Events +
- {publicationResult.metadata.eventStructure.filter((n: any) => n.eventKind === 30040).length + - publicationResult.metadata.eventStructure.reduce((acc: number, n: any) => - acc + (n.children?.filter?.((c: any) => c.eventKind === 30040)?.length || 0), 0)} × 30040 + {publicationResult.metadata.eventStructure.filter( + (n: any) => n.eventKind === 30040, + ).length + + publicationResult.metadata.eventStructure.reduce( + (acc: number, n: any) => + acc + + (n.children?.filter?.( + (c: any) => c.eventKind === 30040, + )?.length || 0), + 0, + )} × 30040
- +
📄
-
Content Events
+
+ Content Events +
{generatedEvents.contentEvents.length} × 30041
@@ -1030,14 +1351,14 @@ Understanding the nature of knowledge...
- +
{#snippet renderEventNode(node, depth = 0)}
- {node.eventKind === 30040 ? '📁' : '📄'} - [{node.eventKind}] {node.title || 'Untitled'} + {node.eventKind === 30040 ? "📁" : "📄"} + [{node.eventKind}] {node.title || "Untitled"}
{#if node.children && node.children.length > 0} {#each node.children as child} @@ -1045,13 +1366,13 @@ Understanding the nature of knowledge... {/each} {/if} {/snippet} - + {#each publicationResult.metadata.eventStructure as node} {@render renderEventNode(node, 0)} {/each}
- +
@@ -1059,19 +1380,22 @@ Understanding the nature of knowledge...
{#if parseLevel === 2} - Each == section becomes a 30041 event with all nested content. + Each == section becomes a 30041 event with all nested + content. {:else if parseLevel === 3} - Level 2 sections with children → 30040 indices
+ Level 2 sections with children → 30040 indices
Level 3 sections → 30041 content events {:else} - Sections with children → 30040 indices
+ Sections with children → 30040 indices
Level {parseLevel} sections → 30041 content events {/if}
- + -
+
📁 @@ -1088,14 +1412,22 @@ Understanding the nature of knowledge...
Add content to see event structure
- Debug: {JSON.stringify({ - hasResult: !!publicationResult, - hasMetadata: !!publicationResult?.metadata, - hasStructure: !!publicationResult?.metadata?.eventStructure, - structureLength: publicationResult?.metadata?.eventStructure?.length || 0, - hasEvents: !!generatedEvents, - contentLength: generatedEvents?.contentEvents?.length || 0 - }, null, 2)} + Debug: {JSON.stringify( + { + hasResult: !!publicationResult, + hasMetadata: !!publicationResult?.metadata, + hasStructure: + !!publicationResult?.metadata?.eventStructure, + structureLength: + publicationResult?.metadata?.eventStructure?.length || + 0, + hasEvents: !!generatedEvents, + contentLength: + generatedEvents?.contentEvents?.length || 0, + }, + null, + 2, + )}
{/if} diff --git a/src/lib/utils/publication_tree_processor.ts b/src/lib/utils/publication_tree_processor.ts index e1e69cd..8f16b66 100644 --- a/src/lib/utils/publication_tree_processor.ts +++ b/src/lib/utils/publication_tree_processor.ts @@ -330,8 +330,34 @@ function parseSegmentContent( } } - // Extract content (everything after attributes) - const content = sectionLines.slice(contentStartIdx).join("\n").trim(); + // Extract content (everything after attributes, but stop at child sections) + const contentLines = sectionLines.slice(contentStartIdx); + + // Find where child sections start (deeper level headers) + let contentEndIdx = contentLines.length; + const currentSectionLevel = sectionLines[0].match(/^(=+)/)?.[1].length || 2; + + for (let i = 0; i < contentLines.length; i++) { + const line = contentLines[i]; + const headerMatch = line.match(/^(=+)\s+/); + if (headerMatch && headerMatch[1].length > currentSectionLevel) { + // Found a child section header - stop content extraction here + contentEndIdx = i; + break; + } + } + + const content = contentLines.slice(0, contentEndIdx).join("\n").trim(); + + // Debug logging for content extraction + if (sectionLines[0].includes("Chapter 1")) { + console.log("[DEBUG] Chapter 1 content extraction in parseSegmentContent:"); + console.log(" sectionLines:", sectionLines); + console.log(" contentStartIdx:", contentStartIdx); + console.log(" contentLines:", contentLines); + console.log(" contentEndIdx:", contentEndIdx); + console.log(" extracted content:", JSON.stringify(content)); + } return { attributes, content }; } @@ -622,6 +648,15 @@ function createContentEvent(segment: ContentSegment, ndk: NDK): NDKEvent { event.tags = tags; event.content = segment.content; + // Debug logging for Chapter 1 content events + if (segment.title === "Chapter 1") { + console.log("[DEBUG] Creating content event for Chapter 1:"); + console.log(" segment.title:", segment.title); + console.log(" segment.content:", JSON.stringify(segment.content)); + console.log(" segment.level:", segment.level); + console.log(" event.content:", JSON.stringify(event.content)); + } + return event; }