Current section
Files
Jump to
Current section
Files
atproto_mlf
README.md
README.md
# atproto_mlf
> **Alpha, pre-release.** Pre-1.0 and evolving; expect breaking changes between 0.x
> releases. Upstream [mlf](https://mlf.lol/) is itself pre-release.
Parse and print [mlf](https://mlf.lol/) ("Matt's Lexicon Format") against the
[`atproto_lexicon`](https://hex.pm/packages/atproto_lexicon) AST, with a
bidirectional CLI for converting whole lexicon file trees. A clean-room Gleam
implementation of the upstream grammar, oracle-tested against upstream's own
snapshot fixtures.
## Installation
```sh
gleam add atproto_mlf
```
## Usage
Library:
```gleam
import atproto_mlf
let assert Ok(doc) = atproto_mlf.parse(source, "com.example.thread")
// doc is an atproto_lexicon ast.LexiconDoc; encode it, diff it, feed codegen.
```
CLI (walks both `.mlf` and `.json` inputs; four directions from one model:
compile, convert, normalize, fmt):
```sh
gleam run -m atproto_mlf -- <src-dir> <out-dir> [--to json|mlf]
```
NSIDs derive from file paths (`com/example/thread.mlf` becomes
`com.example.thread`). Constructs the lexicon spec allows but mlf cannot
express (e.g. a procedure with both query parameters and a non-JSON input
body) produce a spanned error naming the construct; nothing is ever silently
dropped.
## Architecture
Source -> `lexer` -> `parser` -> `lower` -> `atproto_lexicon` AST -> `printer`
-> mlf text; the CLI drives both directions over a file tree.
## Modules
| Module | What it does |
| --------------------- | ------------------------------------------------------------------------------------------------- |
| `atproto_mlf` | Public API: `parse` turns mlf source into an `atproto_lexicon` `LexiconDoc`; `main` runs the CLI. |
| `atproto_mlf/error` | `ParseError` + `describe`, returned by `parse`. |
| `atproto_mlf/printer` | `PrintError` + `describe` + `print`: AST back to mlf text, total or a named `PrintError`. |
`cli`, `lexer`, `lower`, `mlf_ast`, `parser`, `pipeline`, and `token` are
internal.