Skip to content

[fm-var proposal] Add an fm-table tag #131

Description

@DandyLyons

Proposal

Extend the fm-var family with a block-level <fm-table> element for rendering tabular YAML data as a useful cached table in ordinary Markdown views.

This is a specification proposal, not yet an implementation issue. <fm-table> is not part of RFC 001 Rev 3, so its portable syntax and semantics should be agreed in the DandyLyons/fm-var-tag specification before md-utils treats it as conforming behavior.

Related epic: #111.

Motivation

<fm-var> covers one scalar and <fm-list> covers one sequence, but neither naturally represents repeated records such as releases, dependencies, contacts, benchmarks, or project status:

releases:
  - version: 1.2.0
    date: 2026-08-20
    status: stable
  - version: 1.3.0-beta.1
    date: 2026-09-01
    status: beta

A first-class table tag would keep this YAML authoritative while leaving a readable cache in GitHub, detached snippets, feeds, and LLM context.

Strawman syntax

<fm-table
  query="$.releases"
  columns="version,date,status"
  headers="Version,Date,Status">
<table>
<thead><tr><th>Version</th><th>Date</th><th>Status</th></tr></thead>
<tbody>
<tr><td>1.2.0</td><td>2026-08-20</td><td>stable</td></tr>
<tr><td>1.3.0-beta.1</td><td>2026-09-01</td><td>beta</td></tr>
</tbody>
</table>
</fm-table>

The exact columns and headers grammar above is deliberately provisional. The final design must avoid ambiguous delimiter/escaping rules and must not depend on mapping enumeration order.

The tag should share the established source/query/fallback vocabulary where it has the same meaning:

  • src
  • query
  • default-zero
  • default-null
  • effective locale/format configuration where applicable

Proposed v1 data model

  • The table query selects exactly one sequence.
  • Every row must have one consistent supported shape.
  • Initially support either:
    • a sequence of mappings with an explicit, ordered column selection; or
    • a rectangular sequence of scalar sequences with an explicit header policy.
  • Cells are scalar or null only. Nested mappings/sequences, mixed row shapes, missing required columns, and ragged matrix rows fail atomically unless the specification explicitly defines a fallback.
  • Row order and duplicate rows are preserved.
  • Column order is always explicit and deterministic; portable behavior must not rely on JSON/YAML object enumeration order.
  • Zero selected nodes and an empty selected sequence use default-zero or produce a distinct unresolved-zero result.
  • A selected null uses default-null or produces a distinct unresolved-null result.
  • A table failure retains the complete existing cache; synchronization never writes a partial table.

Cache and rendering model

  • <fm-table> is a block element and must stand on its own lines.
  • A successful dynamic cache uses one canonical, tightly constrained HTML table shape so the cache remains inside the custom element and is viewable without hydration.
  • Only the table structure required by the specification is permitted: table, optional thead, tbody, tr, th, and td, with any allowed alignment/accessibility attributes explicitly enumerated.
  • Header and cell text use the fm-var family’s text-only escaping and injection protections.
  • Literal zero/null fallbacks contain escaped literal text rather than an empty table wrapper.
  • Cache comparison is byte-deterministic under the document’s line-ending and indentation rules.
  • [fm-var] Convert references to vanilla Markdown #130’s fm-var to-markdown / to-md workflow converts the canonical HTML cache into a vanilla Markdown pipe table and removes the <fm-table> wrapper.

Column-definition design requirement

Before standardizing the tag, choose one portable way to define ordered columns and their headings. Candidate designs include:

  1. A compact columns attribute plus optional headings.
  2. A JSON-valued attribute containing column descriptors.
  3. A referenced table schema/configuration in YAML.
  4. Nested declarative <fm-column> elements.

The choice must address:

  • mapping keys and headings containing commas, quotes, whitespace, Unicode, or Markdown delimiters;
  • per-column JSONPath versus direct mapping-key lookup;
  • optional/missing/null cells;
  • per-column type and formatting;
  • alignment and accessibility;
  • parser complexity and readable authoring;
  • the existing prohibition on nested fm-var-family elements;
  • compatibility with lossless parsing, cache-only edits, and language-neutral fixtures.

Integration expectations

If the specification adopts <fm-table>, md-utils implementation work should:

  • add a table case to the portable fm-var syntax/domain model and lossless parser;
  • reuse source resolution, YAML-to-I-JSON projection, RFC 9535 evaluation, source policy, scalar coercion, formatting, escaping, and diagnostics from [fm-var] Implement the fm-var specification #111;
  • expose table details through inspect, explain, validation, preview, and synchronization workflows;
  • preserve all unrelated UTF-8 bytes and apply only exact child-cache edits during synchronization;
  • support complete-element conversion through [fm-var] Convert references to vanilla Markdown #130;
  • provide stable table-specific diagnostics without weakening existing query-resource limits;
  • preserve the Apple/Linux/WebAssembly Core boundary and keep host I/O outside Core.

Security and accessibility

  • Treat source values, headings, captions, and cached markup as untrusted.
  • Prevent HTML, Markdown, custom-element, URL, and closing-tag injection.
  • Bound row count, column count, total cells, selected-node count, and serialized cache size.
  • Never evaluate cell expressions through a general-purpose language runtime.
  • Decide whether a caption and/or accessible label is required or supported.
  • Emit semantic header cells and scopes where the chosen table model can determine them.

Questions to resolve in the specification

  • Which row shapes belong in v1: mappings, scalar matrices, or both?
  • How are ordered columns, display headings, and per-column queries authored?
  • Are missing mapping keys errors, null cells, empty cells, or configurable?
  • Can columns specify type, format, locale, alignment, or null presentation independently?
  • Is a header row mandatory? Can row headers be declared?
  • Is a caption part of the tag vocabulary?
  • What exact canonical HTML cache is permitted?
  • What whitespace, indentation, and LF/CRLF rules make cache freshness portable?
  • How should very wide/large tables be diagnosed or truncated, if ever?
  • What vanilla Markdown should [fm-var] Convert references to vanilla Markdown #130 emit when cell content contains pipes or line breaks?
  • Should the extension advance the RFC revision, become a separate RFC, or remain an optional capability?

Proposal acceptance criteria

  • The user problem and non-goals are validated with representative YAML/table examples.
  • The fm-var specification repository records the selected syntax, row shapes, cardinality, fallbacks, formatting, cache grammar, escaping, and resource-limit behavior.
  • Column order is explicit and never depends on mapping enumeration order.
  • Cache HTML and vanilla-Markdown conversion have deterministic, injection-safe algorithms.
  • Interaction with <fm-format>, inspect/explain, validation, synchronization, and to-markdown is specified.
  • Language-neutral fixtures cover valid tables, empty/null results, mappings/matrices, missing/null cells, Unicode, escaping, malformed caches, resource limits, LF/CRLF, and atomic failure.
  • Follow-up md-utils implementation issues are split into parser/model, evaluation/rendering, CLI integration, conversion, documentation, and conformance work with explicit dependencies.

Non-goals for the initial proposal

  • Arbitrary HTML in cells.
  • Nested tables, row spans, or column spans.
  • SQL joins, grouping, pivoting, aggregation, sorting, or general spreadsheet formulas.
  • Recursive flattening of nested values.
  • Interactive tables, browser-only rendering, pagination, or editor UI.
  • Replacing a full data-frame, spreadsheet, or general-purpose templating system.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions