@markii/stdlib 0.2.0 → 0.3.1

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.
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * The neutral, framework-agnostic definition of Mark's standard component
3
- * *contracts* (DESIGN.md §13.3/§13.6): name + kind + attribute schema +
3
+ * *contracts* (docs/integration.md/§13.6): name + kind + attribute schema +
4
4
  * semantics, as pure data — zero React, zero dependency on any other
5
5
  * `@markii/*` package. A renderer (today `@markii/react`, tomorrow a
6
6
  * hypothetical `@markii/gnome`) implements these same contracts against its
@@ -9,7 +9,7 @@
9
9
  *
10
10
  * A contract never describes markup, styling, or a component
11
11
  * implementation — only what a directive named `name` means: how it is
12
- * written (`kind`, matching the three directive forms from DESIGN.md §2/§13:
12
+ * written (`kind`, matching the three directive forms from docs/format.md/§13:
13
13
  * `inline` -> `:name[...]`, `leaf` -> `::name{...}`, `container` ->
14
14
  * `:::name{...} ... :::`) and what attributes it accepts.
15
15
  */
@@ -23,7 +23,7 @@
23
23
  export type ComponentKind = 'inline' | 'leaf' | 'container';
24
24
  /**
25
25
  * Schema for one directive attribute. All directive attributes arrive as
26
- * raw strings (or `null` for a bare attribute) — DESIGN.md never gives
26
+ * raw strings (or `null` for a bare attribute) — docs/spec.md never gives
27
27
  * directives a typed attribute grammar (Architecture rule 5: "no
28
28
  * expressions, conditionals, or loops in attributes"). `type` is kept as an
29
29
  * explicit field, rather than assumed, so the schema has somewhere to grow
package/dist/contracts.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * The neutral, framework-agnostic definition of Mark's standard component
3
- * *contracts* (DESIGN.md §13.3/§13.6): name + kind + attribute schema +
3
+ * *contracts* (docs/integration.md/§13.6): name + kind + attribute schema +
4
4
  * semantics, as pure data — zero React, zero dependency on any other
5
5
  * `@markii/*` package. A renderer (today `@markii/react`, tomorrow a
6
6
  * hypothetical `@markii/gnome`) implements these same contracts against its
@@ -9,10 +9,38 @@
9
9
  *
10
10
  * A contract never describes markup, styling, or a component
11
11
  * implementation — only what a directive named `name` means: how it is
12
- * written (`kind`, matching the three directive forms from DESIGN.md §2/§13:
12
+ * written (`kind`, matching the three directive forms from docs/format.md/§13:
13
13
  * `inline` -> `:name[...]`, `leaf` -> `::name{...}`, `container` ->
14
14
  * `:::name{...} ... :::`) and what attributes it accepts.
15
15
  */
16
+ /**
17
+ * Builds one of docs/format.md's five layout-wrapper container contracts —
18
+ * `center`/`right`/`wide`/`narrow`/`full` — which are otherwise identical in
19
+ * shape (`kind: 'container'`, no attributes) and differ only in `name` and
20
+ * the preset-specific half of `description`. A tiny helper rather than five
21
+ * hand-copied literals, since a typo in one copy's `kind`/`attributes` would
22
+ * otherwise be easy to miss across five near-duplicate blocks.
23
+ *
24
+ * `whatItDoes` is the preset-specific clause (e.g. "Centers narrower-than-
25
+ * column plain markdown..."); the shared clause about why these exist (the
26
+ * attribute mechanism cannot reach plain markdown) and about composing with
27
+ * a nested wrapper is appended identically for all five.
28
+ */
29
+ function layoutWrapperContract(name, whatItDoes) {
30
+ return {
31
+ name,
32
+ kind: 'container',
33
+ attributes: {},
34
+ description: `${whatItDoes} Takes no attributes — docs/format.md gives these five ` +
35
+ 'wrapper names a closed, attribute-free form; unlike a `width`/`align` ' +
36
+ 'attribute on a directive, a wrapper also reaches plain markdown a ' +
37
+ 'directive attribute mechanism structurally cannot (a GFM table or a ' +
38
+ 'bare image has no `{...}` to write `width=`/`align=` into). Nesting a ' +
39
+ 'width wrapper (`wide`/`narrow`/`full`) inside an alignment wrapper ' +
40
+ '(`center`/`right`) composes, e.g. `::::center :::narrow ... ::: ::::` ' +
41
+ '(the outer fence needs more colons than the inner one).',
42
+ };
43
+ }
16
44
  /**
17
45
  * The standard component set, seeded from the components that ship with
18
46
  * `@markii/react` today (`packages/platforms/markii-react/src/components/
@@ -210,7 +238,7 @@ export const STANDARD_COMPONENTS = {
210
238
  description: 'Comma-separated numbers for static authoring, e.g. `values="1,3,2,5"`. Ignored in favor of a bound `data=` array when both are present. Non-numeric entries are dropped.',
211
239
  },
212
240
  },
213
- description: 'A leaf directive rendering a minimal hand-rolled inline SVG chart, e.g. `::chart{kind=line values="1,3,2,5"}`. Sizes to its container — use DESIGN.md §4\'s `width`/`align` layout presets to control its footprint, not a pixel attribute. Data binding (§8): `data=name` resolves against the value store — expects an array of numbers (typically a Lua script returning a table), or an array of `{value}` objects. Non-finite/non-numeric entries are filtered out and the point count is capped; an empty or all-invalid series renders a small neutral empty state rather than a broken chart. Never throws, and never places unescaped text into the emitted SVG markup.',
241
+ description: 'A leaf directive rendering a minimal hand-rolled inline SVG chart, e.g. `::chart{kind=line values="1,3,2,5"}`. Sizes to its container — use docs/format.md\'s `width`/`align` layout presets to control its footprint, not a pixel attribute. Data binding (§8): `data=name` resolves against the value store — expects an array of numbers (typically a Lua script returning a table), or an array of `{value}` objects. Non-finite/non-numeric entries are filtered out and the point count is capped; an empty or all-invalid series renders a small neutral empty state rather than a broken chart. Never throws, and never places unescaped text into the emitted SVG markup.',
214
242
  },
215
243
  row: {
216
244
  name: 'row',
@@ -223,8 +251,20 @@ export const STANDARD_COMPONENTS = {
223
251
  description: 'Fixed column count for the row. Defaults to auto-fit (a responsive number of equal-width columns) when absent or not one of the allowed values — an invalid `cols` is never an error.',
224
252
  },
225
253
  },
226
- description: "DESIGN.md §4's one layout container, e.g. `:::row{cols=3} ... :::`. Its block children become equal-width cells that wrap responsively and stack on narrow viewports — and simply stack in a plain markdown viewer. No spans, no per-cell sizing, no other knobs.",
254
+ description: "docs/format.md's one layout container, e.g. `:::row{cols=3} ... :::`. Its block children become equal-width cells that wrap responsively and stack on narrow viewports — and simply stack in a plain markdown viewer. No spans, no per-cell sizing, no other knobs.",
255
+ },
256
+ cell: {
257
+ name: 'cell',
258
+ kind: 'container',
259
+ attributes: {},
260
+ description: "A transparent grouping container, e.g. `:::cell ... :::`. Its only job is making several blocks count as ONE cell of a `row`: a row's cells are its direct block children, so two blocks are two cells unless a `cell` groups them — and two adjacent task lists, which markdown merges into a single list, can only become two cells by putting one `cell` around each. Takes no attributes and adds no look of its own; outside a `row` it is inert. The enclosing `row` fence must use MORE colons than its `cell` children (directive container nesting rule), hence `::::row` wrapping `:::cell`.",
227
261
  },
262
+ center: layoutWrapperContract('center', 'Centers narrower-than-column plain markdown (a table, an image) within its scope and sets text alignment for everything in scope, e.g. `:::center ... :::`.'),
263
+ left: layoutWrapperContract('left', 'Left-aligns plain markdown within its scope and sets text alignment for everything in scope, e.g. `:::left ... :::`. Mostly matches the ambient default; it exists to override an alignment inherited from an enclosing scope, such as opting one cell back out of `:::row{align=center}`.'),
264
+ right: layoutWrapperContract('right', 'Right-aligns narrower-than-column plain markdown (a table, an image) within its scope and sets text alignment for everything in scope, e.g. `:::right ... :::`.'),
265
+ wide: layoutWrapperContract('wide', "Sizes its scope's content to docs/format.md's wide-column width preset, e.g. `:::wide ... :::`."),
266
+ narrow: layoutWrapperContract('narrow', "Sizes its scope's content to docs/format.md's narrow-column width preset, e.g. `:::narrow ... :::`."),
267
+ full: layoutWrapperContract('full', "Sizes its scope's content to the full available document-column width, e.g. `:::full ... :::`."),
228
268
  };
229
269
  /**
230
270
  * Looks `name` up in `STANDARD_COMPONENTS`, returning `undefined` if it
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@markii/stdlib",
3
- "version": "0.2.0",
3
+ "version": "0.3.1",
4
4
  "description": "Neutral, framework-agnostic standard component contracts for Mark (.mk.md) — the kind/attribute-schema seam every renderer (e.g. @markii/react) implements against. No React, zero dependencies.",
5
5
  "keywords": [
6
6
  "markdown",