diff --git a/src/lib/components/EventInput.svelte b/src/lib/components/EventInput.svelte
index 17b3489..2768205 100644
--- a/src/lib/components/EventInput.svelte
+++ b/src/lib/components/EventInput.svelte
@@ -48,6 +48,38 @@
let warningMessage = $state("");
let pendingPublish = $state(false);
let extractedMetadata = $state<[string, string][]>([]);
+ let hasLoadedFromStorage = $state(false);
+
+ // Load content from sessionStorage if available (from ZettelEditor)
+ $effect(() => {
+ if (hasLoadedFromStorage) return; // Prevent multiple loads
+
+ const storedContent = sessionStorage.getItem('zettelEditorContent');
+ const storedSource = sessionStorage.getItem('zettelEditorSource');
+
+ if (storedContent && storedSource === 'publication-format') {
+ content = storedContent;
+ hasLoadedFromStorage = true;
+
+ // Clear the stored content after loading
+ sessionStorage.removeItem('zettelEditorContent');
+ sessionStorage.removeItem('zettelEditorSource');
+
+ // Extract title from content
+ const extracted = extractTitleFromContent(content);
+ if (extracted) {
+ title = extracted;
+ titleManuallyEdited = false;
+ dTagManuallyEdited = false;
+ }
+
+ // For content from ZettelEditor, don't extract any metadata
+ // since ZettelEditor content never has document metadata
+ if (kind === 30040 || kind === 30041) {
+ extractedMetadata = [];
+ }
+ }
+ });
/**
* Extracts the first Markdown/AsciiDoc header as the title.
@@ -57,10 +89,14 @@
// Look for document title (=) first, then fall back to section headers (==)
const documentMatch = content.match(/^=\s*(.+)$/m);
if (documentMatch) {
- return documentMatch[1].trim();
+ const title = documentMatch[1].trim();
+ // Only return the title if it's not empty (malformed titles like "=|" will be empty)
+ if (title) {
+ return title;
+ }
}
- // If no document title, look for the first section header
+ // If no valid document title, look for the first section header
const sectionMatch = content.match(/^==\s*(.+)$/m);
if (sectionMatch) {
return sectionMatch[1].trim();
@@ -81,16 +117,8 @@
// Extract metadata from AsciiDoc content for 30040 and 30041 events
if (kind === 30040 || kind === 30041) {
- try {
- const { metadata } = extractDocumentMetadata(content);
- const metadataTags = metadataToTags(metadata);
- extractedMetadata = metadataTags;
- console.log("Extracted metadata:", metadata);
- console.log("Metadata tags:", metadataTags);
- } catch (error) {
- console.error("Error extracting metadata:", error);
- extractedMetadata = [];
- }
+ // Don't extract metadata - let users add tags manually
+ extractedMetadata = [];
} else {
extractedMetadata = [];
}
diff --git a/src/lib/components/ZettelEditor.svelte b/src/lib/components/ZettelEditor.svelte
index b8c9d4d..9e33343 100644
--- a/src/lib/components/ZettelEditor.svelte
+++ b/src/lib/components/ZettelEditor.svelte
@@ -5,19 +5,33 @@
parseAsciiDocSections,
type ZettelSection,
} from "$lib/utils/ZettelParser";
+ import {
+ extractDocumentMetadata,
+ extractSectionMetadata,
+ parseAsciiDocWithMetadata,
+ type AsciiDocMetadata,
+ metadataToTags,
+ } from "$lib/utils/asciidoc_metadata";
import asciidoctor from "asciidoctor";
// Component props
let {
content = "",
placeholder = `== Note Title
-:author: {author} // author is optional
-:tags: tag1, tag2, tag3 // tags are optional
+:author: Your Name
+:version: 1.0
+:published_on: 2024-01-01
+:published_by: Alexandria
+:summary: A brief description of this note
+:tags: note, example, metadata
+:image: https://example.com/image.jpg
note content here...
== Note Title 2
-:tags: tag1, tag2, tag3
+Some Other Author (this weeks even if there is no :author: attribute)
+:keywords: second, note, example (keywords are converted to tags)
+:description: This is a description of the note (description is converted to a summary tag)
Note content here...
`,
showPreview = false,
@@ -34,8 +48,63 @@ Note content here...
// Initialize AsciiDoctor processor
const asciidoctorProcessor = asciidoctor();
- // Parse sections for preview
- let parsedSections = $derived(parseAsciiDocSections(content, 2));
+ // Parse sections for preview using the new metadata service
+ let parsedSections = $derived.by(() => {
+ if (!content.trim()) return [];
+
+ // Check if content starts with a document header (level 0 header)
+ const hasDocumentHeader = content.match(/^=\s+/m);
+
+ let sections;
+ if (hasDocumentHeader) {
+ // Use the proper metadata service for documents with headers
+ const parsed = parseAsciiDocWithMetadata(content);
+ sections = parsed.sections;
+ } else {
+ // For content that starts directly with sections, split manually
+ const sectionStrings = content.split(/(?=^==\s+)/gm).filter((section: string) => section.trim());
+ sections = sectionStrings.map((sectionString: string) => {
+ const { metadata, content, title } = extractSectionMetadata(sectionString);
+ return { metadata, content, title };
+ });
+ }
+
+ // Debug logging
+ console.log("Parsed sections:", sections);
+
+ return sections.map((section: { metadata: AsciiDocMetadata; content: string; title: string }) => {
+ // Use only section metadata for each section
+ // Don't combine with document metadata to avoid overriding section-specific metadata
+ const tags = metadataToTags(section.metadata);
+
+ // Debug logging
+ console.log(`Section "${section.title}":`, { metadata: section.metadata, tags });
+
+ return {
+ title: section.title || "Untitled",
+ content: section.content.trim(),
+ tags,
+ };
+ });
+ });
+
+ // Check for 30040-style document headers (publication format)
+ let hasPublicationHeader = $derived.by(() => {
+ if (!content.trim()) return false;
+
+ const lines = content.split(/\r?\n/);
+ for (const line of lines) {
+ // Check for document title (level 0 header)
+ if (line.match(/^=\s+(.+)$/)) {
+ return true;
+ }
+ // Check for "index card" format (case insensitive)
+ if (line.trim().toLowerCase() === 'index card') {
+ return true;
+ }
+ }
+ return false;
+ });
// Toggle preview panel
function togglePreview() {
@@ -51,34 +120,87 @@ Note content here...
-
-
-
-
-
+
+ {#if hasPublicationHeader}
+
+
+
+
+
+
+
+ Publication Format Detected
+
+
+ You're using a publication format (document title with = or "index card").
+ This editor is for individual notes only. Use the
+ Events form
+ to create structured publications.
+
- This editor is for creating individual notes (30041 events) only. Each section becomes a separate note event.
- To create structured publications with a 30040 index event that ties multiple notes together,
- use the Events form.
-
+ This editor is for creating individual notes (30041 events) only. Each section becomes a separate note event.
+ You can add metadata like author, version, publication date, summary, and tags using AsciiDoc attributes.
+ To create structured publications with a 30040 index event that ties multiple notes together,
+ use the Events form.
+
+ {/if}
{:else}
Some events failed to publish.
- {publishResults.successCount} of {publishResults.total} events published.
- {#each publishResults.errors as error}
-