CyanPrintCyanPrint
SearchDocs
Sign in

resolver

atomi/md

CyanPrint Resolver atomi/md

resolverv2folder artifact
Add dependencyresolvers: - atomi/md@2
1downloads
0likes
2versions
0pins

Rendered markdown

README

CyanPrint Resolver atomi/md

AtomiCloud's markdown resolver

Purpose

Merges multiple Markdown files that conflict on the same path by splitting each file on H1 (# ) boundaries, resolving conflicts per section, then reassembling. Each H1 section is treated as an independent unit — sections unique to one file are always included, while sections shared across multiple files are resolved using a configurable strategy.

Configuration Schema

KeyTypeDefaultDescription
sectionOrderstringalphabeticalStrategy for ordering sections in the final output. See Strategies for options.
contentOrderstringlowest-layer-firstStrategy for resolving conflicts when multiple files define the same H1 section.

Strategies

Both sectionOrder and contentOrder accept one of four values:

ValueBehavior
alphabeticalSort by section header name (A–Z) or content text (A–Z)
reverse-alphabeticalSort by section header name (Z–A) or content text (Z–A)
lowest-layer-firstSort by origin layer ascending (layer 0 before layer 1)
highest-layer-firstSort by origin layer descending (layer 1 before layer 0)

For sectionOrder, the sort key is the section header name (or layer for layer-based strategies). For contentOrder, the sort key is the section's content text (or layer for layer-based strategies).

Resolution Strategy

  1. Parse — Each input file is split on H1 lines (# ...). Text before the first H1 becomes a preamble section with an empty header.
  2. Deduplicate — Sections with the same header are grouped. Unique sections are kept as-is.
  3. Resolve conflicts — When a header appears in multiple files, all content blocks from all versions are concatenated (separated by blank lines) and sorted based on contentOrder. Content is never dropped. Ties are broken by layer ascending, then template name ascending.
  4. Order — All resolved sections are sorted based on sectionOrder.
  5. Reconstruct — Sections are concatenated with blank lines between them. Trailing whitespace is normalized per line.
  6. Single file passthrough — If only one input file is provided, it is returned as-is with trailing whitespace normalized.

Edge Cases

  • Content before first H1: Stored as preamble section (empty header), participates in ordering and conflict resolution.
  • Empty content section: Header-only sections are preserved.
  • No H1 at all: Entire file is treated as preamble.
  • All files empty: Returns empty string.

Commutativity and Associativity

CyanPrint may invoke the resolver with files in any order. The resolver produces identical output regardless of input ordering by:

  • Sorting inputs before processing (layer ascending, then template name ascending) to establish a deterministic processing order.
  • Deterministic conflict resolution: When multiple files contribute the same section, all content blocks are concatenated and sorted per contentOrder; ties are broken by layer then template name.
  • Deterministic section ordering: The sectionOrder strategy sorts all sections into a final order independent of input sequence.
  • Unique section deduplication: Each header appears exactly once in the output.

Merge Examples

Example 1: No Conflict — Two Files, Different Sections

Input files (all sharing the same path):

Origin TemplateOrigin LayerContent
template-a0# Alpha\n\nFrom A.
template-b1# Beta\n\nFrom B.

Config:

sectionOrder: alphabetical
contentOrder: lowest-layer-first

Resolved output:

# Alpha

From A.

# Beta

From B.

Both sections are unique, so both are included. Ordered alphabetically by header.

Example 2: Conflict — Same Section Header

Input files (all sharing the same path):

Origin TemplateOrigin LayerContent
template-a0# Overview\n\nAlpha version.
template-b1# Overview\n\nBeta version.

Config:

sectionOrder: alphabetical
contentOrder: lowest-layer-first

Resolved output:

# Overview

Alpha version.

Beta version.

Both files define # Overview. With contentOrder: lowest-layer-first, both content blocks are concatenated, ordered by layer ascending (layer 0 first, layer 1 second).

Example 3: Mixed — Some Shared, Some Unique

Input files (all sharing the same path):

Origin TemplateOrigin LayerContent
template-a0# Introduction\n\nIntro from A.\n\n# Setup\n\nSetup A.
template-b1# Introduction\n\nIntro from B.\n\n# Config\n\nCfg B.

Config:

sectionOrder: alphabetical
contentOrder: lowest-layer-first

Resolved output:

# Config

Cfg B.

# Introduction

Intro from A.

Intro from B.

# Setup

Setup A.

# Introduction appears in both files — both content blocks are concatenated, ordered by layer ascending. # Config and # Setup are unique. Sections ordered alphabetically.

Integration

Reference this resolver in a template's cyan.yaml:

resolvers:
  - ref: atomi/md@2
    config:
      sectionOrder: alphabetical
      contentOrder: lowest-layer-first
    files: ['**/*.md']

Contributors

  • md

Version history

v2Aug 9, 2026
1 downloads
v1Aug 5, 2026
1 downloads

Dependency pins

No pinned runtime dependencies.

Objects

Manifest
resolver/atomi/md/2953fa8b-8289-48f6-b267-a0f450bfc454/manifest/cyan.yaml
Bundle
resolver/atomi/md/2953fa8b-8289-48f6-b267-a0f450bfc454/bundle/bundle.js
Archive
none