comark-ui 0.7.1 → 0.7.4
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/README.md +2 -2
- package/dist/client-Bjd6VcGQ.mjs +241 -0
- package/dist/client.d.mts +11 -1
- package/dist/client.mjs +3 -26
- package/dist/{editor-BAdok66p.mjs → editor-DmxNPK7K.mjs} +522 -68
- package/dist/{editor-CNivEuMH.d.mts → editor-KD97dL_1.d.mts} +21 -3
- package/dist/editor-vue.d.mts +1 -1
- package/dist/editor-vue.mjs +1 -1
- package/dist/editor.d.mts +2 -2
- package/dist/editor.mjs +1 -1
- package/dist/html.d.mts +7 -1
- package/dist/html.mjs +29 -9
- package/dist/{index-B0YvApci.d.mts → index-BUDHsvnm.d.mts} +11 -2
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +2 -2
- package/dist/react.d.mts +2 -2
- package/dist/react.mjs +20 -6
- package/dist/skills/before-after-evidence/SKILL.md +72 -0
- package/dist/skills/before-after-evidence/agents/openai.yaml +3 -0
- package/dist/skills/before-after-evidence/references/blocks.md +54 -0
- package/dist/skills/before-after-evidence/references/example.md +37 -0
- package/dist/skills/before-after-evidence/references/measuring.md +50 -0
- package/dist/skills/comark-ui/SKILL.md +9 -2
- package/dist/skills/comark-ui/references/annotate.md +4 -2
- package/dist/skills/comark-ui/references/comments.md +43 -0
- package/dist/skills/comark-ui/references/diagrams.md +7 -1
- package/dist/skills/comark-ui/references/lint.md +1 -1
- package/dist/skills/comark-ui/references/outline.md +9 -1
- package/dist/skills/comark-ui/references/quiz.md +1 -1
- package/dist/skills/comark-ui/references/ui.md +1 -1
- package/dist/skills/review-document/SKILL.md +64 -0
- package/dist/skills/review-document/agents/openai.yaml +3 -0
- package/dist/skills/review-document/references/blocks.md +69 -0
- package/dist/skills/review-document/references/example.md +51 -0
- package/dist/skills/teach-lesson/SKILL.md +78 -0
- package/dist/skills/teach-lesson/agents/openai.yaml +3 -0
- package/dist/skills/teach-lesson/references/blocks.md +91 -0
- package/dist/skills/teach-lesson/references/example.md +70 -0
- package/dist/skills/visual-explanation/SKILL.md +67 -0
- package/dist/skills/visual-explanation/agents/openai.yaml +3 -0
- package/dist/skills/visual-explanation/references/blocks.md +89 -0
- package/dist/skills/visual-explanation/references/example.md +25 -0
- package/dist/skills.d.mts +18 -0
- package/dist/skills.mjs +326 -0
- package/dist/{src-DROB05U6.mjs → src-PkmYCSNu.mjs} +1 -0
- package/dist/svelte/Mermaid.svelte +16 -0
- package/dist/svelte/index.d.ts +1 -1
- package/dist/svelte/index.js +4 -8
- package/dist/{typeset-css-DPB0S1bV.mjs → typeset-css-5aJ7cSmh.mjs} +14 -0
- package/dist/vue.d.mts +2 -2
- package/dist/vue.mjs +33 -6
- package/package.json +46 -44
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ComarkPlugin } from "comark";
|
|
2
|
-
import { AnyExtension, Extension, JSONContent, Node } from "@tiptap/core";
|
|
2
|
+
import { AnyExtension, Extension, JSONContent, Mark, Node } from "@tiptap/core";
|
|
3
3
|
import { StarterKitOptions } from "@tiptap/starter-kit";
|
|
4
4
|
import { EditorState, Plugin, PluginKey, Transaction } from "@tiptap/pm/state";
|
|
5
5
|
import { DecorationSet } from "@tiptap/pm/view";
|
|
@@ -21,9 +21,27 @@ declare const ComarkSlot: Node<any, any>;
|
|
|
21
21
|
declare const ComarkInline: Node<any, any>;
|
|
22
22
|
/** An HTML comment between blocks. */
|
|
23
23
|
declare const ComarkComment: Node<any, any>;
|
|
24
|
+
/** A footnote reference, `[^label]`. */
|
|
25
|
+
declare const FootnoteReference: Node<any, any>;
|
|
26
|
+
/** A note written where it applies, `^[text]`. */
|
|
27
|
+
declare const InlineFootnote: Node<any, any>;
|
|
28
|
+
/** A footnote's text, `[^label]: text`, with the blocks indented under it. */
|
|
29
|
+
declare const FootnoteDefinition: Node<any, any>;
|
|
30
|
+
/** A definition list, `Term` then `: Definition`. */
|
|
31
|
+
declare const DefinitionList: Node<any, any>;
|
|
32
|
+
declare const DefinitionTerm: Node<any, any>;
|
|
33
|
+
declare const DefinitionDescription: Node<any, any>;
|
|
34
|
+
/** CriticMarkup's suggested insertion, `{++text++}`. */
|
|
35
|
+
declare const CriticInsertion: Mark<any, any>;
|
|
36
|
+
/** CriticMarkup's suggested deletion, `{--text--}`. */
|
|
37
|
+
declare const CriticDeletion: Mark<any, any>;
|
|
38
|
+
/** CriticMarkup's highlight, `{==text==}`. */
|
|
39
|
+
declare const CriticHighlight: Mark<any, any>;
|
|
40
|
+
/** CriticMarkup's comment, `{>>text<<}`. */
|
|
41
|
+
declare const CriticComment: Node<any, any>;
|
|
24
42
|
/**
|
|
25
43
|
* The schema `fromMarkdown` and `toMarkdown` read and write: StarterKit's nodes and marks, task lists, inline images,
|
|
26
|
-
* tables, and Comark's components, slots, and comments. It needs no DOM, so a server can load it to convert a document
|
|
44
|
+
* tables, footnotes, definition lists, CriticMarkup, and Comark's components, slots, and comments. It needs no DOM, so a server can load it to convert a document
|
|
27
45
|
* for a collaborative room.
|
|
28
46
|
*/
|
|
29
47
|
declare const ComarkKit: Extension<ComarkKitOptions, any>;
|
|
@@ -128,4 +146,4 @@ interface EditorCodecOptions {
|
|
|
128
146
|
}
|
|
129
147
|
declare function createEditorCodec(options?: EditorCodecOptions): EditorCodec;
|
|
130
148
|
//#endregion
|
|
131
|
-
export { ComarkSlot as S, ComarkComment as _, Upload as a, ComarkKit as b, startUploads as c, EditorDocument as d, MarkdownCheck as f, ComarkBlock as g, toMarkdown as h, PendingUpload as i, uploadKey as l, fromMarkdown as m, EditorCodecOptions as n, UploadOptions as o, checkMarkdown as p, createEditorCodec as r, findUpload as s, EditorCodec as t, uploadPlugin as u, ComarkImage as v, ComarkKitOptions as x, ComarkInline as y };
|
|
149
|
+
export { FootnoteDefinition as A, CriticComment as C, DefinitionDescription as D, CriticInsertion as E, InlineFootnote as M, DefinitionList as O, ComarkSlot as S, CriticHighlight as T, ComarkComment as _, Upload as a, ComarkKit as b, startUploads as c, EditorDocument as d, MarkdownCheck as f, ComarkBlock as g, toMarkdown as h, PendingUpload as i, FootnoteReference as j, DefinitionTerm as k, uploadKey as l, fromMarkdown as m, EditorCodecOptions as n, UploadOptions as o, checkMarkdown as p, createEditorCodec as r, findUpload as s, EditorCodec as t, uploadPlugin as u, ComarkImage as v, CriticDeletion as w, ComarkKitOptions as x, ComarkInline as y };
|
package/dist/editor-vue.d.mts
CHANGED
package/dist/editor-vue.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as fromMarkdown, l as toMarkdown, m as ComarkKit, s as checkMarkdown } from "./editor-
|
|
1
|
+
import { c as fromMarkdown, l as toMarkdown, m as ComarkKit, s as checkMarkdown } from "./editor-DmxNPK7K.mjs";
|
|
2
2
|
import { Editor, EditorContent } from "@tiptap/vue-3";
|
|
3
3
|
import { defineComponent, h, onScopeDispose, ref, shallowRef, watch } from "vue";
|
|
4
4
|
//#region src/editor-vue.ts
|
package/dist/editor.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { S as ComarkSlot, _ as ComarkComment, a as Upload, b as ComarkKit, c as startUploads, d as EditorDocument, f as MarkdownCheck, g as ComarkBlock, h as toMarkdown, i as PendingUpload, l as uploadKey, m as fromMarkdown, n as EditorCodecOptions, o as UploadOptions, p as checkMarkdown, r as createEditorCodec, s as findUpload, t as EditorCodec, u as uploadPlugin, v as ComarkImage, x as ComarkKitOptions, y as ComarkInline } from "./editor-
|
|
2
|
-
export { ComarkBlock, ComarkComment, ComarkImage, ComarkInline, ComarkKit, type ComarkKitOptions, ComarkSlot, type EditorCodec, type EditorCodecOptions, type EditorDocument, type MarkdownCheck, type PendingUpload, Upload, type UploadOptions, checkMarkdown, createEditorCodec, findUpload, fromMarkdown, startUploads, toMarkdown, uploadKey, uploadPlugin };
|
|
1
|
+
import { A as FootnoteDefinition, C as CriticComment, D as DefinitionDescription, E as CriticInsertion, M as InlineFootnote, O as DefinitionList, S as ComarkSlot, T as CriticHighlight, _ as ComarkComment, a as Upload, b as ComarkKit, c as startUploads, d as EditorDocument, f as MarkdownCheck, g as ComarkBlock, h as toMarkdown, i as PendingUpload, j as FootnoteReference, k as DefinitionTerm, l as uploadKey, m as fromMarkdown, n as EditorCodecOptions, o as UploadOptions, p as checkMarkdown, r as createEditorCodec, s as findUpload, t as EditorCodec, u as uploadPlugin, v as ComarkImage, w as CriticDeletion, x as ComarkKitOptions, y as ComarkInline } from "./editor-KD97dL_1.mjs";
|
|
2
|
+
export { ComarkBlock, ComarkComment, ComarkImage, ComarkInline, ComarkKit, type ComarkKitOptions, ComarkSlot, CriticComment, CriticDeletion, CriticHighlight, CriticInsertion, DefinitionDescription, DefinitionList, DefinitionTerm, type EditorCodec, type EditorCodecOptions, type EditorDocument, FootnoteDefinition, FootnoteReference, InlineFootnote, type MarkdownCheck, type PendingUpload, Upload, type UploadOptions, checkMarkdown, createEditorCodec, findUpload, fromMarkdown, startUploads, toMarkdown, uploadKey, uploadPlugin };
|
package/dist/editor.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { u as ComarkBlock, d as ComarkComment, f as ComarkImage, p as ComarkInline, m as ComarkKit, h as ComarkSlot, n as Upload, s as checkMarkdown, t as createEditorCodec, r as findUpload, c as fromMarkdown, i as startUploads, l as toMarkdown, a as uploadKey, o as uploadPlugin } from "./editor-
|
|
1
|
+
export { u as ComarkBlock, d as ComarkComment, f as ComarkImage, p as ComarkInline, m as ComarkKit, h as ComarkSlot, g as CriticComment, _ as CriticDeletion, v as CriticHighlight, y as CriticInsertion, b as DefinitionDescription, x as DefinitionList, S as DefinitionTerm, C as FootnoteDefinition, w as FootnoteReference, T as InlineFootnote, n as Upload, s as checkMarkdown, t as createEditorCodec, r as findUpload, c as fromMarkdown, i as startUploads, l as toMarkdown, a as uploadKey, o as uploadPlugin } from "./editor-DmxNPK7K.mjs";
|
package/dist/html.d.mts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
import { a as criticCss, n as Preset, r as PresetOptions } from "./index-
|
|
1
|
+
import { a as criticCss, n as Preset, r as PresetOptions } from "./index-BUDHsvnm.mjs";
|
|
2
2
|
import { NodeHandler } from "comark";
|
|
3
3
|
//#region src/html.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* The text of the inline `<script>` that runs the Mermaid diagrams' Copy image and Copy source buttons. It's the same on
|
|
6
|
+
* every render and changes only between versions, so a page with a strict Content Security Policy can allow it by its
|
|
7
|
+
* hash without rendering a document first.
|
|
8
|
+
*/
|
|
9
|
+
export declare const mermaidScript: string;
|
|
4
10
|
/** Every plugin for `@comark/html`, with the `components` to render them. */
|
|
5
11
|
declare const _default: (options?: PresetOptions) => Preset<NodeHandler>;
|
|
6
12
|
//#endregion
|
package/dist/html.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { t as typesetCss } from "./typeset-css-
|
|
2
|
-
import { n as preset, t as criticCss } from "./src-
|
|
3
|
-
import { mermaidCss } from "./client.mjs";
|
|
1
|
+
import { t as typesetCss } from "./typeset-css-5aJ7cSmh.mjs";
|
|
2
|
+
import { n as preset, t as criticCss } from "./src-PkmYCSNu.mjs";
|
|
3
|
+
import { a as start, n as mermaidBar, r as mermaidCss } from "./client-Bjd6VcGQ.mjs";
|
|
4
|
+
import { escapeHtml } from "comark/utils";
|
|
4
5
|
import * as annotate from "comark-annotate/html";
|
|
5
6
|
import * as badge from "comark-badge/html";
|
|
6
7
|
import * as cards from "comark-cards/html";
|
|
@@ -11,6 +12,7 @@ import * as chips from "comark-chips/html";
|
|
|
11
12
|
import * as code from "comark-code/html";
|
|
12
13
|
import * as codeNotes from "comark-code-notes/html";
|
|
13
14
|
import * as colors from "comark-colors/html";
|
|
15
|
+
import * as comments from "comark-comments/html";
|
|
14
16
|
import * as details from "comark-details/html";
|
|
15
17
|
import * as diagrams from "comark-diagrams/html";
|
|
16
18
|
import * as diff from "comark-diff/html";
|
|
@@ -38,14 +40,31 @@ import * as tests from "comark-tests/html";
|
|
|
38
40
|
import * as zoom from "comark-zoom/html";
|
|
39
41
|
//#region src/html.ts
|
|
40
42
|
const styled = /* @__PURE__ */ new WeakSet();
|
|
41
|
-
|
|
43
|
+
/**
|
|
44
|
+
* The text of the inline `<script>` that runs the Mermaid diagrams' Copy image and Copy source buttons. It's the same on
|
|
45
|
+
* every render and changes only between versions, so a page with a strict Content Security Policy can allow it by its
|
|
46
|
+
* hash without rendering a document first.
|
|
47
|
+
*/
|
|
48
|
+
const mermaidScript = `(${start.toString()})()`;
|
|
49
|
+
const attr = (value) => escapeHtml(value, { "\"": """ });
|
|
50
|
+
/**
|
|
51
|
+
* Wraps Pele's card in `.cmm` with the bar of buttons and the source they copy. The wrapper is a wide block with the
|
|
52
|
+
* diagram's own width, so a page that gives wide blocks room shows a long flowchart at its size rather than shrinking
|
|
53
|
+
* its labels to fit the column. A drawn diagram zooms with comark-zoom unless the preset turns zoom off.
|
|
54
|
+
*/
|
|
55
|
+
const mermaid = (zooms) => ({
|
|
42
56
|
default: pele,
|
|
43
57
|
components: { pele: ((node, state) => {
|
|
44
|
-
const
|
|
58
|
+
const first = !styled.has(state.context);
|
|
45
59
|
styled.add(state.context);
|
|
46
|
-
|
|
60
|
+
const card = Pele(node);
|
|
61
|
+
const source = node[1].content;
|
|
62
|
+
const width = /^<div[^>]*><svg[^>]* width="([\d.]+)"/.exec(card)?.[1];
|
|
63
|
+
const wide = width ? ` data-wide style="--cmm-svg:${Math.ceil(Number(width))}px"` : "";
|
|
64
|
+
const zoomed = zooms && width ? card.replace(/^<div/, "<div data-zoom tabindex=\"0\"") : card;
|
|
65
|
+
return (first ? `<style data-comark-mermaid>${mermaidCss}</style>` : "") + `<div class="cmm"${wide} data-source="${attr(source)}">${zoomed}<div class="cmm-bar">${mermaidBar()}</div>${first ? `<script>${mermaidScript}<\/script>` : ""}${zooms && width ? zoom.runtime(state) : ""}</div>`;
|
|
47
66
|
}) }
|
|
48
|
-
};
|
|
67
|
+
});
|
|
49
68
|
const typeset = () => `<style data-comark-typeset>${typesetCss}</style>`;
|
|
50
69
|
/** Every plugin for `@comark/html`, with the `components` to render them. */
|
|
51
70
|
var html_default = (options) => preset({
|
|
@@ -59,6 +78,7 @@ var html_default = (options) => preset({
|
|
|
59
78
|
code,
|
|
60
79
|
codeNotes,
|
|
61
80
|
colors,
|
|
81
|
+
comments,
|
|
62
82
|
details,
|
|
63
83
|
diagrams,
|
|
64
84
|
diff,
|
|
@@ -72,7 +92,7 @@ var html_default = (options) => preset({
|
|
|
72
92
|
mark,
|
|
73
93
|
math,
|
|
74
94
|
media,
|
|
75
|
-
mermaid,
|
|
95
|
+
mermaid: mermaid(options?.zoom !== false),
|
|
76
96
|
metrics,
|
|
77
97
|
outline,
|
|
78
98
|
properties,
|
|
@@ -87,4 +107,4 @@ var html_default = (options) => preset({
|
|
|
87
107
|
zoom
|
|
88
108
|
}, options);
|
|
89
109
|
//#endregion
|
|
90
|
-
export { criticCss, html_default as default };
|
|
110
|
+
export { criticCss, html_default as default, mermaidScript };
|
|
@@ -12,6 +12,7 @@ import { CastOptions } from "comark-cast";
|
|
|
12
12
|
import { ChartsOptions } from "comark-charts";
|
|
13
13
|
import { ChipsOptions } from "comark-chips";
|
|
14
14
|
import { CodeOptions } from "comark-code";
|
|
15
|
+
import { CommentsOptions } from "comark-comments";
|
|
15
16
|
import { DetailsOptions } from "comark-details";
|
|
16
17
|
import { DiagramsOptions } from "comark-diagrams";
|
|
17
18
|
import { FileTreeOptions } from "comark-file-tree";
|
|
@@ -19,6 +20,7 @@ import { CalloutsOptions, ReferencesOptions } from "comark-github";
|
|
|
19
20
|
import { AnchorsOptions, ExternalOptions } from "comark-links";
|
|
20
21
|
import { MathOptions } from "comark-mathml";
|
|
21
22
|
import { MediaOptions } from "comark-media";
|
|
23
|
+
import { OutlineOptions } from "comark-outline";
|
|
22
24
|
import { PeleConfig } from "comark-pele";
|
|
23
25
|
import { PropertiesOptions } from "comark-properties";
|
|
24
26
|
import { QuizOptions } from "comark-quiz";
|
|
@@ -53,6 +55,11 @@ type PresetOptions = {
|
|
|
53
55
|
/** Pass `{ download: false }` when parsing in a browser, which may not download another site's images. */
|
|
54
56
|
chips?: ChipsOptions | boolean;
|
|
55
57
|
colors?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* HTML only: Vue, React, and Svelte have no comments components. `{ mark: "pen" }` draws suggestions with a
|
|
60
|
+
* hand-drawn pen unless one sets its own `mark`.
|
|
61
|
+
*/
|
|
62
|
+
comments?: CommentsOptions | boolean;
|
|
56
63
|
/** Sends each diagram's source to `https://kroki.io` unless you pass your own `server`, or `{ draw: false }`. */
|
|
57
64
|
diagrams?: DiagramsOptions | boolean;
|
|
58
65
|
/** Draws `mermaid` fences with comark-pele, on the server and offline. */
|
|
@@ -94,7 +101,8 @@ type PresetOptions = {
|
|
|
94
101
|
steps?: boolean;
|
|
95
102
|
readingTime?: ReadingTimeOptions | boolean;
|
|
96
103
|
tabs?: TabsOptions | boolean;
|
|
97
|
-
outline
|
|
104
|
+
/** `{ rail: true }` adds a side outline beside the text of every document with two headings or more. Off by default. */
|
|
105
|
+
outline?: OutlineOptions | boolean;
|
|
98
106
|
xref?: XrefOptions | boolean;
|
|
99
107
|
/** Reads no JUnit reports unless you pass `{ root }` or `{ read }`; inline reports render either way. */
|
|
100
108
|
tests?: TestsOptions | boolean;
|
|
@@ -120,6 +128,7 @@ type Renderer<C> = {
|
|
|
120
128
|
charts: Part<C, ChartsOptions>;
|
|
121
129
|
chips: Part<C, ChipsOptions>;
|
|
122
130
|
colors: Part<C>;
|
|
131
|
+
comments?: Part<C, CommentsOptions>;
|
|
123
132
|
diagrams: Part<C, DiagramsOptions>;
|
|
124
133
|
mermaid: Part<C, PeleConfig>;
|
|
125
134
|
diff?: Part<C>;
|
|
@@ -155,7 +164,7 @@ type Renderer<C> = {
|
|
|
155
164
|
sources: Part<C>;
|
|
156
165
|
steps: Part<C>;
|
|
157
166
|
tabs: Part<C, TabsOptions>;
|
|
158
|
-
outline: Part<C>;
|
|
167
|
+
outline: Part<C, OutlineOptions>;
|
|
159
168
|
tests: Part<C, TestsOptions>;
|
|
160
169
|
zoom: Part<C, ZoomOptions>;
|
|
161
170
|
code: Part<C, CodeOptions>;
|
package/dist/index.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { t as typesetCss } from "./typeset-css-DdOGL7WF.mjs";
|
|
2
|
-
import { a as criticCss, c as typeset, i as Renderer, n as Preset, o as preset, r as PresetOptions, s as TYPESET_TAG, t as AnyPlugin } from "./index-
|
|
2
|
+
import { a as criticCss, c as typeset, i as Renderer, n as Preset, o as preset, r as PresetOptions, s as TYPESET_TAG, t as AnyPlugin } from "./index-BUDHsvnm.mjs";
|
|
3
3
|
export { AnyPlugin, Preset, PresetOptions, Renderer, TYPESET_TAG, criticCss, preset, typeset, typesetCss };
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { t as typesetCss } from "./typeset-css-
|
|
2
|
-
import { i as typeset, n as preset, r as TYPESET_TAG, t as criticCss } from "./src-
|
|
1
|
+
import { t as typesetCss } from "./typeset-css-5aJ7cSmh.mjs";
|
|
2
|
+
import { i as typeset, n as preset, r as TYPESET_TAG, t as criticCss } from "./src-PkmYCSNu.mjs";
|
|
3
3
|
export { TYPESET_TAG, criticCss, preset, typeset, typesetCss };
|
package/dist/react.d.mts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { a as criticCss, n as Preset, r as PresetOptions } from "./index-
|
|
1
|
+
import { a as criticCss, n as Preset, r as PresetOptions } from "./index-BUDHsvnm.mjs";
|
|
2
2
|
import { ComponentType } from "react";
|
|
3
3
|
//#region src/react.d.ts
|
|
4
4
|
type AnyComponent = ComponentType<any>;
|
|
5
|
-
/** Every plugin with components for `@comark/react`, which leaves out annotate, diff, and quiz. */
|
|
5
|
+
/** Every plugin with components for `@comark/react`, which leaves out annotate, comments, diff, and quiz. */
|
|
6
6
|
declare const _default: (options?: PresetOptions) => Preset<AnyComponent>;
|
|
7
7
|
//#endregion
|
|
8
8
|
export { type PresetOptions, criticCss, _default as default };
|
package/dist/react.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { t as typesetCss } from "./typeset-css-
|
|
2
|
-
import { n as preset, t as criticCss } from "./src-
|
|
3
|
-
import { addMermaidStyles } from "./client.mjs";
|
|
4
|
-
import { createElement } from "react";
|
|
1
|
+
import { t as typesetCss } from "./typeset-css-5aJ7cSmh.mjs";
|
|
2
|
+
import { n as preset, t as criticCss } from "./src-PkmYCSNu.mjs";
|
|
3
|
+
import { i as startMermaid, n as mermaidBar, t as addMermaidStyles } from "./client-Bjd6VcGQ.mjs";
|
|
4
|
+
import { createElement, useEffect } from "react";
|
|
5
5
|
import * as badge from "comark-badge/react";
|
|
6
6
|
import * as cards from "comark-cards/react";
|
|
7
7
|
import * as carousel from "comark-carousel/react";
|
|
@@ -35,15 +35,29 @@ import * as tabs from "comark-tabs/react";
|
|
|
35
35
|
import * as tests from "comark-tests/react";
|
|
36
36
|
import * as zoom from "comark-zoom/react";
|
|
37
37
|
//#region src/react.ts
|
|
38
|
+
const Pele = createPeleComponent({
|
|
39
|
+
onRender: addMermaidStyles,
|
|
40
|
+
onError: addMermaidStyles
|
|
41
|
+
});
|
|
42
|
+
function Mermaid(props) {
|
|
43
|
+
useEffect(() => startMermaid(), []);
|
|
44
|
+
return createElement("div", {
|
|
45
|
+
className: "cmm",
|
|
46
|
+
"data-source": props.content
|
|
47
|
+
}, createElement(Pele, props), createElement("div", {
|
|
48
|
+
className: "cmm-bar",
|
|
49
|
+
dangerouslySetInnerHTML: { __html: mermaidBar() }
|
|
50
|
+
}));
|
|
51
|
+
}
|
|
38
52
|
const mermaid = {
|
|
39
53
|
default: pele,
|
|
40
|
-
components: { pele:
|
|
54
|
+
components: { pele: Mermaid }
|
|
41
55
|
};
|
|
42
56
|
const typeset = () => createElement("style", {
|
|
43
57
|
"data-comark-typeset": "",
|
|
44
58
|
dangerouslySetInnerHTML: { __html: typesetCss }
|
|
45
59
|
});
|
|
46
|
-
/** Every plugin with components for `@comark/react`, which leaves out annotate, diff, and quiz. */
|
|
60
|
+
/** Every plugin with components for `@comark/react`, which leaves out annotate, comments, diff, and quiz. */
|
|
47
61
|
var react_default = (options) => preset({
|
|
48
62
|
badge,
|
|
49
63
|
cards,
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: before-after-evidence
|
|
3
|
+
description: Shows a visible change as two comparable screenshots, before and after, with marks measured from the source and checked in the rendered page. Use when a pull request, bug fix, or design change alters what people see, or when someone asks for before/after screenshots or visual evidence.
|
|
4
|
+
license: MIT
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Before/after evidence
|
|
8
|
+
|
|
9
|
+
A before/after is evidence when a reviewer can check every claim against the two images and nothing else. Three things make it so, and the reader can't repair any of them: two captures of the same view, marks that sit on what changed, and notes in the words the screen shows.
|
|
10
|
+
|
|
11
|
+
This skill writes the document. Where it's published, and who can open it, is up to your host.
|
|
12
|
+
|
|
13
|
+
## 1. Capture a comparable pair
|
|
14
|
+
|
|
15
|
+
Take **after** from the branch or its preview, and **before** from a deployment or commit that still behaves the old way. Capture both with the same viewport, zoom, theme, data, scroll position, and open menus, so the change is the only difference.
|
|
16
|
+
|
|
17
|
+
- Set up the state that shows the change before you capture: the long name that wrapped, the error that stayed hidden, the empty list.
|
|
18
|
+
- Clip both captures to one region around the change, the same rectangle on each side. A `::compare` gives each image under half the page width, where a full-page capture's text is too small to read.
|
|
19
|
+
- Pin anything that moves the layout between the two states, such as a dialog centered vertically that grows by one line, so the same element sits at the same place in both.
|
|
20
|
+
|
|
21
|
+
If one side can't be captured comparably, stop and say what blocked you. A description in place of a screenshot, or one side alone, isn't before/after evidence.
|
|
22
|
+
|
|
23
|
+
Done when both images exist, have the same size, and differ only where the change is.
|
|
24
|
+
|
|
25
|
+
## 2. Measure every mark
|
|
26
|
+
|
|
27
|
+
Marks take `x`, `y`, `w`, and `h` as percentages of the image. Measure them: an estimate drifts a few percent, and on a half-width image that's the neighbouring button.
|
|
28
|
+
|
|
29
|
+
- **A page you captured:** read the element's box in the same browser, viewport, and state, minus the clip's offset. [references/measuring.md](references/measuring.md) has the snippet.
|
|
30
|
+
- **A still you didn't capture**, such as a frame from a screen recording, a design export, or an image attached to a bug report: there is no DOM to ask. Measure in image pixels and divide by the image's natural width and height. Confirm each box by cropping the image to it and looking at the crop, as the same reference shows.
|
|
31
|
+
|
|
32
|
+
Mark the change at its own size: the field, the label, the button. Use `red` on the before side for the problem and `green` on the after side for the fix, and leave what stayed the same unmarked. Two or three marks a side usually tell the whole story.
|
|
33
|
+
|
|
34
|
+
Done when every mark has numbers you measured, and you can name the element or the pixel rectangle each came from.
|
|
35
|
+
|
|
36
|
+
## 3. Write the document
|
|
37
|
+
|
|
38
|
+
Start from [references/example.md](references/example.md) and keep its shape:
|
|
39
|
+
|
|
40
|
+
1. One sentence: what changed, and for whom.
|
|
41
|
+
2. One line of steps to reach the screen, so a reviewer can reproduce it.
|
|
42
|
+
3. The `::compare`, each note a few words in the screen's own words. A value the screenshot doesn't show stays out of its note.
|
|
43
|
+
4. A `::diff` of the line that caused it, only when the reader would otherwise ask.
|
|
44
|
+
|
|
45
|
+
The images carry the evidence, so the text only points into them. How the work went (the checks you ran, retries, CI) goes in your report to the user, not in the document. [references/blocks.md](references/blocks.md) has the syntax of each block.
|
|
46
|
+
|
|
47
|
+
Image `src` must be a URL the renderer can reach: a path next to the document, or an https URL your host gives you for the upload.
|
|
48
|
+
|
|
49
|
+
## 4. Check the render
|
|
50
|
+
|
|
51
|
+
1. Lint it, and fix until it reports no problems:
|
|
52
|
+
|
|
53
|
+
```sh
|
|
54
|
+
vp dlx --package comark-linter --package comark-ui lint-comark evidence.md
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
These commands use the [global Vite+ CLI](https://viteplus.dev/guide/global-cli). Without it, `pnpm dlx` takes the same arguments.
|
|
58
|
+
|
|
59
|
+
2. Open the page where it will be read and take a screenshot of it. For a local screenshot-only check, copy the complete `::compare` block, including its nested screenshots and annotations, into `evidence-screenshots.md` beside `evidence.md`.
|
|
60
|
+
|
|
61
|
+
Ensure comark-annotate is a direct dependency of this workspace package. If it is only transitive, read the installed Comark UI version and add that exact version with the project's package manager: for pnpm, `pnpm add -D comark-annotate@<version>`, substituting that version. Add `-w` when installing at the workspace root. With no Comark UI packages installed, omit `@<version>`. This links the executable without fetching a different renderer release via `@latest`. Then run:
|
|
62
|
+
|
|
63
|
+
```sh
|
|
64
|
+
vp exec comark-annotate render evidence-screenshots.md -o evidence-screenshots.html
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Without Vite+, use `pnpm exec` with the same arguments.
|
|
68
|
+
|
|
69
|
+
Open `evidence-screenshots.html` and take a screenshot of it. This CLI renders annotate, carousel, and zoom only; check any `::diff` or other blocks in the host's full Comark UI preview.
|
|
70
|
+
3. Check that each mark sits on its target and each note matches what its side shows. Measure a mark that misses again, from the source, since a box moved by eye stays a guess.
|
|
71
|
+
|
|
72
|
+
Done when you've looked at the rendered page and every mark lands. Name any mark or block you couldn't check in your report.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Blocks for before/after evidence
|
|
2
|
+
|
|
3
|
+
These blocks come with `comark-ui`, or alone with `comark-annotate` and `comark-diff`. The comark-ui skill (`vp dlx skills add onmax/comark-ui`) documents every block in full.
|
|
4
|
+
|
|
5
|
+
## `::compare`
|
|
6
|
+
|
|
7
|
+
Two `:::screenshot` blocks inside, before then after. They're titled Before and After unless they set `title`, and their notes are numbered across both.
|
|
8
|
+
|
|
9
|
+
| Prop | What it does |
|
|
10
|
+
| --- | --- |
|
|
11
|
+
| `title` | Names the comparison for screen readers. |
|
|
12
|
+
| `mode` | `columns` (default) side by side, or `slider`: one full-width image with a divider to drag. Use `slider` when the change is small and in the same spot, such as one label. |
|
|
13
|
+
|
|
14
|
+
## `:::screenshot`
|
|
15
|
+
|
|
16
|
+
| Prop | What it does |
|
|
17
|
+
| --- | --- |
|
|
18
|
+
| `src` | Required. The image URL. |
|
|
19
|
+
| `alt` | Required. What the image shows, in one phrase. |
|
|
20
|
+
| `viewport` | The capture's size, like `640x420`. Set the same on both sides; a compare reports a mismatch. |
|
|
21
|
+
| `href` | The page you captured, such as the preview deployment, linked by its host above the image. |
|
|
22
|
+
| `title` | A heading above the image, in place of Before or After. |
|
|
23
|
+
|
|
24
|
+
Other Markdown inside the block, after its annotations, becomes the caption.
|
|
25
|
+
|
|
26
|
+
## `::::annotation`
|
|
27
|
+
|
|
28
|
+
A direct child of a screenshot. Its content is the note, in Markdown.
|
|
29
|
+
|
|
30
|
+
| Prop | What it does |
|
|
31
|
+
| --- | --- |
|
|
32
|
+
| `x` `y` `w` `h` | Required. The marked rectangle as percentages of the image, without `%`. |
|
|
33
|
+
| `mark` | `box` (default), `circle`, `underline`, `highlight`, `bracket`, `cross`, `check`, or `none`. |
|
|
34
|
+
| `color` | `red` for a problem, `green` for the fix, `amber` for a warning, `violet` (default) to point something out, `gray`, or a hex color. |
|
|
35
|
+
| `side` | `top` or `bottom` moves the note into the margin with an arrow; in a side-by-side compare, `left` and `right` notes join the numbered list. |
|
|
36
|
+
|
|
37
|
+
Notes without a `side` are numbered under their image, which is the clearest default in a compare.
|
|
38
|
+
|
|
39
|
+
## `::diff`
|
|
40
|
+
|
|
41
|
+
Two fenced blocks inside, the file before and after, starting at the same line.
|
|
42
|
+
|
|
43
|
+
````md
|
|
44
|
+
::diff{line=42 label="The change"}
|
|
45
|
+
```tsx [src/members/InviteDialog.tsx]
|
|
46
|
+
<button onClick={send}>Send invite</button>
|
|
47
|
+
```
|
|
48
|
+
```tsx
|
|
49
|
+
<button onClick={send} disabled={invalid}>Send invite</button>
|
|
50
|
+
```
|
|
51
|
+
::
|
|
52
|
+
````
|
|
53
|
+
|
|
54
|
+
`line` is the file's line number of the first line in both blocks. Keep a diff to the few lines that caused the change; the pull request has the rest.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
The invite dialog now says what's wrong with an address, and waits for a valid one before it sends.
|
|
2
|
+
|
|
3
|
+
Open **Settings › Members**, select **Invite**, type `maria@acme`, and press Tab.
|
|
4
|
+
|
|
5
|
+
::compare{title="Invite dialog with an incomplete address"}
|
|
6
|
+
:::screenshot{src="https://comark-ui.onmax.me/skill-invite-before.png" alt="Invite dialog with a red email field and no message" viewport="640x420"}
|
|
7
|
+
::::annotation{x=8.3 y=42.9 w=60.6 h=12.8 color="red"}
|
|
8
|
+
Only the border turns red. Nothing says what to fix.
|
|
9
|
+
::::
|
|
10
|
+
|
|
11
|
+
::::annotation{x=72 y=63.5 w=19.7 h=11.5 color="red"}
|
|
12
|
+
**Send invite** still sends to `maria@acme`.
|
|
13
|
+
::::
|
|
14
|
+
:::
|
|
15
|
+
|
|
16
|
+
:::screenshot{src="https://comark-ui.onmax.me/skill-invite-after.png" alt="Invite dialog with an error under the email field and a disabled Send invite button" viewport="640x420" href="https://pr-218.preview.acme.example/settings/members"}
|
|
17
|
+
::::annotation{x=8.3 y=58.3 w=49 h=5.8 mark="underline" color="green"}
|
|
18
|
+
"Add the domain, like maria@acme.com"
|
|
19
|
+
::::
|
|
20
|
+
|
|
21
|
+
::::annotation{x=72 y=71.8 w=19.7 h=11.5 color="green"}
|
|
22
|
+
**Send invite** waits for a valid address.
|
|
23
|
+
::::
|
|
24
|
+
:::
|
|
25
|
+
::
|
|
26
|
+
|
|
27
|
+
::diff{line=42 label="The change"}
|
|
28
|
+
```tsx [src/members/InviteDialog.tsx]
|
|
29
|
+
<input id="email" aria-invalid={invalid} value={email} onChange={edit} />
|
|
30
|
+
<button className="primary" onClick={send}>Send invite</button>
|
|
31
|
+
```
|
|
32
|
+
```tsx
|
|
33
|
+
<input id="email" aria-invalid={invalid} aria-describedby="email-error" value={email} onChange={edit} />
|
|
34
|
+
{invalid && <p id="email-error" className="error">Add the domain, like {suggestion}</p>}
|
|
35
|
+
<button className="primary" onClick={send} disabled={invalid}>Send invite</button>
|
|
36
|
+
```
|
|
37
|
+
::
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Measuring marks
|
|
2
|
+
|
|
3
|
+
Every mark is `x y w h`, each a percentage of the image from 0 to 100. Measure in the same coordinates the image was captured in.
|
|
4
|
+
|
|
5
|
+
## A page you captured
|
|
6
|
+
|
|
7
|
+
Capture both states with one clip, then read each element's box in the same page, before anything moves:
|
|
8
|
+
|
|
9
|
+
```js
|
|
10
|
+
// Playwright: one clip for both sides, so the same element sits at the same place.
|
|
11
|
+
const clip = { x: 56, y: 12, width: 528, height: 312 };
|
|
12
|
+
await page.screenshot({ path: "after.png", clip });
|
|
13
|
+
|
|
14
|
+
const box = await page.$eval("#email", (el, clip) => {
|
|
15
|
+
const r = el.getBoundingClientRect();
|
|
16
|
+
return [
|
|
17
|
+
((r.x - clip.x) / clip.width) * 100,
|
|
18
|
+
((r.y - clip.y) / clip.height) * 100,
|
|
19
|
+
(r.width / clip.width) * 100,
|
|
20
|
+
(r.height / clip.height) * 100,
|
|
21
|
+
].map((v) => +v.toFixed(1));
|
|
22
|
+
}, clip);
|
|
23
|
+
// box is [x, y, w, h] for the annotation.
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
- Without a clip, divide by `innerWidth` and `innerHeight` and subtract nothing.
|
|
27
|
+
- For a full-page capture, add `scrollX` and `scrollY` to the box and divide by `document.documentElement.scrollWidth` and `scrollHeight`.
|
|
28
|
+
- An element that spans its container, such as a block paragraph, measures as wide as the container. Measure the text instead: give it `width: fit-content` while you capture, or measure a `Range` around its text.
|
|
29
|
+
- If an element crosses the clip's edge, cut its box at the edge, so every value stays between 0 and 100.
|
|
30
|
+
|
|
31
|
+
## A still you didn't capture
|
|
32
|
+
|
|
33
|
+
A frame from a screen recording, a design export, or an image attached to an issue has no DOM. Measure in pixels:
|
|
34
|
+
|
|
35
|
+
1. Read the image's natural size, such as with `magick identify frame.png` or `file frame.png`.
|
|
36
|
+
2. Find the target's rectangle in pixels in an image viewer that shows the pointer's coordinates.
|
|
37
|
+
3. Divide: `x = left / width * 100`, `y = top / height * 100`, `w = boxWidth / width * 100`, `h = boxHeight / height * 100`.
|
|
38
|
+
4. Crop the image to that rectangle and look at the crop. It should show the target and little else:
|
|
39
|
+
|
|
40
|
+
```sh
|
|
41
|
+
magick frame.png -crop 320x38+44+134 +repage crop.png
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
With Python and Pillow, `Image.open("frame.png").crop((44, 134, 364, 172)).save("crop.png")` does the same.
|
|
45
|
+
|
|
46
|
+
For a pair of video frames, take both at the same playback size and use the same crop for both, as you would clip two page captures.
|
|
47
|
+
|
|
48
|
+
## In the render
|
|
49
|
+
|
|
50
|
+
The rendered page is the last check. A mark that misses there has the wrong numbers: measure it again from the source.
|
|
@@ -15,6 +15,8 @@ Prefer `comark-ui`, every plugin in one install, registered in the order they ne
|
|
|
15
15
|
pnpm add comark @comark/html comark-ui
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
+
Run the comark CLIs with the [global Vite+ CLI](https://viteplus.dev/guide/global-cli): `vp dlx` for a package the project doesn't install, `vp exec` for one it does. Without Vite+, `pnpm dlx` and `pnpm exec` take the same arguments.
|
|
19
|
+
|
|
18
20
|
```ts
|
|
19
21
|
import { createHtmlRenderer } from "@comark/html";
|
|
20
22
|
import comarkUi from "comark-ui/html";
|
|
@@ -43,6 +45,10 @@ Either way, the HTML renderer inlines the styles once per document, and the Vue,
|
|
|
43
45
|
|
|
44
46
|
Problems land in `meta.issues` after `parseMarkdown`, one sentence each, and a host can refuse a document while any remain. For untrusted input, add Comark's `security` plugin with `blockedTags` such as `script`, `style`, and `iframe`; it cleans the Markdown inside blocks too.
|
|
45
47
|
|
|
48
|
+
## Shape the document
|
|
49
|
+
|
|
50
|
+
This skill teaches the blocks. Four sibling skills teach a whole document, what goes in it and in what order: `before-after-evidence`, `review-document`, `visual-explanation`, and `teach-lesson`. When the user asks for one of those and the skill isn't installed, suggest `vp dlx skills add onmax/comark-ui` and picking it from the list.
|
|
51
|
+
|
|
46
52
|
## Pick the blocks
|
|
47
53
|
|
|
48
54
|
Read the reference for each block you use before you write it. Mix the blocks freely with ordinary Markdown, such as headings, tables, and lists.
|
|
@@ -55,10 +61,11 @@ Read the reference for each block you use before you write it. Mix the blocks fr
|
|
|
55
61
|
| A change on screen, before and after | `::compare` | [annotate](references/annotate.md) |
|
|
56
62
|
| A command's output, such as a test run or a build, as colored text | `::cast` | [cast](references/cast.md) |
|
|
57
63
|
| Numbers, such as sizes, timings, before/after metrics, a trend, or a timeline | `::chart` | [charts](references/charts.md) |
|
|
58
|
-
| A flow, a sequence, an architecture, or a schema as a diagram | a `d2`, `dot`, `plantuml`, `dbml`, `goat`, or `svgbob` fence | [diagrams](references/diagrams.md) |
|
|
64
|
+
| A flow, a sequence, an architecture, or a schema as a diagram | a `mermaid`, `d2`, `dot`, `plantuml`, `dbml`, `goat`, or `svgbob` fence | [diagrams](references/diagrams.md) |
|
|
59
65
|
| Links and `@mentions` with the site's favicon or the person's avatar | links, `@user`, `:chip` | [chips](references/chips.md) |
|
|
60
66
|
| Colors, such as design tokens before and after, or a palette | a color in inline code, `::palette` | [colors](references/colors.md) |
|
|
61
67
|
| A suggested change to one file, before and after | `::diff` | [diff](references/diff.md) |
|
|
68
|
+
| Suggested edits and comment threads on prose, such as a copy review, each note in a card in the margin | `:suggestion`, `:comment` | [comments](references/comments.md) |
|
|
62
69
|
| A video, a design file, or a live reproduction from its link | `::embed` | [embed](references/embed.md) |
|
|
63
70
|
| A screen recording or a sound that a screenshot can't show | `` | [media](references/media.md) |
|
|
64
71
|
| A number before and after, a table of befores and afters, or progress | `:delta`, `::stats`, `:progress` | [metrics](references/metrics.md) |
|
|
@@ -134,5 +141,5 @@ Mark only what your text talks about. Each note says what changed or what is wro
|
|
|
134
141
|
|
|
135
142
|
## Check the result
|
|
136
143
|
|
|
137
|
-
1. Lint the file: `
|
|
144
|
+
1. Lint the file: `vp exec lint-comark report.md`, in a project with `comark-linter` and the plugins installed, where `comark-ui` counts as every plugin. It prints one line per problem with its line, its rule, and how to fix it, and exits with 1 while any remain. Fix every one, and run it again until it exits with 0. The [lint reference](references/lint.md) covers its flags, its config file, the library, ESLint, and Vite Doctor.
|
|
138
145
|
2. Look at the render, made as the block's reference says. Open it in a browser and take a screenshot: each mark sits on its target, each number matches its note, and each chart says what your text says. If you can't verify something, say so when you hand the document over instead of guessing.
|
|
@@ -53,11 +53,13 @@ For a clipped capture, `getBoundingClientRect()` and Playwright's main-frame `cl
|
|
|
53
53
|
|
|
54
54
|
## Preview
|
|
55
55
|
|
|
56
|
+
Ensure comark-annotate is a direct dependency of the workspace package where you run the CLI. If it is only transitive, read the installed Comark UI version and add that exact version with the project's package manager: for pnpm, `pnpm add -D comark-annotate@<version>`, substituting that version. Add `-w` when installing at the workspace root. With no Comark UI packages installed, omit `@<version>`. This links the executable without fetching a different renderer release via `@latest`.
|
|
57
|
+
|
|
56
58
|
```sh
|
|
57
|
-
|
|
59
|
+
vp exec comark-annotate render report.md -o report.html
|
|
58
60
|
```
|
|
59
61
|
|
|
60
|
-
`render` writes a standalone page of the screenshots and compares, and relative `src` paths resolve next to it. Without comark-linter, `
|
|
62
|
+
`render` writes a standalone page of the screenshots and compares, and relative `src` paths resolve next to it. Without comark-linter, `vp exec comark-annotate check report.md` lists these blocks' problems on its own. It names each one like `screenshot "after.png", annotation 2`, counting annotations within their screenshot, and exits with 1 while any remain.
|
|
61
63
|
|
|
62
64
|
## Register
|
|
63
65
|
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Suggestions and comments
|
|
2
|
+
|
|
3
|
+
comark-comments draws suggested edits and comments on a span of prose, each with its note in a card in the margin beside its line, as in a Google Docs or Word review. Use it to review copy or a docs page, where each change needs a reason and a comment can get a reply. For marks with no notes or margin, which a host can also accept or reject, use [critic](critic.md). For a change to code, write a `::diff`.
|
|
4
|
+
|
|
5
|
+
## Syntax
|
|
6
|
+
|
|
7
|
+
```md
|
|
8
|
+
To :suggestion[sign in]{from="log in" by="Claude" note="The button says Sign in."}, enter your email.
|
|
9
|
+
|
|
10
|
+
:suggestion[]{from="simply" by="Claude" note="“Simply” tells a stuck reader it should have been easy."} Enter the email you signed up with.
|
|
11
|
+
|
|
12
|
+
The link expires after :comment[15 minutes]{#ttl by="@onmax" note="Is 15 minutes enough when email is slow?"}.
|
|
13
|
+
|
|
14
|
+
:comment{reply="ttl" by="Claude" note="Keeping 15. The email has a resend button."}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
| Write | Is |
|
|
18
|
+
| --- | --- |
|
|
19
|
+
| `:suggestion[new]{from="old"}` | A replacement: `old` struck, `new` inserted |
|
|
20
|
+
| `:suggestion[]{from="old"}` or `:suggestion{from="old"}` | A deletion |
|
|
21
|
+
| `:suggestion[new]` | An insertion |
|
|
22
|
+
| `:comment[words]{note="…"}` | A comment on `words` |
|
|
23
|
+
| `:comment{reply="id" note="…"}` | A reply to the comment or suggestion with `#id` |
|
|
24
|
+
|
|
25
|
+
| Prop | On | What it does |
|
|
26
|
+
| --- | --- | --- |
|
|
27
|
+
| `from` | suggestion | The text it replaces or deletes. Plain text. |
|
|
28
|
+
| `by` | both, reply | The author, shown as written; a leading `@` is dropped. The avatar is the name's initial. |
|
|
29
|
+
| `note` | both, reply | The card's text. Plain text. A suggestion with no note and no replies is only a redline, with no card. |
|
|
30
|
+
| `mark` | suggestion | `track` (default): red strike, green insert. `pen`: a hand-drawn strike with the new words handwritten above. |
|
|
31
|
+
| `#id` | both | The id a reply points at. Comments and suggestions share one id space. |
|
|
32
|
+
| `reply` | reply | The `#id` of the thread it joins. |
|
|
33
|
+
|
|
34
|
+
- A reply can sit anywhere in the document; it moves into its thread, and the paragraph it leaves empty is dropped. Put replies after the paragraph, or at the end.
|
|
35
|
+
- Pen fits short changes only: both sides 24 characters or fewer, on one line, and plain text. Anything else draws as `track`, with no issue.
|
|
36
|
+
- Write suggestions and comments in paragraphs and list items. In a heading or a table cell, and inside another one, they draw without a card, and the linter reports them.
|
|
37
|
+
- On a page 50rem wide or more, each card sits in the right margin level with its line. On a narrow page the reader clicks a bubble to open its card under the line.
|
|
38
|
+
- Don't overlap two anchors. Mark the words once, and reply to the thread.
|
|
39
|
+
|
|
40
|
+
## Register
|
|
41
|
+
|
|
42
|
+
- In `comark-ui`: on, as `comments`, in `comark-ui/html` only. `comments: { mark: "pen" }` draws every suggestion with the pen unless it sets its own `mark`.
|
|
43
|
+
- Alone: `pnpm add comark @comark/html comark-comments`, then `createHtmlRenderer({ plugins: [comments()], components })` with `comments, { components }` from `comark-comments/html`. There are no Vue, React, or Svelte entries.
|
|
@@ -21,10 +21,16 @@ queue -> map: pigeon pin
|
|
|
21
21
|
| `goat` or `svgbob` | ASCII art, as lines and arrows |
|
|
22
22
|
|
|
23
23
|
- The title in brackets after the language goes under the diagram and names it for screen readers. Give every diagram one.
|
|
24
|
-
- Every other fence stays code, `mermaid
|
|
24
|
+
- Every other fence stays code, except `mermaid`, which comark-ui draws with comark-pele (see Mermaid below).
|
|
25
25
|
- A diagram Kroki can't draw stays code, and `meta.issues` quotes the tool's error. So does one drawn while the server can't be reached; the next parse tries again.
|
|
26
26
|
- The plugin drops anything that could run from the SVG: scripts, event handlers, embedded HTML, and animations. Write labels as plain text. A D2 Markdown label (`|md … |`) is embedded HTML, so it comes out empty, and nothing reports it.
|
|
27
27
|
|
|
28
|
+
## Mermaid
|
|
29
|
+
|
|
30
|
+
Through comark-ui, a ` ```mermaid ` fence is drawn as SVG by comark-pele while rendering, with no network, and themed with the other blocks. A diagram Pele can't draw shows its source, and nothing goes in `meta.issues`, so check it in a render.
|
|
31
|
+
|
|
32
|
+
With `comark-ui/html`, a click, `Enter`, or `Space` zooms the diagram, and its buttons copy it as a PNG on the page's background or as its ` ```mermaid ` fence. The Vue, React, and Svelte entries draw the same buttons, and Pele zooms the diagram in place there. `zoom: false` in `comarkUi()` turns the zoom off; the buttons stay. A host with a strict Content Security Policy allows the buttons' script by the hash of `mermaidScript` from `comark-ui/html`, and Copy image needs `img-src data:`.
|
|
33
|
+
|
|
28
34
|
## Check each diagram
|
|
29
35
|
|
|
30
36
|
Send an internal architecture or a schema with sensitive names only to the host's own Kroki server. With the default `server`, each diagram's source goes to `https://kroki.io`, a public service.
|