Browse Source

Compose can now edit index titles

master
buttercat1791 1 year ago
parent
commit
342393dcad
  1. 27
      src/lib/components/Preview.svelte
  2. 60
      src/lib/parser.ts
  3. 2
      src/lib/stores.ts
  4. 29
      src/routes/new/edit/+page.svelte

27
src/lib/components/Preview.svelte

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
<script lang="ts">
import { parser } from "$lib/parser";
import { Button, Heading, P, Textarea, Tooltip } from "flowbite-svelte";
import { Button, ButtonGroup, CloseButton, Heading, Input, P, Textarea, Tooltip } from "flowbite-svelte";
import { CaretDownSolid, CaretUpSolid, EditOutline } from "flowbite-svelte-icons";
import { createEventDispatcher } from "svelte";
@ -19,7 +19,7 @@ @@ -19,7 +19,7 @@
let hasCursor: boolean = false;
let childHasCursor: boolean;
const title = $parser.getIndexTitle(rootId);
let title = $parser.getIndexTitle(rootId);
const orderedChildren = $parser.getOrderedChildIds(rootId);
$: buttonsVisible = hasCursor && !childHasCursor;
@ -62,6 +62,10 @@ @@ -62,6 +62,10 @@
const editing = isEditing;
if (editing && shouldSave) {
if (orderedChildren.length > 0) {
}
$parser.updateEventContent(id, currentContent);
}
@ -73,7 +77,7 @@ @@ -73,7 +77,7 @@
<!-- svelte-ignore a11y-no-static-element-interactions -->
<section
id={rootId}
class={`note-leather w-full flex space-x-2 justify-between ${sectionClass}`}
class={`note-leather flex space-x-2 justify-between ${sectionClass}`}
on:mouseenter={handleMouseEnter}
on:mouseleave={handleMouseLeave}
>
@ -111,9 +115,20 @@ @@ -111,9 +115,20 @@
{/if}
{:else}
<div class='flex flex-col space-y-2'>
<Heading tag={getHeadingTag(depth)} class='h-leather'>
{title}
</Heading>
{#if isEditing}
<ButtonGroup class='w-full'>
<Input type='text' class='input-leather' size='lg' bind:value={title}>
<CloseButton slot='right' on:click={() => toggleEditing(rootId, false)} />
</Input>
<Button class='btn-leather' color='primary' size='lg' on:click={() => toggleEditing(rootId, true)}>
Save
</Button>
</ButtonGroup>
{:else}
<Heading tag={getHeadingTag(depth)} class='h-leather'>
{title}
</Heading>
{/if}
<!-- Recurse on child indices and zettels -->
{#each orderedChildren as id, index}
<svelte:self

60
src/lib/parser.ts

@ -84,6 +84,12 @@ export default class Pharos { @@ -84,6 +84,12 @@ export default class Pharos {
*/
private events: Map<string, NDKEvent> = new Map<string, NDKEvent>();
/**
* A map of event d tags to the context name assigned to each event's originating node by the
* Asciidoctor parser.
*/
private eventToContextMap: Map<string, string> = new Map<string, string>();
/**
* A map of node IDs to the integer event kind that will be used to represent the node.
*/
@ -125,7 +131,12 @@ export default class Pharos { @@ -125,7 +131,12 @@ export default class Pharos {
}
parse(content: string, options?: ProcessorOptions | undefined): void {
this.html = this.asciidoctor.convert(content, options) as string | Document | undefined;
try {
this.html = this.asciidoctor.convert(content, options) as string | Document | undefined;
} catch (error) {
console.error(error);
throw new Error('Failed to parse AsciiDoc document.');
}
}
/**
@ -235,12 +246,7 @@ export default class Pharos { @@ -235,12 +246,7 @@ export default class Pharos {
throw new Error(`No event found for #d:${dTag}.`);
}
event.content = content;
event.id = event.getEventHash();
this.events.set(dTag, event);
this.eventIds.set(dTag, event.id);
this.shouldUpdateEventTree = true;
this.updateEventByContext(dTag, content, this.eventToContextMap.get(dTag)!);
return event;
}
@ -283,6 +289,8 @@ export default class Pharos { @@ -283,6 +289,8 @@ export default class Pharos {
this.shouldUpdateEventTree = true;
}
// TODO: Add method to update index title.
/**
* Resets the parser to its initial state, removing any parsed data.
*/
@ -563,6 +571,10 @@ export default class Pharos { @@ -563,6 +571,10 @@ export default class Pharos {
// #region Utility Functions
/**
* Generates an ID for the given block that is unique within the document, and adds a mapping of
* the generated ID to the block's context, as determined by the Asciidoctor parser.
*/
private generateNodeId(block: AbstractBlock): string {
let blockId: string | null = this.normalizeId(block.getId());
@ -752,6 +764,8 @@ export default class Pharos { @@ -752,6 +764,8 @@ export default class Pharos {
}
block.setId(blockId);
this.eventToContextMap.set(blockId, context);
return blockId;
}
@ -768,6 +782,38 @@ export default class Pharos { @@ -768,6 +782,38 @@ export default class Pharos {
.replace(/[^a-z0-9\-]/g, ''); // Remove non-alphanumeric characters except dashes.
}
private updateEventByContext(dTag: string, value: string, context: string) {
switch (context) {
case 'document':
case 'section':
this.updateEventTitle(dTag, value);
break;
default:
this.updateEventBody(dTag, value);
break;
}
}
private updateEventTitle(dTag: string, value: string) {
const event = this.events.get(dTag);
this.events.delete(dTag);
this.events.set(value, event!);
this.rehashEvent(dTag, event!);
}
private updateEventBody(dTag: string, value: string) {
const event = this.events.get(dTag);
event!.content = value;
this.rehashEvent(dTag, event!);
}
private rehashEvent(dTag: string, event: NDKEvent) {
event.id = event.getEventHash();
this.eventIds.set(dTag, event.id);
this.shouldUpdateEventTree = true;
}
private extractAndNormalizeWikilinks(content: string): string[][] {
const wikilinkPattern = /\[\[([^\]]+)\]\]/g;
const wikilinks: string[][] = [];

2
src/lib/stores.ts

@ -6,5 +6,3 @@ export let idList = writable<string[]>([]); @@ -6,5 +6,3 @@ export let idList = writable<string[]>([]);
export let alexandriaKinds = readable<number[]>([30040, 30041]);
export let feedType = writable<FeedType>(FeedType.Relays);
export let editorText = writable<string>('');

29
src/routes/new/edit/+page.svelte

@ -1,7 +1,6 @@ @@ -1,7 +1,6 @@
<script lang="ts">
import { Heading, Textarea, Toolbar, ToolbarButton, Tooltip } from "flowbite-svelte";
import { CodeOutline, EyeSolid, PaperPlaneOutline } from "flowbite-svelte-icons";
import { editorText } from "$lib/stores";
import Preview from "$lib/components/Preview.svelte";
import Pharos, { parser } from "$lib/parser";
import { ndk } from "$lib/ndk";
@ -12,10 +11,19 @@ @@ -12,10 +11,19 @@
let isEditing: boolean = true;
let rootIndexId: string;
let editorText: string;
const showPreview = () => {
$parser ??= new Pharos($ndk);
$parser.reset();
$parser.parse($editorText);
try {
$parser ??= new Pharos($ndk);
$parser.reset();
$parser.parse(editorText);
} catch (e) {
console.error(e);
// TODO: Indicate error in UI.
return;
}
rootIndexId = $parser.getRootIndexId();
isEditing = false;
};
@ -25,8 +33,15 @@ @@ -25,8 +33,15 @@
};
const prepareReview = () => {
$parser.reset();
$parser.parse($editorText);
try {
$parser.reset();
$parser.parse(editorText);
} catch (e) {
console.error(e);
// TODO: Indicate error in UI.
return;
}
$parser.generate($ndk.activeUser?.pubkey!);
goto('/new/compose');
}
@ -42,7 +57,7 @@ @@ -42,7 +57,7 @@
class='textarea-leather'
rows=8
placeholder='Write AsciiDoc content'
bind:value={$editorText}
bind:value={editorText}
>
<Toolbar slot='header' embedded>
<ToolbarButton name='Preview' on:click={showPreview}>

Loading…
Cancel
Save