@plannotator/ui 0.41.2 → 0.42.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/HANDOFF.md +1 -0
- package/components/DiagramBlock.tsx +3 -1
- package/hooks/useLinkedDoc.ts +11 -6
- package/package.json +2 -2
- package/styles.css +1 -1
- package/types.ts +20 -0
- package/utils/parser.ts +33 -0
- package/utils/sharing.ts +28 -1
package/types.ts
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import type { DiagramAnchor } from '@plannotator/core/diagram-anchor';
|
|
2
|
+
import type { DiagramRenderKind } from '@plannotator/core/annotatable';
|
|
2
3
|
|
|
3
4
|
export type { DiagramAnchor } from '@plannotator/core/diagram-anchor';
|
|
5
|
+
export type { DiagramRenderKind } from '@plannotator/core/annotatable';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* How a document's body is rendered. `markdown` and `html` are the original
|
|
9
|
+
* pair; the two diagram kinds are whole-file diagram sources (.mmd/.mermaid,
|
|
10
|
+
* .dot/.gv) that render as ONE diagram through the same engine a ```mermaid
|
|
11
|
+
* fence uses — see diagramDocumentBlocks in utils/parser.
|
|
12
|
+
*/
|
|
13
|
+
export type DocumentRenderAs = 'markdown' | 'html' | DiagramRenderKind;
|
|
4
14
|
|
|
5
15
|
export enum AnnotationType {
|
|
6
16
|
DELETION = 'DELETION',
|
|
@@ -192,6 +202,16 @@ export interface Block {
|
|
|
192
202
|
order: number; // Sorting order
|
|
193
203
|
startLine: number; // 1-based line number in source
|
|
194
204
|
sourceLineCount?: number; // Number of source lines consumed when it differs from content lines
|
|
205
|
+
/**
|
|
206
|
+
* Line offset a diagram comment's `sourceLine` is measured from, when it
|
|
207
|
+
* differs from `startLine`. A ```mermaid fence in a document has its opening
|
|
208
|
+
* line ABOVE the diagram's first line, so `startLine` is the right offset
|
|
209
|
+
* there and this stays unset. A whole-file diagram source (.mmd/.dot) has no
|
|
210
|
+
* fence: its first line IS document line 1, so it sets 0 here while
|
|
211
|
+
* `startLine` keeps naming the block's own first line for the export's
|
|
212
|
+
* `(lines a–b)` label.
|
|
213
|
+
*/
|
|
214
|
+
diagramSourceLineOffset?: number;
|
|
195
215
|
}
|
|
196
216
|
|
|
197
217
|
export interface DiffResult {
|
package/utils/parser.ts
CHANGED
|
@@ -541,6 +541,39 @@ export const resolveReferenceLinks = (markdown: string): string => {
|
|
|
541
541
|
.join('\n');
|
|
542
542
|
};
|
|
543
543
|
|
|
544
|
+
/**
|
|
545
|
+
* The block list for a whole-file diagram source (`plannotator annotate
|
|
546
|
+
* flow.mmd`): ONE code block carrying the file's raw text, which `Viewer`
|
|
547
|
+
* hands to the same `DiagramBlock` a ```mermaid fence in a plan produces.
|
|
548
|
+
* Everything downstream — diagram comments, the annotations rail, the export's
|
|
549
|
+
* `Diagram node <label> (<id>), line <n>` location line, drafts, restore — is
|
|
550
|
+
* the fence path unchanged.
|
|
551
|
+
*
|
|
552
|
+
* `diagramSourceLineOffset: 0` is the load-bearing part. `DiagramBlock` passes
|
|
553
|
+
* it as the viewer's `sourceLineOffset` and the codec adds it to the 1-based
|
|
554
|
+
* line WITHIN the diagram source; for a fence that offset is the fence's own
|
|
555
|
+
* opening line, which sits one line above the diagram's first line. A diagram
|
|
556
|
+
* FILE has no fence, so its first line is document line 1 and the offset is 0
|
|
557
|
+
* — the 1 a synthesized ```mermaid wrapper would produce puts every exported
|
|
558
|
+
* diagram line one too high. `startLine`/`sourceLineCount` still describe the
|
|
559
|
+
* block itself, so the export's `(lines a–b)` label names the file's real
|
|
560
|
+
* span.
|
|
561
|
+
*/
|
|
562
|
+
export const diagramDocumentBlocks = (text: string, kind: 'mermaid' | 'graphviz'): Block[] => [
|
|
563
|
+
{
|
|
564
|
+
id: 'block-0',
|
|
565
|
+
type: 'code',
|
|
566
|
+
content: text,
|
|
567
|
+
// `dot` is what isGraphvizLanguage reads for the Graphviz engine.
|
|
568
|
+
language: kind === 'graphviz' ? 'dot' : 'mermaid',
|
|
569
|
+
order: 1,
|
|
570
|
+
startLine: 1,
|
|
571
|
+
// A trailing newline ends the last line, it does not start another.
|
|
572
|
+
sourceLineCount: text === '' ? 0 : text.replace(/\n$/, '').split('\n').length,
|
|
573
|
+
diagramSourceLineOffset: 0,
|
|
574
|
+
},
|
|
575
|
+
];
|
|
576
|
+
|
|
544
577
|
/**
|
|
545
578
|
* A simplified markdown parser that splits content into linear blocks.
|
|
546
579
|
* For a production app, we would use a robust AST walker (remark),
|
package/utils/sharing.ts
CHANGED
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
* Inspired by textarea.my's approach.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import { AnnotationType, type Annotation, type ImageAttachment } from '../types';
|
|
11
|
+
import { AnnotationType, type Annotation, type DocumentRenderAs, type ImageAttachment } from '../types';
|
|
12
|
+
import { isDiagramRenderKind } from '@plannotator/core/annotatable';
|
|
12
13
|
import { compress, decompress } from '@plannotator/core/compress';
|
|
13
14
|
import { encrypt, decrypt } from '@plannotator/core/crypto';
|
|
14
15
|
|
|
@@ -31,6 +32,32 @@ export interface SharePayload {
|
|
|
31
32
|
r?: 'html'; // render mode flag (omitted = markdown)
|
|
32
33
|
}
|
|
33
34
|
|
|
35
|
+
/**
|
|
36
|
+
* The markdown a document ships as in a share payload's `p`.
|
|
37
|
+
*
|
|
38
|
+
* A whole-file diagram source (.mmd/.dot) has no fence of its own — the
|
|
39
|
+
* annotate session renders it as one diagram because the SERVER said so in
|
|
40
|
+
* `renderAs`, and a share link carries no server. So it travels as the fenced
|
|
41
|
+
* form, which the portal's ordinary markdown parse turns back into the same
|
|
42
|
+
* diagram block. This is deliberately smaller than adding a render-mode flag
|
|
43
|
+
* (`r: 'html'`'s sibling): the portal needs no change at all.
|
|
44
|
+
*
|
|
45
|
+
* Diagram comments themselves still degrade to text comments in a share link,
|
|
46
|
+
* exactly as they do today — `diagramAnchor` is dropped like `htmlAnchor`
|
|
47
|
+
* (see sharing.multiTarget.test.ts).
|
|
48
|
+
*/
|
|
49
|
+
export function shareableDocumentMarkdown(
|
|
50
|
+
markdown: string,
|
|
51
|
+
renderAs: DocumentRenderAs | undefined,
|
|
52
|
+
): string {
|
|
53
|
+
if (!isDiagramRenderKind(renderAs) || markdown === '') return markdown;
|
|
54
|
+
const language = renderAs === 'graphviz' ? 'dot' : 'mermaid';
|
|
55
|
+
// A diagram source can itself contain a ``` run only in a comment/label;
|
|
56
|
+
// a four-backtick fence keeps such a body intact.
|
|
57
|
+
const fence = markdown.includes('```') ? '````' : '```';
|
|
58
|
+
return `${fence}${language}\n${markdown.replace(/\n+$/, '')}\n${fence}`;
|
|
59
|
+
}
|
|
60
|
+
|
|
34
61
|
/**
|
|
35
62
|
* Convert ShareableImage[] to ImageAttachment[] (handles old plain-string format)
|
|
36
63
|
*/
|