You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Provide one command that converts a document containing active RFC 001 Rev 3 fm-var syntax into ordinary, portable Markdown:
md-utils fm-var to-markdown document.md
to-md is an exact alias for to-markdown.
The result contains no active <fm-var>, <fm-list>, or <fm-format> elements. Cached presentation values are inlined. When a reference has no cached value, the command resolves and evaluates its live value and inlines that result. fm-var-owned HTML and entity escaping are converted into vanilla Markdown while preserving the rendered meaning as closely as possible.
This is an export/conversion workflow, not synchronization: the output deliberately discards the dynamic fm-var declarations.
Epic: #111. This issue is related to, but semantically distinct from, cache synchronization in #113.
Default to converted Markdown on stdout without modifying the source.
Support --output <file> for one input file.
Require explicit --write for in-place replacement.
Follow existing GlobalOptions conventions for file/tree selection, recursion, exclusions, hidden files, deterministic ordering, diagnostics, and styling.
Reject ambiguous combinations such as multiple inputs with a single --output file.
Conversion semantics
For every active element recognized by the lossless fm-var parser:
<fm-var>
If the element has a non-empty cache, use that cache without fetching or refreshing the live value.
If the cache is empty or absent, run the normal source-resolution, YAML projection, JSONPath, fallback, coercion, formatting, and escaping pipeline and use the resulting value.
Replace the complete element, including opening and closing tags, with vanilla Markdown representing the selected presentation value.
<fm-list>
Apply the same cache-first/live-when-empty rule atomically to the complete list.
Convert canonical <ul>/<ol>/<li> success caches into Markdown unordered/ordered lists with valid indentation and the document's line-ending convention.
Convert inline list formats and literal fallbacks to safe Markdown text.
Preserve item order and duplicates.
<fm-format>
Remove the declaration and its fm-var-only syntax from the output.
Avoid leaving unnecessary blank lines where a top-level declaration was removed.
Entities and literal text
Decode fm-var cache entities such as &, <, and numeric character references.
Re-serialize decoded text as safe Markdown when necessary so decoding does not accidentally change its rendered meaning or create markup injection. For example, an encoded literal Markdown delimiter may need a Markdown backslash escape rather than becoming active emphasis.
Normalize only fm-var-owned cache serialization. Unrelated authored Markdown/HTML remains unchanged.
Only active syntax recognized by FMVarParser is converted. Tag-like examples inside code spans, fenced/indented code, escaped text, comments, raw-code contexts, or other parser exclusion regions remain literal source text.
Failure and atomicity
Never silently discard an unresolved reference.
If an empty/absent cache cannot be resolved to a valid presentation value, report a precise diagnostic and do not emit or write a misleading partially stripped version of that file.
Plan and validate every complete-element replacement before producing a successful file result.
For --write, revision-check and atomically replace each changed file; skip byte-identical files.
Define deterministic multi-file partial-success and exit-status behavior consistent with other fm-var workflows.
Treat cached child content as untrusted input and prevent HTML/Markdown/custom-element injection during conversion.
Architecture direction
Reuse FMVarParser and its exact UTF-8 ranges; apply complete-element edits from highest to lowest byte offset.
md-utils fm-var to-markdown exists and md-utils fm-var to-md is an exact alias.
Default execution writes converted Markdown to stdout and never mutates the input.
A cached <fm-var> becomes vanilla Markdown without live source access.
An empty/absent scalar cache is resolved live and converted when policy permits.
Cached and live <fm-list> results become Markdown lists or safe inline Markdown as appropriate.
All active <fm-var>, <fm-list>, and <fm-format> syntax is absent from successful output.
fm-var-owned HTML list wrappers are removed and entity-escaped cache text is decoded/re-escaped safely for Markdown.
Unrelated Markdown, frontmatter spelling, whitespace, attributes outside replaced elements, Unicode, and LF/CRLF bytes remain unchanged wherever conversion does not require an edit.
Literal tag-like text in parser exclusion contexts remains unchanged.
An unresolved empty cache fails visibly rather than dropping content or emitting a partially stripped file.
--output and explicit --write behavior are documented, tested, and safe against concurrent changes.
Human-readable and structured diagnostics identify the document, source range, element, cache/live decision, and failure reason.
Test requirements
Golden tests for cached scalar, empty-cache live scalar, zero/null fallbacks, cached/live inline lists, ordered/unordered lists, and <fm-format> removal.
Entity cases for named and numeric references, Unicode, Markdown delimiters, angle brackets, ampersands, quotes, and closing-tag/injection attempts.
Preservation tests for frontmatter spelling, unrelated Markdown/HTML, inline/fenced/indented code, comments, escaped tags, whitespace, LF, and CRLF.
Failure tests for denied/unreadable sources, invalid queries, unresolved zero/null results, bad value shapes, invalid cache markup, and output-path conflicts.
Process tests proving stdout is non-mutating, to-md matches to-markdown, --output writes only the destination, and --write uses revision-checked atomic replacement.
Directory tests for deterministic ordering, exclusions, partial failure, no-op files, and exit statuses.
Documentation / CLI-help impact
Document the cache-first/live-when-empty rule prominently.
Explain that the operation is intentionally destructive to fm-var declarations and differs from synchronization.
Include stdout, --output, --write, single-file, and directory examples.
Document the boundary between fm-var-owned HTML/entity conversion and unrelated authored HTML, which remains unchanged.
Update README, DocC, CLI help, common-use-case references, and both synchronized copies of the bundled Markdown Utilities skill.
Explicitly deferred
Refreshing non-empty caches before conversion; use synchronization for that workflow.
Converting arbitrary unrelated HTML throughout the document.
Updating authoritative YAML/frontmatter.
Recursive/transitive evaluation of referenced documents.
General-purpose templating or conversion of non-fm-var custom elements.
Problem / outcome
Provide one command that converts a document containing active RFC 001 Rev 3 fm-var syntax into ordinary, portable Markdown:
to-mdis an exact alias forto-markdown.The result contains no active
<fm-var>,<fm-list>, or<fm-format>elements. Cached presentation values are inlined. When a reference has no cached value, the command resolves and evaluates its live value and inlines that result. fm-var-owned HTML and entity escaping are converted into vanilla Markdown while preserving the rendered meaning as closely as possible.This is an export/conversion workflow, not synchronization: the output deliberately discards the dynamic fm-var declarations.
Epic: #111. This issue is related to, but semantically distinct from, cache synchronization in #113.
Command surface
Canonical command and alias:
Expected output modes:
--output <file>for one input file.--writefor in-place replacement.GlobalOptionsconventions for file/tree selection, recursion, exclusions, hidden files, deterministic ordering, diagnostics, and styling.--outputfile.Conversion semantics
For every active element recognized by the lossless fm-var parser:
<fm-var><fm-list><ul>/<ol>/<li>success caches into Markdown unordered/ordered lists with valid indentation and the document's line-ending convention.<fm-format>Entities and literal text
&,<, and numeric character references.Only active syntax recognized by
FMVarParseris converted. Tag-like examples inside code spans, fenced/indented code, escaped text, comments, raw-code contexts, or other parser exclusion regions remain literal source text.Failure and atomicity
--write, revision-check and atomically replace each changed file; skip byte-identical files.Architecture direction
FMVarParserand its exact UTF-8 ranges; apply complete-element edits from highest to lowest byte offset.MarkdownUtilitiesCorewhere portable.MarkdownUtilitiesand the executable.MarkdownDocument.render(), because unrelated frontmatter and Markdown bytes must not be normalized.to-markdownreplaces complete elements and removes that syntax.Acceptance criteria
md-utils fm-var to-markdownexists andmd-utils fm-var to-mdis an exact alias.<fm-var>becomes vanilla Markdown without live source access.<fm-list>results become Markdown lists or safe inline Markdown as appropriate.<fm-var>,<fm-list>, and<fm-format>syntax is absent from successful output.--outputand explicit--writebehavior are documented, tested, and safe against concurrent changes.Test requirements
<fm-format>removal.to-mdmatchesto-markdown,--outputwrites only the destination, and--writeuses revision-checked atomic replacement.Documentation / CLI-help impact
--output,--write, single-file, and directory examples.Explicitly deferred