kantord / kantord/optative

mdx: document-mode lowering — prose as intrinsic JSX nodes in document order

Open
#108 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
1
Forks
0
Avg merge
3d 5h
Merged PRs (30d)
17

Description

Follow-up to #103.

## Problem

The mdx lowering serves its original purpose well — prose as *metadata about* units: each section's prose (heading included) is merged into one `` string wrapping that section's JSX. Two properties make it the wrong shape for consumers that want to *render* the document (e.g. a static site builder where `.op.mdx` files are pages):

1. **Interleaving is lost.** Prose parts and JSX children are collected separately per section, so `paragraph, , paragraph` can't be reconstructed — a renderer can only emit "all prose, then the components".
2. **The markdown stays a string**, forcing the consumer to bundle a second markdown parser (in JS, inside QuickJS) even though the lowering already has the full mdast.

## Proposal: a document-mode lowering

Lower prose all the way to intrinsic JSX nodes, in document order — the same thing mdx-js does:

```mdx
# Benchmarks

Here is the setup.

And here is what it means.
```

context mode (today):

```tsx

```

document mode (proposed):

```tsx
<>

Benchmarks


Here is the setup.



And here is what it means.

```

Since `h()` passes string tags through as inert `{type, props, children}` data, the consumer supplies per-tag mapper functions to serialize into its sink (HTML, or anything else) — prose and components become the same substance, and interleaving stops being a "mode" at all: document order is just child order. Inline constructs (emphasis, links, code spans) come from the mdast the parser already produces; no second markdown parser anywhere.

Context mode stays as-is for grounding/prompt consumers — this is an additional lowering target over the same parse (ESM hoisting, frontmatter, positions all shared), selectable by the caller (and eventually by the #103 loader).

## Motivating consumer

Static site builder as an esto script: posts are `.op.mdx` modules imported by the build script; the default export's tree is walked into HTML by per-tag mappers, only for pages whose input signature moved. Context mode is usable for this today (the value is verbatim markdown), but costs a vendored JS markdown parser and restricts component placement to section boundaries — document mode removes both.

Contributor guide

No contributing guide indexed for this repository

Research direction

No source file or test is named. Start by tracing the existing MDX context-mode lowering and the shared mdast parse path, including how ESM hoisting, frontmatter, and positions are preserved. Done means a caller-selectable document mode emits intrinsic JSX nodes in document order while context mode remains unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.