comark-ui 0.7.6 → 0.8.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.
Files changed (44) hide show
  1. package/README.md +2 -2
  2. package/dist/{client-Bjd6VcGQ.mjs → client-BhzMlpun.mjs} +17 -7
  3. package/dist/client.mjs +1 -1
  4. package/dist/{editor-DmxNPK7K.mjs → editor-ASZBrUYa.mjs} +10 -11
  5. package/dist/editor-vue.d.mts +20 -4
  6. package/dist/editor-vue.mjs +40 -9
  7. package/dist/editor.mjs +1 -1
  8. package/dist/html.d.mts +1 -1
  9. package/dist/html.mjs +6 -2
  10. package/dist/{index-Dbqxt4Qg.d.mts → index-DVGSDzBS.d.mts} +1 -1
  11. package/dist/index.d.mts +1 -1
  12. package/dist/react.d.mts +1 -1
  13. package/dist/react.mjs +1 -1
  14. package/dist/skills/before-after-evidence/SKILL.md +11 -13
  15. package/dist/skills/before-after-evidence/references/blocks.md +1 -1
  16. package/dist/skills/comark-ui/SKILL.md +11 -9
  17. package/dist/skills/comark-ui/references/annotate.md +1 -1
  18. package/dist/skills/comark-ui/references/badge.md +1 -1
  19. package/dist/skills/comark-ui/references/cards.md +2 -1
  20. package/dist/skills/comark-ui/references/code-notes.md +1 -1
  21. package/dist/skills/comark-ui/references/code.md +3 -3
  22. package/dist/skills/comark-ui/references/comments.md +3 -3
  23. package/dist/skills/comark-ui/references/embed.md +3 -2
  24. package/dist/skills/comark-ui/references/keys.md +1 -1
  25. package/dist/skills/comark-ui/references/links.md +1 -1
  26. package/dist/skills/comark-ui/references/lint.md +21 -12
  27. package/dist/skills/comark-ui/references/magic-move.md +1 -1
  28. package/dist/skills/comark-ui/references/metrics.md +1 -0
  29. package/dist/skills/comark-ui/references/outline.md +2 -2
  30. package/dist/skills/comark-ui/references/properties.md +1 -1
  31. package/dist/skills/comark-ui/references/quiz.md +15 -3
  32. package/dist/skills/comark-ui/references/reading-time.md +1 -1
  33. package/dist/skills/comark-ui/references/steps.md +1 -1
  34. package/dist/skills/comark-ui/references/table.md +1 -0
  35. package/dist/skills/comark-ui/references/tabs.md +2 -2
  36. package/dist/skills/comark-ui/references/tests.md +1 -1
  37. package/dist/skills/comark-ui/references/ui.md +7 -6
  38. package/dist/skills/teach-lesson/SKILL.md +4 -4
  39. package/dist/skills/teach-lesson/references/blocks.md +6 -6
  40. package/dist/skills.mjs +29 -29
  41. package/dist/text-D8j9clg3.mjs +19 -0
  42. package/dist/vue.d.mts +1 -1
  43. package/dist/vue.mjs +2 -2
  44. package/package.json +45 -45
@@ -25,7 +25,7 @@ The link expires after :comment[15 minutes]{#ttl by="@onmax" note="Is 15 minutes
25
25
  | Prop | On | What it does |
26
26
  | --- | --- | --- |
27
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. |
28
+ | `by` | both, reply | The author, shown as written; a leading `@` is dropped. The avatar is the name's initial, or the image `avatars` gives that name. |
29
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
30
  | `mark` | suggestion | `track` (default): red strike, green insert. `pen`: a hand-drawn strike with the new words handwritten above. |
31
31
  | `#id` | both | The id a reply points at. Comments and suggestions share one id space. |
@@ -39,5 +39,5 @@ The link expires after :comment[15 minutes]{#ttl by="@onmax" note="Is 15 minutes
39
39
 
40
40
  ## Register
41
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.
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`. `comments: { avatars: { onmax: "https://github.com/onmax.png" } }` gives authors an image by the name in `by`, without `@`, in any case.
43
+ - Alone: `pnpm add comark @comark/html comark-comments`, then `createHtmlRenderer({ plugins: [comments()], components })` with `comments, { components }` from `comark-comments/html`, which takes the same `mark` and `avatars` options. There are no Vue, React, or Svelte entries.
@@ -1,6 +1,6 @@
1
1
  # Players and link cards
2
2
 
3
- comark-embed turns `::embed` into the provider's player, with the link under it, for YouTube, Vimeo, Loom, Spotify, CodePen, StackBlitz, and Figma, and into a link card for any other https page. It reads the player's address from the link alone and fetches nothing. Use it for a screen recording of a bug, a design file, or a live reproduction.
3
+ comark-embed turns `::embed` into the provider's player, with the link under it, for YouTube, Vimeo, Loom, Spotify, CodePen, StackBlitz, Figma, and X, and into a link card for any other https page. It reads the player's address from the link alone and fetches nothing. Use it for a screen recording of a bug, a design file, or a live reproduction.
4
4
 
5
5
  ## Syntax
6
6
 
@@ -26,6 +26,7 @@ Close the block with `::` on the next line. It drops anything inside and reports
26
26
  | CodePen | `codepen.io/<user>/pen/<id>` |
27
27
  | StackBlitz | `stackblitz.com/edit/<project>` and `stackblitz.com/github/<owner>/<repo>`, keeping options such as `file` and `view` |
28
28
  | Figma | `figma.com/design`, `file`, `proto`, `board`, `slides`, and `deck` links, keeping `node-id` |
29
+ | X | `x.com/<user>/status/<id>` and `twitter.com` links, `mobile.` ones too; the post grows to its own height |
29
30
 
30
31
  Any other `https://` link renders as a card with its `title` and host. A provider's link it can't read an ID from renders as a card too, and is reported. A link with a user name or password renders nothing.
31
32
 
@@ -37,4 +38,4 @@ Any other `https://` link renders as a card with its `title` and host. A provide
37
38
  ## Register
38
39
 
39
40
  - In `comark-ui`: on.
40
- - Alone: `pnpm add comark @comark/html comark-embed`, then `createHtmlRenderer({ plugins: [embed()], components })` with both from `comark-embed/html`. It takes no options and needs no script. `comark-embed/vue`, `/react`, and `/svelte` render it too.
41
+ - Alone: `pnpm add comark @comark/html comark-embed`, then `createHtmlRenderer({ plugins: [embed()], components })` with both from `comark-embed/html`. It takes no options. Only an X post needs a script, which the HTML renderer inlines and the components start on mount. `comark-embed/vue`, `/react`, and `/svelte` render it too.
@@ -11,7 +11,7 @@ Hold ++shift++ and press ++"Duck Button"++ to page the rubber duck.
11
11
  ```
12
12
 
13
13
  - Write the keys between `++` and `++`, joined by single `+` signs, with no spaces. Names aren't case sensitive.
14
- - Letters and digits render uppercase, `f1` to `f24` as F1 to F24, and these names as their usual labels:
14
+ - Full names (`control`, `command`, `escape`, `delete`, `arrow-up`) and pymdownx.keys' other aliases work too. Letters and digits render uppercase, `f1` to `f24` as F1 to F24, and these names as their usual labels:
15
15
  - Modifiers: `ctrl`, `alt`, `shift`, `cmd`, `opt`, `option`, `meta`, `super`, `win`, `fn`, `altgr`.
16
16
  - Editing: `enter`, `return`, `tab`, `esc`, `space`, `backspace`, `bksp`, `del`, `ins`, `caps-lock`.
17
17
  - Moving: `up`, `down`, `left`, `right`, `home`, `end`, `pg-up`, `pg-dn`, `page-up`, `page-down`.
@@ -15,7 +15,7 @@ Turn off the `new-checkout` flag in **Settings**, then redeploy.
15
15
  ```
16
16
 
17
17
  - A heading's `#` link uses its id. Comark makes the id from the heading's text, so write `{#rollout}` after a heading that other pages link to, and the link survives a reworded heading.
18
- - A link opens a new tab only when the host sets `target` or the link says `{target="_blank"}`. Leave both off, so the reader decides; add one only where leaving loses the reader's work, such as a page with a half-filled form. Any link that opens a new tab, on your site or another, gets `rel="noopener"`, a ↗, and "(opens in a new tab)" for screen readers, so leave that out of the link's text.
18
+ - A link opens a new tab only when the host sets `target` or the link says `{target="_blank"}`. Leave both off, so the reader decides; add one only where leaving loses the reader's work, such as a page with a half-filled form. Any link that opens a new tab, on your site or another, gets a ↗ and "(opens in a new tab)" for screen readers, so leave that out of the link's text. Any link with `target="_blank"` also gets `rel="noopener"`.
19
19
  - A link keeps the `target` and `rel` written on it, such as `{rel="me"}` on a profile link, or `{target="_self"}` to keep one link in the tab when the host opens the others in a new one.
20
20
 
21
21
  ## Options
@@ -1,6 +1,6 @@
1
1
  # Checking documents
2
2
 
3
- comark-linter reports what Comark forgives, such as a `::` block never closed, a misspelled component, or a link to a missing file. It also reports every problem a plugin puts in `meta.issues`, each under its own rule. Check the result in SKILL.md runs it on one file; this page covers its flags, its config file, the library, ESLint, and Vite Doctor.
3
+ comark-linter reports what Comark forgives, such as an unclosed `::` block, a misspelled component, or a link to a missing file. It also reports every problem a plugin puts in `meta.issues`, each under its own rule. SKILL.md's Check the result step runs it on one file. This page covers the flags, the config file, the library, ESLint, and Vite Doctor.
4
4
 
5
5
  ## Run the command
6
6
 
@@ -10,13 +10,22 @@ vp exec comark-lint "docs/**/*.md" --format json --check-urls
10
10
 
11
11
  - Pass files or globs. Quote a glob so the shell passes it as written; comark-lint expands it and skips `node_modules` and `dist`.
12
12
  - It prints `file:line:column rule message fix` for each problem, or `No problems.` when there are none. It exits with 0 when clean, 1 on any problem, and 2 when a file can't be read, a glob matches nothing, or the config fails to load.
13
- - `--format json` prints an array of `{ file, rule, line, column, message, fix }` instead.
14
- - `--check-urls` also requests every external URL, and reports one that answers 404 or 410, has no DNS record, or fails its TLS check. It caches answers for a day in `node_modules/.cache/comark-linter/urls.json`, except a 404, 410, 429, or 5xx, which it requests again on the next run.
13
+ - `--format json` prints an array of `{ file, rule, severity, line, column, message, fix }` instead. `severity` is `error` or `warn`; the exit code is 1 for either.
14
+ - `--check-urls` also requests every external URL and reports one that answers 404 or 410, has no DNS record, or fails its TLS check. It caches answers for a day in `node_modules/.cache/comark-linter/urls.json`, except a 404, 410, 429, or 5xx, which the next run requests again.
15
15
  - It loads `comark-lint.config.ts` (or `.mts`, `.mjs`, `.js`) from the working directory, or a `lint-comark.config` file there. `--config path/to/config.ts` loads another one instead.
16
16
 
17
- Run it from the project root. A relative link or image resolves from the document's folder, and a `/` path from the working directory. Each must point at a file that exists, so save the screenshots before you lint.
17
+ Run it from the project root. A relative link or image resolves from the document's folder, and a `/` path from the working directory. Each must point at an existing file, so save the screenshots before you lint.
18
18
 
19
- It lints with every comark-ui package installed, `comark-ui` first; the [comark-ui reference](ui.md) says what it turns on there. Besides each plugin's own rules, named `comark/<package>/<kind>`, it reports unclosed blocks, unknown components, an unclosed `{` or a key set twice, broken links and anchors, frontmatter that isn't valid YAML, `javascript:` and other unsafe URLs, duplicate ids, images without alt text unless `{alt=""}` marks them as decoration, and empty links. It also reports links that stop working for other readers: localhost, private network, and `file:` URLs, tunnels such as ngrok, and Vercel or Netlify deploy previews. In PR evidence, link the production page or the pull request, and write a local address as code, such as `` `localhost:3000` ``, since Comark links a bare URL.
19
+ It lints with every installed comark-ui package, `comark-ui` first; the [comark-ui reference](ui.md) says what it turns on there. Besides each plugin's own rules, named `comark/<package>/<kind>`, it reports:
20
+
21
+ - unclosed blocks, unknown components, an unclosed `{`, and a key set twice
22
+ - broken links and anchors, empty links, and duplicate ids
23
+ - frontmatter that isn't valid YAML
24
+ - `javascript:` and other unsafe URLs
25
+ - images without alt text, unless `{alt=""}` marks them as decoration
26
+ - links that stop working for other readers: localhost, private network, and `file:` URLs, tunnels such as ngrok, and Vercel or Netlify deploy previews
27
+
28
+ In PR evidence, link the production page or the pull request. Write a local address as code, such as `` `localhost:3000` ``, since Comark turns a bare URL into a link.
20
29
 
21
30
  ## Config file
22
31
 
@@ -32,8 +41,8 @@ export default defineConfig({
32
41
  });
33
42
  ```
34
43
 
35
- - `plugins` and `components` add to those of the installed packages. `components` takes names, or the components map you render with. Comark keeps the first plugin of each name and drops the rest, so a config can add plugins, such as your own or [include](include.md), and can't change the options of one an installed package registers.
36
- - It takes every library option below except `file`. Node reads a `.ts` config from 22.18 on; on older versions, write it as `.mjs`.
44
+ - `plugins` and `components` add to those of the installed packages. `components` takes names, or the components map you render with. Comark keeps the first plugin of each name, so a config can add plugins, such as your own or [include](include.md), but can't change the options of one an installed package registers.
45
+ - It takes every library option below except `file`. Node reads a `.ts` config from 22.18; on older versions, write `.mjs`.
37
46
 
38
47
  `links` sets how the linter checks links. It applies `skip`, `block`, and `allow` in that order, then checks the file or the URL:
39
48
 
@@ -57,8 +66,8 @@ const diagnostics = await lint(markdown, { plugins: [annotate()], components, fi
57
66
  const results = await lintFiles(["docs/index.md", "docs/setup.md"], await resolveConfig());
58
67
  ```
59
68
 
60
- - `lint(markdown, options)` returns `{ rule, line, column?, message, fix }[]` in source order and never throws. A rule that crashes reports one diagnostic saying so, and the others still run.
61
- - Pass `plugins` and `components`, the ones you render with; without `components`, it skips the unknown-component check. Pass `file`, the document's path, to check its links to files. `root` defaults to the working directory, and `read`, `exists`, and `list` replace node:fs, by absolute path. Pass `headingIds` if you render with it, so anchors match, and `links` as above.
69
+ - `lint(markdown, options)` returns `{ rule, severity, line, column?, message, fix }[]` in source order and never throws. A rule that crashes reports one diagnostic saying so, and the others still run.
70
+ - Pass the `plugins` and `components` you render with; without `components`, it skips the unknown-component check. Pass `file`, the document's path, to check its links to files. `root` defaults to the working directory, and `read`, `exists`, and `list` replace node:fs, by absolute path. Pass the `headingIds` you render with so anchors match, and `links` as above.
62
71
  - `lintFiles(paths, options)` parses each file once, checks links between them against each other's headings, and requests each URL once. It returns `{ file, text, diagnostics }` for each path, with no `text` when the file can't be read.
63
72
  - `resolveConfig(config)` returns the installed packages' plugins and components plus the config's, as the command uses them. `rules` maps every rule to its title.
64
73
 
@@ -71,9 +80,9 @@ import comark from "comark-linter/eslint";
71
80
  export default [comark.configs.recommended, { settings: { comark: { config: "comark-lint.config.mjs" } } }];
72
81
  ```
73
82
 
74
- Use a JavaScript ES module (`export default { ... }`) for the linter config across supported Node versions. A `.ts` config requires Node 22.18+ or `--experimental-strip-types` on Node 22.12–22.17, including in the editor. Restart ESLint after editing the config or its imports; they are cached for the process lifetime.
83
+ Write the linter config as a JavaScript ES module (`export default { ... }`) so it loads on every supported Node version. A `.ts` config needs Node 22.18+, or `--experimental-strip-types` on Node 22.12–22.17, in the editor too. Restart ESLint after you edit the config or its imports, since it caches them for the process.
75
84
 
76
- Install `eslint` (9.15 or later) and `@eslint/markdown` (8 or later). The recommended config lints `**/*.md` and `**/*.mdc` with `@eslint/markdown`'s `markdown/commonmark` language and YAML frontmatter, and turns on every rule but `comark/dead-url`, which requests every URL; turn that one on in `rules` to check them. Each rule has the name the command prints and is configured like any ESLint rule, `<!-- eslint-disable-next-line comark/unknown-component -->` included. ESLint prints the fix after the message. `settings.comark.config`, from the working directory, loads the same config file as `--config`. oxlint can't run it: its JS plugins don't lint `.md` files, so run `comark-lint` beside `oxlint`.
85
+ Install `eslint` (9.15 or later) and `@eslint/markdown` (8 or later). The recommended config lints `**/*.md` and `**/*.mdc` with `@eslint/markdown`'s `markdown/commonmark` language and YAML frontmatter. It turns on every rule but `comark/dead-url`, which requests every URL; turn that one on in `rules` to check them. Each rule has the name the command prints and is configured like any ESLint rule, `<!-- eslint-disable-next-line comark/unknown-component -->` included. ESLint prints the fix after the message. `settings.comark.config`, a path from the working directory, loads the same config file as `--config`. oxlint can't run it, because its JS plugins don't lint `.md` files; run `comark-lint` beside `oxlint`.
77
86
 
78
87
  ## Vite Doctor
79
88
 
@@ -93,4 +102,4 @@ Run `vite-doctor . --config doctor.config.ts --max-warnings 0`. The extension ta
93
102
  ## Register
94
103
 
95
104
  - In `comark-ui`: not included. Install it beside the preset, which it finds on its own.
96
- - Alone: `pnpm add -D comark-linter`. The command is `comark-lint`, also installed as `lint-comark`, the library `comark-linter`, the ESLint plugin `comark-linter/eslint`, and the extension `comark-linter/doctor`. npm refused `comark-lint` as too close to `remark-lint`, hence the name.
105
+ - Alone: `pnpm add -D comark-linter`. It installs the command `comark-lint` (also `lint-comark`), the library `comark-linter`, the ESLint plugin `comark-linter/eslint`, and the Vite Doctor extension `comark-linter/doctor`.
@@ -25,7 +25,7 @@ const total = price * rate
25
25
  ## Choose the steps
26
26
 
27
27
  - Change one thing per step. When most of the code moves at once, the reader can't follow any of it.
28
- - Keep the code that stays the same identical, spaces aside, so it moves rather than fading out and in.
28
+ - Keep the code that stays the same identical, so it moves rather than fading out and in.
29
29
  - For a change a reviewer approves, write `::diff`: it shows every removed and added line at once, which an animation can't.
30
30
 
31
31
  ## Register
@@ -20,6 +20,7 @@ Tests moved to Vitest: :progress{value=17 max=20 label="Migrated"}
20
20
 
21
21
  - `:delta` reads `412 kB → 388 kB ↓ 5.8%`. `from` and `to` are required numbers, and `unit`, such as `kB`, `s`, or `%`, goes after both. `better` is `lower` for sizes and durations or `higher` for scores. It colors the change green when it's better and red when it's worse; without it the change is gray. The percent is of `from`, to one decimal. From 0 there is no percent, so the change is the difference, such as `↑ 1.5 s`.
22
22
  - `::stats` holds one Markdown table of three columns: a name, the value before, and the value after, under any headers. A cell is a number, with commas if you like, and an optional unit after it, the same in both cells of a row. `better` applies to every row, and `unit` names a difference from 0 for cells written without one. The plugin drops anything else inside the block and reports it.
23
+ - Add `tiles` to `::stats` to show each row as a tile, with the name above the after value and the change below it. The table can then have two columns, a name and a value; a value with no before shows without a change. `better` and `unit` work as for the table.
23
24
  - `:progress` is a native `<progress>` with its percent after it. `value` is required: a fraction from 0 to 1, or a count up to `max`, which is 1 by default. `label` shows before the bar and names it for screen readers. The plugin clamps a `value` outside 0 to `max` and reports it.
24
25
 
25
26
  ## Write the numbers
@@ -36,9 +36,9 @@ The `rail` option adds an "On this page" outline beside the text of every docume
36
36
 
37
37
  - Options: `rail: true`, or `{ title, depth }` (default "On this page" and 3).
38
38
  - The page sets `--comark-inset-end` on `:root` for a panel that covers its right edge. While the outline keeps a column beside wide blocks, it sets `data-comark-rail` and `--comark-rail-width` on `<html>`, and the page shrinks `--comark-wide-end` by it, so wide blocks move toward the room before the text.
39
- - It hides where it doesn't fit, and rather than narrow a diagram.
39
+ - It hides where it doesn't fit, and hides rather than narrow a wide diagram.
40
40
 
41
41
  ## Register
42
42
 
43
43
  - In `comark-ui`: on in every entry; `outline: { rail: true }` adds the side outline.
44
- - Alone: `pnpm add comark @comark/html comark-outline`, then `createHtmlRenderer({ plugins: [outline()], components })` with both from `comark-outline/html`. `comark-outline/vue`, `/react`, and `/svelte` render it too. It reads the headings itself, so it works in any plugin order and without Comark's toc plugin, which only fills `meta.toc` for a sidebar. The npm name is `comark-outline` because npm refused `comark-toc`.
44
+ - Alone: `pnpm add comark @comark/html comark-outline`, then `createHtmlRenderer({ plugins: [outline()], components })` with both from `comark-outline/html`. `comark-outline/vue`, `/react`, and `/svelte` render it too. It reads the headings itself, so it works in any plugin order and without Comark's toc plugin, which only fills `meta.toc` for a sidebar.
@@ -24,7 +24,7 @@ The palette page now shows every token of the theme.
24
24
  - The box shows the host's `keys`, by default `status`, `pr`, `author`, `date`, and `tags`, in that order. A key that's missing or empty is skipped, and the rest of the frontmatter, such as a layout or a slug, stays off the page.
25
25
  - The box goes first in the document. To put it somewhere else, such as under the title, write `::properties` there and close it with `::` on the next line. It takes no props and no content; choosing keys is the host's job.
26
26
  - Text, a number, `true`, and `false` show as written, and so does a date such as `2026-10-23`. A GitHub or GitLab pull request, merge request, or issue link shows as `owner/repo#123`, any other http(s) link as its host and path, and a list as one badge per item. An object or a list of lists doesn't show, and is reported.
27
- - Each label is its key capitalized, with `pr` as PR, unless the host names it.
27
+ - Each label is its key capitalized, with dashes and underscores as spaces, `pr` as PR, and `url` as URL, unless the host names it.
28
28
 
29
29
  ## Register
30
30
 
@@ -1,6 +1,6 @@
1
1
  # Lessons and quizzes
2
2
 
3
- comark-quiz adds `::question`, `::poll`, and `::recall` blocks for interactive lessons. Questions check one or more answers and explain each option, polls collect votes, and recall cards reveal an answer for self-testing. Without its script, the prompt, options, and answer disclosure remain readable HTML.
3
+ comark-quiz adds `::question`, `::poll`, and `::recall` blocks for interactive lessons. A question checks one or more answers and explains each option, a poll collects votes, and a recall card hides an answer until the reader asks for it. Without the script, the prompt, options, and answer disclosure stay readable HTML.
4
4
 
5
5
  ## Syntax
6
6
 
@@ -35,11 +35,23 @@ Promise callbacks are microtasks, and a timer's callback is a task.
35
35
  ::
36
36
  ```
37
37
 
38
- A question uses radios when one option is marked `[x]`; `multiple` makes it a checkbox question. Options are shuffled deterministically unless `shuffle="false"`. Questions and recall cards share numbering, while polls are not numbered. A missing id is derived from the block content. Use `#hint` and `#explain` on questions, and `#answer` on recall cards. Polls accept `multiple` and a date in `closes`.
38
+ | Block | Props and slots |
39
+ | --- | --- |
40
+ | `::question` | `#id`, `multiple`, `shuffle="false"`, `number="false"`, slots `#hint` and `#explain`. |
41
+ | `::poll` | `#id`, `multiple`, `closes` (an ISO date; after it the poll shows as closed). Options are never shuffled. |
42
+ | `::recall` | `#id`, `number="false"`, and the required slot `#answer`. |
43
+
44
+ - Mark a right option `[x]` and a wrong one `[ ]`. One right option makes radios and several make checkboxes; `multiple` forces checkboxes even with one. Mark no option in a poll.
45
+ - Put a `>` line under an option to say why it is right or wrong. Give every wrong option a reason, since that is the lesson for a reader who picked it.
46
+ - Leave a blank line before `#hint` and `#explain`. Without it, the text above swallows the slot, and the plugin reports it.
47
+ - Give every block an `#id`. Hosts save answers by id. Without one the id derives from the prompt and options, changes when you reword them, and the plugin reports it. Keep the id when you reword the prompt.
48
+ - Questions and recall cards share one count, so a lesson numbers them 1, 2, 3 down the page. Polls are not numbered.
49
+ - Options are shuffled the same way for every reader, so do not write options that point at others by place, such as "All of the above" or "Both A and B". Keep the options about as long as each other, since a right option much longer than the rest is reported.
50
+ - Keep a block to six options or fewer. Mark at least one right option in a question, or ask it as a poll. Put no block inside another block's prompt, option, or slot.
39
51
 
40
52
  The HTML renderer inlines the quiz script and styles. Hosts can listen for `comark-quiz:answer` and `comark-quiz:ready`, and restore answers or results with `comark-quiz:state`; see [Saving answers](https://comark-ui.onmax.me/quiz/#saving-answers) on its page for the event shapes and storage behavior.
41
53
 
42
54
  ## Register
43
55
 
44
56
  - In `comark-ui`: on, as `quiz`, with optional `{ labels }` for translated UI text.
45
- - Alone: `pnpm add comark @comark/html comark-quiz`, then `createHtmlRenderer({ plugins: [quiz()], components })` with `quiz, { components }` from `comark-quiz/html`. The HTML renderer is required because the blocks need its inlined script; there are no Vue, React, or Svelte entries.
57
+ - Alone: `pnpm add comark @comark/html comark-quiz`, then `createHtmlRenderer({ plugins: [quiz()], components })` with `quiz, { components }` from `comark-quiz/html`. Use the HTML renderer, since the blocks need its inlined script; there are no Vue, React, or Svelte entries.
@@ -28,5 +28,5 @@ With `@comark/vue` or `@comark/react`, read `meta.readingTime` from the parsed d
28
28
 
29
29
  ## Register
30
30
 
31
- - In `comark-ui`: on in every entry. `readingTime: { wordsPerMinute: 230 }` sets the speed. The default, 200, is a cautious pace for technical prose; 230 to 250 suits light reading, and a site mostly in CJK may want more.
31
+ - In `comark-ui`: on in every entry. `readingTime: { wordsPerMinute: 230 }` sets the speed; 0 or less counts at 200. The default, 200, is a cautious pace for technical prose; 230 to 250 suits light reading, and a site mostly in CJK may want more.
32
32
  - Alone: `pnpm add comark comark-reading-time`, then `parseMarkdown(markdown, { plugins: [readingTime()] })` with `readingTime` from `comark-reading-time`. It has no components, so it works with any renderer.
@@ -18,7 +18,7 @@ At 1024 px wide, **Apply** drops under the filter chips.
18
18
  ```
19
19
 
20
20
  - Each `###` heading starts a step that holds everything up to the next one, code blocks and images included. The heading keeps its id, so a link to `#add-three-filters` and a table of contents still find it.
21
- - `level` is the level of the headings that start each step, from 2 to 6, default 3. Write `::steps{level="2"}` for `##` headings. Deeper headings stay inside their step.
21
+ - `level` is the level of the headings that start each step, from 2 to 6, default 3; any other value falls back to 3 and is reported. Write `::steps{level="2"}` for `##` headings. Deeper headings stay inside their step.
22
22
  - A block whose only content is one numbered list makes a step of each item, and a list that starts at 3 numbers its steps from 3. Use the list when every step fits on one line.
23
23
  - A `:::steps{level="4"}` inside a step keeps its own headings and numbers.
24
24
 
@@ -25,6 +25,7 @@ Or read the file the run wrote, and leave the block empty:
25
25
  - A ` ```json ` fence stays code unless it sits inside `::table`. It holds an array of objects, one per row. Every key becomes a column, in the order first seen, and a nested value shows as JSON.
26
26
  - `src` starts at the document's folder, or at the host's `root` when it starts with `/`. It can't leave `root` or be a URL, and the extension picks the format. The plugin drops content beside `src` and reports it.
27
27
  - A Markdown table inside `::table{sort}` or `::table{copy}` gets the Copy button. A `::table` with no props renders its Markdown table plain.
28
+ - To tint a cell by status, write the whole cell as `[text]{tone="success"}`, with `success`, `warning`, `error`, or `info`. A tone on the first cell tints the row. This works in Markdown, CSV, TSV, and JSON cells. A span that doesn't fill its cell, or another tone, leaves the cell uncolored and is reported.
28
29
 
29
30
  | Prop | What it does |
30
31
  | --- | --- |
@@ -28,9 +28,9 @@ Press **Ctrl+K** to find the pigeon data.
28
28
 
29
29
  - `::tabs`: each `:::tabs-item` inside is one tab. Content outside every tab doesn't render, and is reported.
30
30
  - `:::tabs-item`: `label` is required and must differ from the other labels in its block, since `sync` matches tabs by label. `icon` draws an Iconify name, such as `lucide:apple`, or an image URL before the label.
31
- - `::code-group`: only code blocks go inside. Name each one's tab in brackets after its language, as in `sh [pnpm]`, with an optional icon after it, as in `sh [pnpm] icon=logos:pnpm`. The tab replaces the block's own title, and comark-code's `title="pnpm"` names no tab.
31
+ - `::code-group`: only code blocks go inside. Name each one's tab in brackets after its language, as in `sh [pnpm]`, with an optional icon after it, as in `sh [pnpm] icon=logos:pnpm`. The tab replaces the block's own title. `title="pnpm"` names no tab, so a block without brackets is reported.
32
32
  - `sync`, on either block, is a key shared by blocks that switch together. Picking a tab picks the tab with the same label in every block with that key, and the next page that uses the key remembers it.
33
- - A code block marked `pm`, as in `sh pm`, holds package manager commands in any manager (npm, npx, pnpm, pnpx, yarn, bun, bunx, or deno) and becomes a code group with a tab each for npm, pnpm, yarn, and bun, synced as `pm`. The manager it's written in keeps its commands as written. It reads install, frozen install (`npm ci`), add with `-D`, `-E`, `-O`, `--save-peer`, or `-g`, remove, update, run, `npx`/`dlx`, create, and init. Only commands at the start of a line or after `&&`, `||`, or `;` change. Inside a `::code-group`, `pm` does nothing.
33
+ - A code block marked `pm`, as in `sh pm`, holds package manager commands in any manager (npm, npx, pnpm, pnpx, yarn, bun, bunx, or deno) and becomes a code group with a tab each for npm, pnpm, yarn, and bun, synced as `pm`. The manager it's written in keeps its commands as written. It reads install, frozen install (`npm ci`), add with `-D`, `-E`, `-O`, `--save-peer`, or `-g`, remove, run, `npx`/`dlx`, create, and init. An update or a `pnpm exec` stays only in its own manager's tab, and the others are left out and reported. Only commands at the start of a line or after `&&`, `||`, or `;` change. Inside a `::code-group`, `pm` does nothing.
34
34
 
35
35
  ## Choose the block
36
36
 
@@ -35,7 +35,7 @@ The block shows:
35
35
 
36
36
  - The counts of `<testcase>` elements. A case with `<skipped>` is skipped, one with `<failure>` or `<error>` failed, and the rest passed. Failed and skipped show only when there are any.
37
37
  - The duration, from the `time` of `<testsuites>`, else the sum of the suites' times, else the cases', written as `250 ms`, `4.2 s`, or `1 min 21 s`. A report without times shows none.
38
- - Each failure as a closed disclosure named `classname › name`, with its `message` and its stack in a code block. Failures print open.
38
+ - Each failure as a closed disclosure named `classname › name`, with its `message` and its stack in a code block. In print, every failure prints open.
39
39
 
40
40
  The root is `<testsuites>` or a single `<testsuite>`. A report with another root renders nothing, and so does malformed XML, which the plugin reports with its line.
41
41
 
@@ -1,10 +1,10 @@
1
1
  # Every plugin in one install
2
2
 
3
- comark-ui registers every comark-ui package for one renderer, in the order they need, with one icon resolver shared by `:icon`, cards, details, file trees, tabs, and code actions. Install in SKILL.md shows its basic use. This page covers its options, what it turns on, its other renderers, and how the linter uses it.
3
+ comark-ui registers every comark-ui package for one renderer, in the order they need, with one icon resolver shared by `:icon`, cards, details, file trees, tabs, and code actions. SKILL.md's Install section shows the basic use. This page covers the options, what the preset turns on, the other renderers, and how the linter uses it.
4
4
 
5
5
  ## Options
6
6
 
7
- `comarkUi(options)` returns `{ plugins, components }`. Each key is a package's name without `comark-`, in camelCase, such as `fileTree`, `codeNotes`, or `readingTime`. `false` turns a plugin off along with its components, and an object turns it on with those options. `true` turns on `include` and leaves the others as they are:
7
+ `comarkUi(options)` returns `{ plugins, components }`. Each key is a package's name without `comark-`, in camelCase, such as `fileTree`, `codeNotes`, or `readingTime`. The exceptions are `math` for comark-mathml, `outline` for comark-outline, and `mermaid` and `typeset`, which are not packages. `false` turns a plugin off along with its components, and an object turns it on with those options. `true` turns on `include` and leaves the others as they are:
8
8
 
9
9
  ```ts
10
10
  comarkUi({
@@ -16,17 +16,18 @@ comarkUi({
16
16
  });
17
17
  ```
18
18
 
19
- `github` takes its three plugins by name, `callouts`, `references`, and `html`, and `links` takes `external` and `anchors`. Each package's reference lists its own options. The order stays fixed whatever you pass. `include` runs first, so the others read what it pastes, and `code` and `codeNotes` run last, after every plugin that writes code blocks.
19
+ `github` takes its three plugins by name, `callouts`, `references`, and `html`, and `links` takes `external` and `anchors`. Each package's reference lists its own options. The order stays fixed whatever you pass: `include` runs first, so the others read what it pastes, and `code` and `codeNotes` run late, after every plugin that writes code blocks.
20
20
 
21
21
  ## What it turns on
22
22
 
23
23
  - Every plugin except `include`, which reads files from disk. `include: { root, base }` turns it on, or `{ read }` in a browser or an edge runtime. `include: true` reads under the working directory.
24
24
  - `cast`, `table`, and `tests` get a reader that finds no file. Inline casts, CSV fences, and pasted JUnit reports render, and a `src` file doesn't load until you pass `{ root }` or `{ read }`. Any other options object replaces that reader too, so the plugin reads under the working directory.
25
- - By default, three plugins use the network while parsing: `chips` downloads favicons and avatars, `icon` fetches icon sets from the Iconify API, and `diagrams` sends each diagram's source to `https://kroki.io`. In a browser, pass `chips: { download: false }`, since a browser may not download another site's images. To parse offline, also pass `icon: { fetch: false }` with your icon sets in `collections`, and `diagrams: { draw: false }`. To keep diagram sources private, pass your own Kroki `server`.
26
- - Media sizing reads only data URIs by default. `zoom: { size: true }` and `media: { size: true }` also fetch remote files while parsing; `annotate: { size: true }` does so at HTML render time. Enable these only for trusted documents, since requests follow redirects and can reach private networks. `{ size: false }` disables measurement for each plugin; authored dimensions and screenshot viewports still work.
25
+ - Three plugins use the network while parsing by default: `chips` downloads favicons and avatars, `icon` fetches icon sets from the Iconify API, and `diagrams` sends each diagram's source to `https://kroki.io`. In a browser, pass `chips: { download: false }`, because a browser may not download another site's images. To parse offline, also pass `icon: { fetch: false }` with your icon sets in `collections`, and `diagrams: { draw: false }`. To keep diagram sources private, pass your own Kroki `server`.
26
+ - Media sizing reads only data URIs by default. `zoom: { size: true }` and `media: { size: true }` also fetch remote files while parsing, and `annotate: { size: true }` does so at HTML render time. Enable these only for trusted documents, because the requests follow redirects and can reach private networks. `{ size: false }` turns measurement off for that plugin; authored dimensions and screenshot viewports still work.
27
27
  - `icon`'s options apply to every icon the preset draws, in cards, details, file trees, tabs, and code actions too.
28
+ - `mermaid` draws `mermaid` fences with comark-pele, on the server and offline. In the HTML entry the diagram zooms with comark-zoom unless `zoom` is `false`. `mermaid: false` turns it off.
28
29
  - comark-critic has no component to add its styles, so put `criticCss`, which every entry exports, in the page.
29
- - The text around the blocks is styled by default, scoped to the element the document renders into, on the same `--comark-*` tokens. Pass `typeset: false` when the site already styles Markdown, such as with Tailwind Typography's `prose`.
30
+ - The preset styles the text around the blocks, scoped to the element the document renders into, on the same `--comark-*` tokens. Pass `typeset: false` when the site already styles Markdown, such as with Tailwind Typography's `prose`.
30
31
 
31
32
  ## Renderers
32
33
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: teach-lesson
3
- description: Write a short lesson on one concept, with simplified English, a worked example, and an application question. Use for a lesson, a self-check, or onboarding on one idea.
3
+ description: Writes a short lesson on one concept in simplified English, with a worked example and a question the reader answers. Use when someone asks to learn or understand one concept, wants a tutorial or self-check they can test themselves on, or needs onboarding on one idea.
4
4
  license: MIT
5
5
  ---
6
6
 
@@ -58,7 +58,7 @@ Use [`::question`](references/blocks.md#the-check-question) to test the outcome.
58
58
 
59
59
  - Make each wrong option a real misconception, and give it a `>` rationale that says why it's tempting and why it's wrong.
60
60
  - Keep the options parallel, one idea each and close in length, so their shape gives no clue to the answer.
61
- - Add `#explain` for the one thing the reader should take away whatever they picked.
61
+ - Add `#explain` for the one thing the reader should take away. It opens after the right answer or Show answer, so it must resolve every misconception the wrong options carry.
62
62
  - For a fact worth remembering a week later, optionally add a [`::recall` card](references/blocks.md#the-fact-to-keep-recall).
63
63
 
64
64
  Done when the question tests the stated outcome with one changed input, every option has a rationale, and the shared explanation resolves each misconception.
@@ -73,6 +73,6 @@ Done when the question tests the stated outcome with one changed input, every op
73
73
 
74
74
  These commands use the [global Vite+ CLI](https://viteplus.dev/guide/global-cli). Without it, `pnpm dlx` takes the same arguments.
75
75
 
76
- 2. Open the rendered page where it will be read. Select each option and check its rationale and the shared explanation.
76
+ 2. Open the rendered page where it will be read. Select each option and check its rationale. Pick the right option, or press Show answer, and check the shared explanation.
77
77
 
78
- Done when lint reports no problems, every worked step and diagram is visible, and each option reveals the expected result and rationale. Confirm that the correct answer follows from the example and that the lesson fits a five-minute read.
78
+ Done when lint reports no problems, every worked step and diagram is visible, and each option reveals its rationale. Confirm that the correct answer follows from the example and that the lesson fits a five-minute read.
@@ -19,11 +19,11 @@ If-Match: "v7"
19
19
  ::
20
20
  ````
21
21
 
22
- Each `###` heading starts a step that holds everything up to the next one, code blocks included. Put any introduction above the block, since a paragraph before the first heading is reported. For steps of one line each, a numbered list inside `::steps` works too.
22
+ Each `###` heading starts a step that holds everything up to the next one, code blocks included. Put any introduction above the block; content before the first heading renders above the steps and is reported. For steps of one line each, a numbered list inside `::steps` works too.
23
23
 
24
24
  ## Build a diagram across steps
25
25
 
26
- Use a `mermaid` fence when a diagram helps explain interacting parts. Redraw the previous diagram and add one part or relationship at each move. Keep existing labels and participant order consistent.
26
+ Use a `mermaid` fence when a diagram helps explain interacting parts. At each move, redraw the previous diagram with one more part or relationship, and keep its labels and participant order.
27
27
 
28
28
  Use numbered Markdown headings for the worked example. Mermaid fences currently disappear inside `::steps`, so place them directly under these headings:
29
29
 
@@ -48,7 +48,7 @@ sequenceDiagram
48
48
  ```
49
49
  ````
50
50
 
51
- These paths and version labels are illustrative. Use `sequenceDiagram` for messages or `flowchart LR` for a flow. comark-ui renders Mermaid as SVG, so the reader needs no diagram script.
51
+ These paths and version labels are illustrative. Use `sequenceDiagram` for messages or `flowchart LR` for a flow.
52
52
 
53
53
  ## The check: `::question`
54
54
 
@@ -69,10 +69,10 @@ What does the server compare the label against?
69
69
  ::
70
70
  ```
71
71
 
72
- - Mark the right option `[x]`. One `[x]` makes radio buttons; add `multiple` to the block for checkboxes with several right options.
72
+ - Mark each right option `[x]`. One `[x]` makes radio buttons and several make checkboxes. Add `multiple` to show checkboxes even with one right option.
73
73
  - The `>` quote under an option is its rationale, shown once the reader answers.
74
- - `#hint` is optional, shown on request; `#explain` shows after any answer.
75
- - Options are shuffled the same way on every render; write `shuffle="false"` only when their order means something, such as numbers in order.
74
+ - `#hint` is optional and opens on request. `#explain` opens after the right answer or Show answer, not after a wrong pick.
75
+ - Options are shuffled the same way on every render. Write `shuffle="false"` only when their order means something, such as numbers in order.
76
76
  - Give the block an `#id` so a host can store the answer. Without one, the id comes from the question's text and changes when you edit it.
77
77
 
78
78
  Without its script, the question and an answer disclosure still render as plain HTML.